0
\$\begingroup\$

I am trying to implement a hard pivot, like in Mario game, where the character is moving in one direction then you move the stick in a hard 180 to trigger the pivot animation.

My problem is that I calculate my velocities and rotation based on the thumbstick position each frame. Velocity is calculated from the magnitude of the Thumbstick axis, using Input.GetAxis. (0->0.1 Idle, 0.1->0.4 walk, 0.4->1 Run). Rotation is calculated from the difference between transform.forward and axis direction. See below:

float angle = Math.Abs(Vector3.Angle(transform.forward, axisDirection));
if (angle > 175) animator.SetTrigger("turn180");

For example:

Frame 1: Thumbstick is at Vector2(-1,0) Character facing (-1,0) Angle = 0
Frame 2: Thumbstick is at Vector2(0,0) Character facing (-1,0) Angle = 0
Frame 3: Thumbstick is at Vector2(1,0) Character facing (-1,0) Angle = 180

In this example the Animator would be told to play Run animation in Frame 1, Idle in Frame 2 and Run again in Frame 3. What I need to to basically ignore Frame 2 then the Animator will be told to play the Pivot 180 animation. The problem is during the time the angle == 0 the character is turning in an arc towards the direction of input which is not the desired animation. Obviously this shouldn't be an issue if the player can move the stick quick enough but it is not realistic to expect the player to do that.

What is the best practice to capture such input? I was thinking of implementing a buffer and using the Thumbstick values from a certain time ago, but that has it's own issues. Similarly, I was thinking of detecting the speed of movement of stick and only change movement if it is under a certain threshold. (I.e. in a certain place for a certain amount of time) but that could introduce lag? There must be an accepted way to handle this sort of input.

\$\endgroup\$
2
  • \$\begingroup\$ Are you calculating axisDirection with Input.GetAxis or GetAxisRaw, or some other computation? \$\endgroup\$
    – DMGregory
    Jan 12 at 3:18
  • \$\begingroup\$ @DMGregory Input.GetAxis \$\endgroup\$ Jan 12 at 9:06
0
\$\begingroup\$

I have come up with a solution that calculates the average speed of the stick movement in the past 0.05s, if it is over a certain threshold the stick is moving fast and the input will revert to the previous input. If it is under the threshold, the stick has slowed to an acceptable level, input is read and animations triggered.

It's a bit of a hack so still interested in other ideas.

Example code:

float stickSpeedThreshold = 0.3f;
float timeBuffer = 0.05f;
Vector2 axisDirectionBuffer; //Set 0.05s ago
float speedOfStickMovement = Vector2.Distance(axisDirection, axisDirectionBuffer) / timeBuffer;
if(speedOfStickMovement < stickSpeedThreshold)
{
    //Continue movement processing
}
else
{
    //Skip movement processing for this frame
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .