Pawn Sensing to Socket

Hello Guys,

Someone know how to attach the Pawn Sensing to socket or bone??? (c++ or blueprint)

Thanks in advance!

Hello, there is some news about this?

Yeah I think is a bug where you can’t set the socket, im in 4.7.6

Has anyone been able to attach the pawn sensing component to a socket?

my idea is to put the pawn sensing in a child actor , then attach the childe actor to te bone

This works only with an Character, or Pawn (AICharakter). Create a second Pawn Actor and rename it to “sensing”. Add a Component PawnSensing in “sensing”.
In your Character, where PawnSensing should work, you must use SpawnAIFromClass and spawn your “sensing”. Then a tickrate must copy the location and rotation of the socket.

212765-2017-09-08-15-45-48-fuchscharakter.jpg

Or you can use without Tickrate:

This is crazy idea but semi working (tested). I think it can create bugs, because this is not rotating in all axes, only horizontally. My character rotating head around - left/right - up/down and as I see, I can’t use any ready engine solutions for this.

As of version 4.19.2 you still can’t attach a UPawnSensingComponent to a socket, but you can achieve the same with the following setup:

  1. If you don’t already have, create a subclass of APawn or ACharacter, whatever Actor should your sensor belong to.
  2. Override the AActor::GetActorEyesViewPoint() method to your needs. It should basically populate input parameters with the head location and rotation of your character.
  3. Create a subclass of UPawnSensingComponent.
  4. Override the UPawnSensingComponent::GetSensorRotation() method to use the FRotator object from the overridden AActor::GetActorEyesViewPoint() method.

And that’s about it.

Overridden method in my UPawnSensingComponent subclass:

FRotator UExtendedPawnSensingComponent::GetSensorRotation() const {
	FRotator SensorRotation(FRotator::ZeroRotator);
	FVector SensorLocation;
	const AActor* SensorActor = GetSensorActor();

	if (SensorActor != NULL) {
		SensorActor->GetActorEyesViewPoint(SensorLocation, SensorRotation);
	}

	return SensorRotation;
}

Overridden method in my AActor subclass:

void AHumanCharacter::GetActorEyesViewPoint(FVector& OutLocation, FRotator& OutRotation) const {
	const USkeletalMeshSocket* HeadSocket = GetMesh()->GetSocketByName(FName("headSocket"));
	if (HeadSocket && AnimInstance) {
		const USkeletalMeshComponent* SkelMesh = AnimInstance->GetSkelMeshComponent();
		const FVector HeadLocation = HeadSocket->GetSocketLocation(SkelMesh);
		FRotator CharRotation = GetActorForwardVector().Rotation();
		const float BodyYaw = AnimInstance->GetRelativeUpperBodyRotation();
		const float Diff = CharRotation.Yaw - BodyYaw;
		const float Angle = FMath::Abs(Diff) > 180 
			? 360 - FMath::Abs(Diff) : Diff;
		
		CharRotation.Yaw = Angle;

		OutLocation = HeadLocation;
		OutRotation = CharRotation;
	}
	else {
		Super::GetActorEyesViewPoint(OutLocation, OutRotation);
	}
}

Excellent solution! Way better than the Blueprint hack w/ attaching a child Actor. Thanks!

Thanks for this solution, it seems to be working fine. However, I am wondering, where does the AnimInstance object come from? I have added your code to our custom Character-derived class, but then AnimInstance is an invalid identifier. Any ideas?

Hi haimat,
That AnimInstance is a custom class derived from UAnimInstance which I defined in my controller. So, the GetRelativeUpperBodyRotation() method is not something you have in your default UAnimInstance class. It just returns the value of the rotation of the head and upper torso that are the member values of my custom anim class and are being hooked to a Bone transform node in the blueprint.
Btw, you can get the default anim instance from your controller with GetMesh()->GetAnimInstance().