Download

"Faking" rotating movement on 180 degree turns?

Hello once more! Not sure if this fits better in programming or animation since it includes both.

I handle my movement based on two axes, forward and backward (positive and negative value) and left and right (positive and negative value).
I then use AddMovementInput to move my character based on this input.

It works nicely for the most part, but I’ve found that I get some strange, floating and snapping movement when the player changes direction 180degrees in one sharp motion.
But also found that it looks really clean and nice if for instance go forward->right->backwards, making a turning that goes through the sideways movement as well, and I would like to emulate this when the player skips the 90 degree directions.

How would you suggest I do this?



void ATribesmenCharacter::MoveForward(float Value)
{
if ((Controller != NULL) && (Value != 0.0f))
{
//Find direction
FRotator Rotation = Controller->GetControlRotation();
//Ignore Pitch

if (GetCharacterMovement()->IsMovingOnGround() || GetCharacterMovement()->IsFalling())
{
Rotation.Pitch = 0.0f;
}
//InputDirection
const FVector Direction = FRotationMatrix(Rotation).GetScaledAxis(EAxis::X);
AddMovementInput(Direction, Value);

if (!bOffsetTriggered)
{
AnimOffsetTarget = 40;
bOffsetTriggered = true;
}
bIsMovingForwards = true;
}
else if (Value == 0.0f)
{
//Offset to while moving to avoid clipping in First person
if (bOffsetTriggered)
{
AnimOffsetTarget = 0;
bOffsetTriggered = false;
}
bIsMovingForwards = false;
}
}


void ATribesmenCharacter::Strafe(float Value)
{
StrafeValue = Value;
if ((Controller != NULL) && (Value != 0.0f))
{
//Find direction
const FRotator Rotation = Controller->GetControlRotation();
const FVector Direction = FRotationMatrix(Rotation).GetScaledAxis(EAxis::Y);
AddMovementInput(Direction, Value);

bIsStrafing = true;
}

else if (Value == 0.0f)
{
bIsStrafing = false;
}
}

So far I’m envisioning that if the player is moving forwards, then presses backwards, it first interpolates to the nearest strafe direction, and then to the negative forwards once the first interp is complete. But I’m not quite sure if this is the best way to do it, or how I would exactly put it into code.

Edit: I think I explained it poorly. Simply put, I want to make my character run in a circle when turning instead of rotating on the spot.

I would force the state machines.
basically you have a direction of travel. You know if that direction suddenly became the opposite of itself. If it has, you can either play a special turn animation (like paragon), or you can add movement input to make the direction do what you want and then return the input to the player.

handling in animation may be preferable as taking input over CAN (doesn’t mean it has to) become clumsy.

I think I’d actually prefer to force the character to move in a circle rather than a dedicated animation, it looks nice and is subtle enough to not make the player feel like they’re out of control.

But how do I translate 2 axes into a direction? Also those two axes don’t take camera rotation into account in of themselves and would need to make use of the camera rotation as a base somehow.

Normalize, then cross product.

Its hard to say what you need exactly because I would just use the movement input node, forcing the other axis to activate for a short burst…

But my axes are just two independent floats, not two vectors?

Yeah, I’m considering maybe doing it this way instead too, but I’m not too sure how I would detect the characters rotation in relation to input and camera direction.
If it was always facing one way, the logic would be simple.

Depends on a few things, but its all basic trig.
essentially the return of a dot product between something thats a vector…

In the case the camera rotates with the pawn. The camera rotation and pawn rotation always match, so getting pawn forward vector is an axis.

you also have a movement speed, in the movement component. This can be used to determine directionally as well, since it is a vector. If you normalize it, that should be your axis of travel (say left key applies a strafe instead of a direction change, that direction should be the normalized speed).

Personally I’d keep it very simple.
Going forward toggles a bool.
​​pressing backwards checks the bool.
If you were going forward you apply a short but of input (timeline).
if fowards was released after a delay of .2 (default) reset the forward bool.

Invert the process for the other axes so it happens in both directions.

Possibly check the rotation of camera/player to determine if to apply left or right movement. This is possible if you use a base with turn in place or similar where you travel forward but can look right or left as you do so…