AI Perception attachment

Hello,
I want to attach AI Perception Component to characters head instead of capsule center. Does anyone know how to do it? I red somewhere that it can be done by making AIPerceptionComponent based class in C++ and adding functionality to GetLocationAndDirection function, but that was all. I’m not hardcore programmer and I guess that since AIPerception is in AIController, not in Character, that’s tricky to do.

Hi,

Maybe these two answers (link1, link2) can help you achieve what you want :slight_smile:

Hey, thanks but it’s not what I want. I don’t want custom points on sensed character (well, I want, but I have that already). What I want is when my AI turns head, its vision cone rotates with it. Now its rotating only with whole character.

Oh sorry, I misunderstood your question. Unfortunately, afaik this cannot be done in blueprints. The comment section doesn’t like Code blocks so I’m posting an updated answer with some steps on how to do it in C++.

As was pointed out in this archived post, AIPerception uses GetActorViewPoint to determine the Sight Sense location and orientation. Unfortunately, this function cannot be overridden in blueprints yet. However, you can very easily override it in C++ and update the actor viewport with the location and rotation of “head” bone to achieve the effect you want. Hence, if you really need this, you have to do a little bit of coding. It’s not that difficult though. Here’s a quick step by step guide on how to accomplish this:

  1. In the Content Browser, click on the green button Add New > New C++ Class. Select Character and name it BaseCharacter.

  2. Th Engine will take a short moment to create this class and recompile the solution. If you’re on Windows and have Visual Studio installed, it will open automatically. Once the Visual Studio opens, go to the BaseCharacter.h and override GetActorViewpoint method as a public function by adding the following line within those curly brackets:

    void GetActorEyesViewPoint(FVector& Location, FRotator& Rotation) const override;

  3. Go to BaseCharacter.cpp and add these few lines:

    void ABaseCharacter::GetActorEyesViewPoint(FVector& Location, FRotator& Rotation) const
    {
    Location = GetMesh()->GetSocketLocation(“head”);

    Rotation = GetActorRotation();
    Rotation.Yaw -= GetMesh()->GetSocketTransform("head", RTS_ParentBoneSpace).Rotator().Roll;
    

    }
    This uses the default’s Third Person skeleton and the “head” bone to update these Location and Rotation values.

That’s it! Now go back to the Editor, and compile your solution. If you’re already in the blueprint version of ThirdPersonTemplate, then simply open the ThirdPersonCharacter blueprint, go to the Class Settings and on the top right, change the Parent Class to this BaseCharacter. If you’re building your own Character, then use this BaseCharacter as the parent and create a new blueprint from it (one simple way to do this is to find this C++ BaseCharacter class in the Content Browser, right-click on it and create a new blueprint class from it). Next, create an AIController, add the AIPerception to it, and enable Sight Sense. The Yaw angle of Sight Sense will automatically get updated as this Character turns his head.

Hope this helps.

~Vizgin

4 Likes

Now it works as it should :slight_smile: However I had to change RTS_ParentBoneSpace to RTS_World and Rotator() to Yaw, because it was keeping world rotation 0,0,0 when characters head was in default position, so vision cone wasn’t rotating even with the whole character.

I thought it we’ll be something more complicated :slight_smile:
Thanks for your help!

You’re welcome :slight_smile:

Yes, you’re right. I missed the part that the bone coordinate system doesn’t get affected by the root motion. I’ll update the code soon.

Use this code instead as yours uses the wrong quotation marks due to the Epic forum migration:

void ABaseCharacter::GetActorEyesViewPoint(FVector& Location, FRotator& Rotation) const
{
    Location = GetMesh()->GetSocketLocation("head");

    Rotation = GetActorRotation();
    Rotation.Yaw -= GetMesh()->GetSocketTransform("head", RTS_ParentBoneSpace).Rotator().Roll;
}