1
\$\begingroup\$

I'm currently working on a twin stick shooter but I encountered a problem when I rotate my player. The rotation snaps to right angles. I'm guessing it's a problem, due to the value that the joystick gives me back. Here is a screen recording, via Giphy.

How do I go about fixing this problem?

This is my code:

 void FixedUpdate()
{

    float hR = gamepad.GetStick_R().X;
    float vR = gamepad.GetStick_R().Y;

    float lastHR = hR;
    float lastVR = vR;
    // This part was added recently in the hope of smoothing the rotation
    float lerpHr = Mathf.Lerp(lastHR, hR, Time.deltaTime * speedRotation);
    float lerpVr = Mathf.Lerp(lastVR, vR, Time.deltaTime * speedRotation);

    PlayerRotation(lerpHr, lerpVr);
}

void PlayerRotation(float h, float v)
{
    rotation.Set(h, 0f, v);

    if (rotation != Vector3.zero)
    {
        currentRotation = Quaternion.LookRotation(rotation);
        playerRigidbody.MoveRotation(currentRotation);
        lastRotation = currentRotation;
    }
    else
        playerRigidbody.MoveRotation(lastRotation);
}

I also tried two other ways, but each time, I got the same results. I tried every way I could think of, with these lines of code. I don't know where else to look.

// Attempt Two
playerRigidbody.transform.rotation = Quaternion.Slerp(p
    layerRigidbody.transform.rotation, currentRotation, Time.time * speedRotation);

// Attempt Three
transform.eulerAngles = new Vector3(0, Mathf.Atan2(v, h) * 180 / Mathf.PI, 0);
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Unity uses an axial dead zone this causes the joystick to "snap" at 90 degrees (up, down, left, right). What you need is a radial dead zone.

First, you need to go into the Unity Input Manager and set the dead zone ("dead") value to zero (0), to disable their axial dead zone.

Under "Input Manager" > "Axes", you have to set the "Dead" value to 0 for every axes where you do not want snapping.

Then, do your own radial dead zone:

float hR = gamepad.GetStick_R().X;
float vR = gamepad.GetStick_R().Y;

float deadzone_squared = 0.1f * 0.1f;

// calculate and compare magnitude squared (skip the square root)
if((hR * hR + vR * vR) < deadzone_squared)
{
  hR = 0;
  vR = 0;
}

This will create a deadzone that is a circle, rather than a cross.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ This article from gamasutra is very useful in understanding this. \$\endgroup\$
    – Gnemlock
    Jan 26, 2017 at 3:53
  • \$\begingroup\$ Thanks, both of you! I saw the article before but I though that was not my problem. I get it now. \$\endgroup\$
    – jocte
    Jan 27, 2017 at 2:48

You must log in to answer this question.

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