x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

AI Perception Mark player as enemy

How do I mark the player as an enemy for my AI so that they will sense him when using "Detection by Affiliation: Detect Enemies"?

Also see this old topic: https://answers.unrealengine.com/questions/285849/aiperception-how-to-use-detection-by-affiliation.html

What's the proper way to do this now? I added the interface IGenericTeamAgentInterface. But I have no idea how to set the actual (const) member. All I could find was:

alt text

I set the interface in C++:

 #include "Runtime/AIModule/Classes/GenericTeamAgentInterface.h"
 class AFPS1Character : public ACharacter, public IGenericTeamAgentInterface

But it crashes: Assertion failed: bCreateOnlyIfEmpty || !PointerToUberGraphFrame->RawPointer [File:D:\BuildFarm\buildmachine_++UE4+Release-4.11\Engine\Source\Runtime\Engine\Private\BlueprintGeneratedClass.cpp] [Line: 647]

But could also be done through this: https://docs.unrealengine.com/latest/INT/Engine/Blueprints/UserGuide/Types/Interface/UsingInterfaces/index.html (which does not crash the engine even though they should be the same?)

Why is it so hard to set a simple int-variable? Am I doing it all wrong?

Product Version: UE 4.11
Tags:
c.png (37.9 kB)
more ▼

asked Apr 16 '16 at 12:05 PM in Blueprint Scripting

avatar image

Napoleonite
580 84 102 146

(comments are locked)
10|2000 characters needed characters left

3 answers: sort voted first

Since 4.10 is recommended to use a AI controller as provider of diplomacy options:

 class AIMODULE_API AAIController : .... public IGenericTeamAgentInterface

Override method with logics of your game:

 virtual FGenericTeamId GetGenericTeamId() const override { return TeamID; }
 virtual ETeamAttitude::Type     GetTeamAttitudeTowards(const AActor& Other) const override;

more ▼

answered Apr 16 '16 at 05:16 PM

avatar image

v.s.
342 9 8 26

avatar image Napoleonite Apr 16 '16 at 05:21 PM

Sorry I'm not that experienced with C++ yet.

 virtual FGenericTeamId GetGenericTeamId() const override { return FGenericTeamId::NoTeam; }

There is no build-in struct-member for Enemy, Player & Neutral. Does that mean we have to create those ourselves as well? Only FGenericTeamId::NoTeam is present.

Also it gives me 496 errors: alt text

alt text

err.png (61.2 kB)
err2.png (70.5 kB)
avatar image v.s. Apr 16 '16 at 05:29 PM

GetGenericTeamId provides ID of the team only. GetTeamAttitudeTowards logic provides attittude to unit (Enemy, Neutral or Friendly). At the moment there is no version of these functions for use in blueprints.

avatar image v.s. Apr 16 '16 at 05:31 PM

Your controller should override these methods, and as an option to provide a wrapper for blueprints. I do not know any other way at this time.

avatar image v.s. Apr 16 '16 at 05:54 PM
 UENUM(BlueprintType)
 enum class ETeamAttitudeWrapper : uint8
 {
     Friendly = 0,
     Neutral,
     Hostile
 };
 
 UFUNCTION(BlueprintCallable, DisplayName = "GetTeamAttitudeTowards", Category = "AI")
 ETeamAttitudeWrapper K2_GetTeamAttitudeTowards(AActor* Other) const;
 
 ETeamAttitudeWrapper  YourAIController::K2_GetTeamAttitudeTowards(AActor* Other) const
 {
     return (ETeamAttitudeWrapper)GetTeamAttitudeTowards(*Other);
 }
avatar image Napoleonite Apr 16 '16 at 07:14 PM

Sorry I can't get it to compile. Also can't really make our own enum for it. We have to use the one UE4 uses in it's interface ( https://docs.unrealengine.com/latest/INT/API/Runtime/AIModule/FGenericTeamId/index.html ) and extend that. But C++ does not really support it. And you end up with gigantic workarounds. I give up.

