Why is GetUnitAxis returning zero?

I’m trying to write a function that will read the current direction the player is trying to move in by reading the X and Y control axes, and execute a short dash in that direction by adding impulse:

	UCharacterMovementComponent* myMovement = Cast<UCharacterMovementComponent>(GetMovementComponent());

	const FRotator Rotation = Controller->GetControlRotation();
	const FRotator YawRotation(0, Rotation.Yaw, 0);
	const FVector DirectionY = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
	const FVector DirectionX = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);

	FVector DodgeDirection = (DirectionX + DirectionY) * 10;

	myMovement->AddImpulse(DodgeDirection, true);

I expect DodgeDirection to be equal to my current direction of travel magnified ten times, but this adds no velocity when run, and when I exposed DodgeDirection in the editor I see that it always remains at a value of (0,0,0), even when dodge is pressed while the player is moving. Does GetUnitAxis not work like I thought it did?

I think you’re looking for GetScaledAxis() instead of GetUnitAxis().

e.g. I use the following to add movement input in the player’s left/right or forward/backward direction:

AddMovementInput(FRotationMatrix(GetControlRotationZeroPitch()).GetScaledAxis(axis), val)

Good point.

If you’re trying to do the dodge based on which direction the player is trying to move in, I’d suggest you rather check which directional keys are held down instead of using the viewrotation. If you use your original approach I think the impulse would always be added in the direction halfway between forward and right?

inline FVector FMatrix::GetUnitAxis( EAxis::Type InAxis ) const
return GetScaledAxis( InAxis ).GetSafeNormal();

Don’t think so.

Hmm, the problem there is that the game only knows about two movement keys- W/S are hooked to one axis and A/D is hooked to the other, so it can tell it’s getting input on one or both planes, but not which specific keys are being held down.

Am I using viewrotation by mistake? I thought the original example I posted was using movement direction… either way, is GetControlRotationZeroPitch one of your functions? I’m having trouble finding it in the library. :slight_smile:

Ah yes, my apologies, that is my own function which simply looks like this:

FRotator APWNPlayerCharacter::GetControlRotationZeroPitch() const
	FRotator rot = Controller->GetControlRotation();
	rot.Pitch = 0.0f;
	return rot;

As for knowing which direction the player wants to dodge in, I have a similar functionality which determines which direction the player wants to do a melee strike in. I created a class derived from UObject which calculates the intended strike direction based on which keys are held down. (Consider the case where the player is in the air, moving left, but they want to strike from the right, so move right key is held down. Here, the movement velocity/direction won’t work because it will register as left instead of right).

I’ve posted my movement code to a public repo if you’d like to have a look. You will see that I have the movement direction calculator, and I create an instance of this class on my character, then in my character’s input functions (like move forward, backwards etc.) I fire notified to the movemendirectioncalculator, which figures out which direction the player wants to go in. Maybe it will help.