0
\$\begingroup\$

Here is a snippet of my Update function, which contains everything regarding my rotations for the character:

// Higher the Z float, the LESS of a rotation when moving
Vector3 v3 = new Vector3 (Input.GetAxis ("Horizontal"), 0.0f, 1.5f); 

// A Quaternion variable named "quaternion" that's equal to LookRotation class that takes 
// the "v3" variable
Quaternion quaternion = Quaternion.LookRotation (v3); 

// The actual rotation is done using the Slerp class
transform.rotation = Quaternion.Slerp (
  transform.rotation, 
  quaternion, 
  Rotspeed * Time.deltaTime); 

// When Countdown timer is done, then the animator is enabled
adventureAnimator.enabled = true; 

When I put "357" on the X-Axis tab of Rotation, why does it go back to 0 whenever the game starts? After some debugging I know it is because of my logic contained in my "transform.rotation = Quaternion.Slerp" line of code. What do I need to change?

If you need more information or need me to elaborate, please let me know.

\$\endgroup\$
1
  • \$\begingroup\$ what is Rotspeed set to? \$\endgroup\$
    – Gnemlock
    Commented Sep 18, 2016 at 14:32

2 Answers 2

1
\$\begingroup\$

Having tested your code, I find that your problem occurs due to several faults.

  • Your telling your rotation to move with a time value of Rotspeed * Time.deltaTime. I have previously mistaken this value to represent how long the rotation should take. If you have taken the same misinterpretation, there is a good chance your actually telling it to complete the rotation immediately.
  • Your telling your rotation to move between 357 degrees and 0 degrees. That gives us only 3 degrees of rotation, which is not a lot. Depending on your setup, you might very well be completing the rotation in such a small amount of time that you simply do not notice.
  • As InfiniteCanvas points out, your taking Input.GetAxis("Horizontal") at every Update() call. Whenever your not providing input, this will return a value of 0.

Using Quaternion.Slerp

Since you have neglected to tell us what you are setting Rotspeed to, this could easily be a red herring. That said, I see this error a lot, and have made it myself when first starting to use Quaternion.Slerp.

As per the API, the method takes two Quaternion values to represent the start and finish rotations, and a float to represent the time. While time is commonly interpreted as "how long should my rotation take", it is actually a normal for how quickly your object should complete the rotation.

If the combined value of Rotspeed * time.deltaTime reaches the value of 1, your effectively telling your code "perform the entire rotation in a single frame". This will move the rotation immediately to the b quaternion, in this case, (0, 0, 0).


This is the only fault that specifically results in your reported problem. All other potential faults result in a similar problem, but instead of skipping straight to 0, the rotation still "teeters" for a little. For example, with the input problem, rotation moves back and fourth between -0.01 and 0.01.

Understanding Transform.Rotation

There is a possibility you interpret the move between (357, 0, 0) and (0, 0, 0) to be quite large; the gap between 357 and 0. It is important to know that this is not the case.

The rotation displayed on the transform via the inspector can be interpreted as degrees. You can submit any value, but as soon as you hit play, the transform will scale these values back to the true degrees. Once a rotation value reaches 360, it has performed a full rotation. It may as well be returned to 0 - and that is exactly what it does. You can see this by setting the rotation to values higher than 360, via the inspector. Once you hit play, these numbers will immediately scale down to values between 0 and 360.

As you can see, rotation between 357 and 0 is not that much - it is actually only a difference of 3. The object is rotated clockwise, and once it reaches a rotation of 360, the transform resets this value to 0. The Quaternion.Slerp() is successfully carried out over a mere 3 degrees.

Ensuring Input

As mentioned by InfiniteCanvas, constantly updating your rotation means that whenever the user is not actually providing input, you will update your rotation to 0. This might have a secondary effect on your logic, as you might reset the look at rotation when you do not mean to. Further testing has confirmed that this alone will not cause the problem you describe, but it is worth addressing how you might better your input.

Keep in kind that if you did not intend to pass non-values at Update(), you will want to declare Vector3 v3 as a class variable rather than a method variable. This way, if your current input as a non-value, you still have the rotation from your last value input.


Continuing use of the Input Manager, you could simply exclude non-input in an if statement, prior to setting it as your new rotation:

// we should initialise the vector with a default value.
Vector3 v3 = new Vector3(0, 0, 1.5f);

void Update()
{
    if(Input.GetAxis("Horizontal") != 0)
    {
        Vector3 v3 = new Vector3 (Input.GetAxis ("Horizontal"), 0.0f, 1.5f); 
    }

    ...
}

You might consider checking direct key presses to influence a set vector, instead. Ideally, you would set a class variable to represent rotationMovement per input update. You could than tailor your code to rotate once per key press with Input.GetKeyDown(KeyCode), during ever update where the key is pressed with Input.GetKey(KeyCode), or even once at the update where the key is released with Input.GetKeyUp(KeyCode). The choice is yours, but it would look something like this:

// we should initialise the vector with a default value.
Vector3 v3 = new Vector3(0, 0, 1.5f);
float rotationMovement = 0.1f;

void Update()
{
    if(Input.GetKey(KeyCode.LeftArrow))
    {
        v3.x -= rotationMovement;
    }
    else if(Input.GetKey(KeyCode.LeftArrow))
    {
        v3.x += rotationMovement;
    }

    ...
}
\$\endgroup\$
-1
\$\begingroup\$

Wrap it all in an if statement, like so:

if(Input.GetAxis("Horizontal") != 0)
{
    //your code
}

As it is now it updates on every frame, regardless of your input. That means that you update your rotation to

v3 = new Vector3(0f, 0f, 1.5f)

when you're not pressing anything.

\$\endgroup\$
1
  • \$\begingroup\$ Reversing my vote as I have found this answer to be incorrect. Copying the above code, a vector of (0, 0, 1.5) does not lead to any rotation. The rotation stays at 357. \$\endgroup\$
    – Gnemlock
    Commented Sep 19, 2016 at 0:19

You must log in to answer this question.

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