I'm going back to PawnSensing. I know it's 'deprecated' but at least it works. This is too much of a mess just to set a very very simple enum on the player actor...

I'll mark it as answered since you are pointing in the right direction but my C++ knowledge is just not advanced enough yet to do this.

avatar image v.s. Apr 16 '16 at 07:47 PM

Other solution

 UCLASS(BlueprintType)
 class UTempResult : public UObject
 {
     GENERATED_BODY()
 
 public:
     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AI")
     ETeamAttitudeWrapper Result;
 };
 
 class AYourAIController
 {
 public:
     UFUNCTION(BlueprintImplementableEvent, DisplayName = "GetTeamAttitudeTowards", Category = "AI")
     void    K2_GetTeamAttitudeTowards(const AActor* Other, UTempResult* Result);
     virtual void K2_GetTeamAttitudeTowards_Implementation(const AActor* Other, UTempResult* Result);
 
     UPROPERTY()
     UTempResult* TempResult;
 };
 
 void AYourAIController::BeginPlay()
 {
     Super::BeginPlay();
     TempResult = NewObject<UTempResult>();
 }
 
 void AYourAIController::K2_GetTeamAttitudeTowards_Implementation(const AActor*, UTempResult* Result)
 {
 }
 
 ETeamAttitude::Type AYourAIController::GetTeamAttitudeTowards(const AActor& Other) const
 {
     // Hack
     const_cast<AYourAIController*>(this)->K2_GetTeamAttitudeTowards(&Other, TempResult);
     ETeamAttitude::Type Result = (ETeamAttitude::Type) TempResult->Result;
 
     return Result;
 }

alt text

test.jpg (48.4 kB)
avatar image Napoleonite Apr 16 '16 at 09:35 PM

I gave it another try without hacking around first. But it always returns neutral because OtherTeamAgent always evaluates to false. And I was so close... Still, the amount of C++ knowledge needed for this is quite advanced. You need knowledge about: inheritance, overriding with different scopes, virtuals + constants, references, extending enums (EPredefinedId), etc. etc. How are people using only blueprints supposed to implement this? Also the internal code looks 'odd', may need some refactoring.

Not sure but I may also have to set the TeamID it seems.

 // header file (did the same to the playercontroller)
 #pragma once
 
 #include "AIController.h"
 #include "FPS1AIController.generated.h"
 
 /**
  * AAIController already implements the IGenericTeamAgentInterface so don't add it here.
  */
 UCLASS()
 class FPS1_API AFPS1AIController : public AAIController
 {
     GENERATED_BODY()
     
 public:
 
 
     virtual FGenericTeamId GetGenericTeamId() const { return ETeamAttitude::Hostile; }
     // WHY is this method private (in their interface) while their static solver is public?
     // WHY do they use both a solver and this method? Why so complicated?
     virtual ETeamAttitude::Type GetTeamAttitudeTowards(const AActor& Other) const
     {
         const IGenericTeamAgentInterface* OtherTeamAgent = Cast<const IGenericTeamAgentInterface>(&Other);
 
         if (OtherTeamAgent) // <<<<<<<< always evaluates to false? WHY?
         {
             UE_LOG(LogTemp, Error, TEXT("checking"))
             return OtherTeamAgent->GetGenericTeamId() ? ETeamAttitude::Hostile : ETeamAttitude::Neutral;
             //return ETeamAttitude::Hostile;
             //return OtherTeamAgent->GetGenericTeamId() != GetGenericTeamId() ? ETeamAttitude::Hostile : ETeamAttitude::Friendly;
         }
         else
         {
             UE_LOG(LogTemp, Error, TEXT("neutral"))
             return ETeamAttitude::Neutral;
         }
     }
 };

avatar image v.s. Apr 16 '16 at 09:48 PM

GetGenericTeamId is public anywhere (Interface or implementation) and GetTeamAttitudeTowards too. OtherTeamAgent is nullptr because Pawn (Actor) in argument has not IGenericTeamAgentInterface's implementation. I usually do Cast to the desired type of Pawn and check its diplomacy. My K2 version is working and you can edit logic in BP. For GetGenericTeamID also need to use a K2 wrapper.

avatar image v.s. Apr 16 '16 at 09:53 PM
 ETeamAttitude::Type AMyAIController::GetTeamAttitudeTowards(const AActor& Other) const
 {
     auto Character = Cast<AMyCharacter>(GetPawn());
 
     if (Character == nullptr)
         return ETeamAttitude::Neutral;
 
     // My own implementation
     return Character->GetTeamAttitudeTowards(Other);
 }

 ETeamAttitude::Type AMyCharacter::GetTeamAttitudeTowards(const AActor& Other) const
 {    
     auto OtherCharacter = Cast<const AMyCharacter>(&Other);
     if (OtherCharacter == nullptr)
         return ETeamAttitude::Neutral;
 
     if (OtherCharacter->Controller == nullptr)
     {
         return GetTeamAttitudeTowards(OtherCharacter...); 
     }
 
     auto AIController = Cast<const AAIController>(OtherCharacter->Controller);
 
     if (AIController == nullptr)
         return ETeamAttitude::Neutral;
 
     const auto& OtherId = AIController->GetGenericTeamId();
     
     return GetTeamAttitudeTowards(OtherCharacter, OtherId ...);
 }
avatar image Napoleonite Apr 17 '16 at 09:10 AM

GetTeamAttitudeTowards too. OtherTeamAgent is nullptr because Pawn (Actor) in argument has not IGenericTeamAgentInterface's implementation.

I put 2 enemies (same blueprint) opposite of each other and making them look at one another, thus both having the interface. So if one of them has the implementation, the other one MUST have too it can not be null. Yet I get only null-values for the other agent variable.

I applied your latest code example but again the same problem. I'm really going back to pawnsensing because this new aiperception is just unfinished imo. I'm sure some people hack their way around and and that others use dirty workarounds and perhaps some people get it properly to work. But I'm not one of those. And pawnsensing is like 10 minutes to imlement.

avatar image Daniel Hilburn Jul 11 '16 at 02:58 PM

@Napoleon, from how you've described your issue, it sounds like your sensing component is (correctly) on your AIController subclass. However, the perception is picking up your AI agent's Character object and not its AIController object. Since your Character object doesn't implement the IGenericTeamAgentInterface (it's AIController does), the interface cast fails and you always get OtherTeamAgent == nullptr. You can get around this by creating a subclass of Character for your AI to use which also implements IGenericTeamAgentInterface. In this class, you'd simply return the Character's AIController's TeamID. You'll need to do something similar for PlayerController as well if your player is going to be on a team. If you're feeling like this is a lot of work to do to set an int property, you are wrong. But hopefully this will help you get everything sorted. =)

(comments are locked)
10|2000 characters needed characters left

I created a tutorial on how to setup the AI perception correctly. You can check it out if you are still confused. AI Perception Setup Tutorial

more ▼

answered May 08 '17 at 11:17 AM

avatar image

dbrizov
324 21 22 42

(comments are locked)
10|2000 characters needed characters left

I see that this is still a problem in 4.21.1. It can not be so difficult to fix something like that, and that you can edit from blueprint, at least be able to choose if an actor is, friend, neutral or enemy.

more ▼

answered Dec 30 '18 at 11:24 PM

avatar image

CUERN1T0S
26 3 8 4

avatar image boynet Feb 06 '19 at 09:00 AM

it seems like from my little experienced once a feature is ready, they never go back and add stuff to it, so if they for some reason decided not to add that option to blueprint it will never be possible.. there is many small stuff like that

(comments are locked)
10|2000 characters needed characters left
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question