Rotating Character Towards Mouse In C++, Buggy Code

Hey,

So I’m trying to make my player rotate towards the mouse. I’ve created a method to do this, but it causes the player to rapidly rotate in many directions, and I’m not sure why.

Here’s the method:

void ATopDownPlayerController::RotatePlayerToMouse()
{
	//Player exists.
	if (ATopDownCharacter* TopDownCharacter = Cast<ATopDownCharacter>(GetCharacter()))
	{
		//Get mouse rotation.
		FVector MouseLocation, MouseDirection;
		this->DeprojectMousePositionToWorld(MouseLocation, MouseDirection);

		//Get the rotation needed for the player to face the mouse.
		FRotator TargetRotation = UKismetMathLibrary::FindLookAtRotation(TopDownCharacter->GetActorLocation(), MouseLocation);

		//Set new yaw rotation while retaining current pitch and roll.
		ControlRotation = FRotator(GetControlRotation().Pitch, TargetRotation.Yaw, GetControlRotation().Roll);
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("Pointer to character is null!"));
	}
}

Am I doing this correctly? What would be the proper way to accomplish this in C++?

Found a solution. I use a custom trace collision channel and invisible plane to determine rotation.

Here’s the code for the controller:

void ATopDownPlayerController::RotatePlayerToMouse()
{
	//Player exists.
	if (ATopDownCharacter* TopDownCharacter = Cast<ATopDownCharacter>(GetCharacter()))
	{
		//Store data returned by UE.
		FVector MouseLocation, MouseDirection, MouseLocationEnd;
		FHitResult HitResult;

		//Use player controller and get mouse info.
		this->DeprojectMousePositionToWorld(MouseLocation, MouseDirection);

		//Make trace long so it hits anything nearby.
		MouseLocationEnd = (MouseDirection * 10000) + MouseLocation;

		//Stores settings for raycast.
		FCollisionQueryParams TraceSettings;
		FCollisionResponseParams TraceResponses;

		//Do trace. If it succeeds, complete calculations and set new rotation.
		if (GetWorld()->LineTraceSingleByChannel(HitResult, MouseLocation, MouseLocationEnd, MouseRotation, TraceSettings, 
			                                     TraceResponses) == true)
		{
			//Calculate new rotation with actor's location and hit result.
			FRotator NewRotation = UKismetMathLibrary::FindLookAtRotation(TopDownCharacter->GetActorLocation(), HitResult.ImpactPoint);
			TopDownCharacter->SetActorRotation(FRotator(GetControlRotation().Pitch, NewRotation.Yaw, GetControlRotation().Roll));
		}
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("Pointer to character is null!"));
	}
}

I also use a blueprint to set the trace channel on the plane.

1 Like

So where is the MouseRotation coming from? If you are referencing the MouseDirection previously declared it’s saying that you cannot cast a FVector/FRotator into a ECollisionChannel