How to Set the Actor rotation to Yaw in C++?

I want to set the rot_Y to actor rotation,

float rot_Y = GetControlRotation().Yaw;
SetActorRotation(rot_Y);

any help appreciated, Thank You.

1 Like

Hi Alexa.kl,

There is a good document here that describes the things you are trying to do.
It looks like you’ve already got a lot covered, so maybe skip down to section 2.3 - Implementing Character Movement Functions

2 Likes

I have these all setup done, now I am trying to add the free camera look, the player hold the Alt key and move the mouse , he can look around without effecting the character.

When the Alt key is on Hold, the mouse only effect the Yaw .

void AMyCharacter::FreeLook(float Axis)
{
    _bAltPressed = true;
	AltPressedRotation = SpringArm->GetTargetRotation();
	GetCharacterMovement()->bUseControllerDesiredRotation = false;
	GetCharacterMovement()->bOrientRotationToMovement = true;
}

Thank You very much for helping me in my Studies

this I want to check in tick every frame to see if the Alt is pressed.

I think what you’re after is:

bAltPressed=MyPlayerController->IsInputKeyDown(EKeys::LeftAlt);

Where MyPlayerController is your reference to the PlayerController.

1 Like

.cpp

void AMyCharacter::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	if (_bAltPressed) //Tick to call sync the character in real time
	{
		SynchCharacterFreeLook();
	}
}
void AMyCharacter::SynchCharacterFreeLook()
{
		print("Synch free look"); //called print on screen macro
		FRotator rotYaw_GC = GetControlRotation();
		FRotator rotYaw_GA = GetActorRotation();
		rotYaw_GA.Yaw = rotYaw_GC.Yaw;
		SetActorRotation(rotYaw_GA);
}
PlayerInputComponent->BindAction(FreeLook, IE_Pressed, this, &AMyCharacter::FreeLookPressed);
PlayerInputComponent->BindAction(FreeLook, IE_Released, this, &AMyCharacter::FreeLookReleased);
void AMyCharacter::FreeLookPressed() //Alt Pressed
{
	_bAltPressed = true;
	FRotator AltPressedRotation = SpringArm->GetTargetRotation();
	GetCharacterMovement()->bUseControllerDesiredRotation = false;
	GetCharacterMovement()->bOrientRotationToMovement = true;
}

void AMyCharacter::FreeLookReleased() //Alt Released
{
	_bAltPressed = false;
	FRotator AltPressedRotation = SpringArm->GetTargetRotation();
	GetCharacterMovement()->bUseControllerDesiredRotation = true;
	GetCharacterMovement()->bOrientRotationToMovement = false;
}

This is whole structure , but not working correctly, I have doubt on SynchCharacterFreeLook() , something I have done not correctly I think in this function.

I guess u need to save current direction of movement when u press Alt key (i.e. in FreeLookPressed()) to a variable and use it in movement code instead of calculating new movement direction relative to camera rotation.
Later (in FreeLookRelease()) just return to using calculated direction.

Tick isnt nessesary at all

1 Like

Very Good Idea, but for this I will have to modify the code on many places and the main thing how to save the current location in a variable and process it when the mouse rotates?

I am doing this in tick to make it in real time sync.

Hmm… how about create FVector FreeLookMovementDirection in .h and save there ur direction in FreeLookPressed() method (dont know how u calculate direction, maybe try Camera->GetForvardVector for forvard/backward dir vector and Camera->GetRightMovement for left/right dir vector) then in move method via if (bAltPressed) change between default direction and saved direction

1 Like

What happens if you just have “rotYaw_GA.Yaw=0;”? One of my favorite ways to test things…

1 Like

this way it will work , I already tried but its very heavy on performance because this function is called on minimum 40 places, even called when on air dive or in car drive, it will have a time line too to smooth back to the original position when the alt key released.
so these 40+ functions executes when the alt key is pressed and tick will progress them.

when I put it to zero, nothing happened, on pressing alt and I have no free look functionality.

I approached something different: Now character is rolling faster fast when the alt is pressed and the mouse moved.

void AMyCharacter::SynchCharacterFreeLook()
{
		print("Synch free look");
		float rotYaw = GetControlRotation().Yaw;
		FRotator rot = GetActorRotation().Add(0.0f, rotYaw, 0.0f);
		SetActorRotation(rot);

		//FRotator rotYaw_GA = GetActorRotation();
		//rotYaw_GA.Yaw = rotYaw_GC.Yaw;
}
1 Like

continuous rotation was caused by the rotYaw in FRotator rot = GetActorRotation().Add(0.0f, rotYaw, 0.0f);
Just changed it to FRotator rot = GetActorRotation().Add(0.0f, 0.0f, 0.0f); temoporary fixed the bad rotation and now when I hold the alt key, spring arm is rotating as expected when the mouse is moved. So now I can look around and it not effecting the character location/rotation. Only the spring arm rotates under the boundaries

but still I want to set the SetActorRotation(rot); as shown in the image

I think this is what you are trying to achieve. I apologize if I am incorrect.
Here is how I currently have mine working. I hope it helps!

InputComponent->BindAction("CameraHold", IE_Pressed, this, &ATopDownPlayerController::HandleCameraHoldStart);

InputComponent->BindAction("CameraHold", IE_Released, this, &ATopDownPlayerController::HandleCameraHoldStop);
void ATopDownPlayerController::PlayerTick(const float DeltaTime)
{
	Super::PlayerTick(DeltaTime);	
	HandleCameraRotation(DeltaTime);
}
void ATopDownPlayerController::HandleCameraRotation(const float DeltaTime)
{
	if (bIsCameraHeld)
	{
		if (const ATopDownCharacter* MyPawn = GetTopDownCharacter())
		{
			if (USpringArmComponent* CameraBoom = MyPawn->GetCameraBoom())
			{
				GetInputMouseDelta(MouseDeltaX, MouseDeltaY);
				CameraBoom->AddRelativeRotation(FRotator(0, MouseDeltaX * PlayerInput->GetMouseSensitivityX() * ( 100.0f + DeltaTime ), 0));
				SetMouseLocation(PreviousMouseX, PreviousMouseY);
			}
		}
	}
}

 void ATopDownPlayerController::HandleCameraHoldStart()
 {
 	bIsCameraHeld = true;
 	bShowMouseCursor = false;
 	GetMousePosition(PreviousMouseX, PreviousMouseY);
 }

void ATopDownPlayerController::HandleCameraHoldStop()
{
	bShowMouseCursor = true;
	bIsCameraHeld = false;
	MouseDeltaX = 0;
	MouseDeltaY = 0;
}
2 Likes

This is also a good set of logics, but mine is different and I have it working, the problem is the pitch value stops updating at 90 degrees due to Gimbal Lock.
I can only pass this if I will manage to set the actor.Yaw from controller.Yaw as shown in the image above.
In blueprint I can set it and in C++ I have no Idea about it.

Are you trying to have your character rotate to match the forward vector of the controller? Sorry I’m having a difficult time trying to understand…

No, that is already matched, now I am trying to set the controller.Yaw to actor.Yaw while the alt key is released. so all the rotations and other values comes to its original state + character comes back to its state smoothly, for this I will add a float curve with a timeline animation

SetActorRotation(FRotator(0, GetControlRotation().Yaw, 0));

1 Like