2
\$\begingroup\$

I'm making my first project in Unity, a simple game where touching objects adds points to the player's score.

I'd like the objects to have a pleasant back and forth swaying animation on the Z axis. Nodding to the right 30 degrees, then to the left 30 degrees, on and on.

Here's what I've got...

public class Rotator : MonoBehaviour 
{
    void Update () 
    {
        transform.Rotate(new Vector3(0,0,12)*Time.deltaTime);
    }
}

This gives me a nice slow rotation. But I am clueless how to tell Unity to stop at +30 degrees, reverse to -30 degrees, rotate again to +30, stop and repeat, etc, etc.

I'd really appreciate any help. Maybe there is a thread like this that I was not able to find? I assume it will involve some kind of 'if then' function?

\$\endgroup\$
2
\$\begingroup\$

This gives me a nice slow rotation. But I am clueless how to tell Unity to stop at +30 degrees, reverse to -30 degrees, rotate again to +30, stop and repeat, etc, etc.

I suggest you to use coroutines for that. There are several ways of course of doing that. The code could look more or less the following:

IEnumerator LoopRotation(float angle)
{
  float rot = 0f;
  float dir = 1f;
  while(true)
  {
    while(rot < angle)
    {
      float step = Time.deltaTime * rotSpeed;
      transform.Rotate(new Vector3(0,0,12)*step * dir);
      yield return null;
    }
    rot= 0f;
    dir *= -1f;
  }
}

void Awake()
{
  StartCoroutine(LoopRotation(30f))
}
\$\endgroup\$
1
\$\begingroup\$

Use a sine wave.

During the update method, get the elapsed total time and store that as a float. Feed it to a sine function and you'll end up with a value between -1 and 1 that oscillates between the two values; multiply it by thirty and you can rotate an object from -30 degrees to +30 degrees.

float elapsed = Time.deltaTime; float degrees = Mathf.Sin(elapsed) * 30.0f;

That might move a little too quickly, however, so you could always create a new floating-point variable and just increment that slightly each frame. Then feed that to the sine function.

Mathf.Sin(0) == 0.0; Mathf.Sin(90) == 1.0f; Mathf.Sin(180) == 0.0f; Mathf.Sin(270) == -1.0f;

I'm unfamiliar with how rotations are defined in unity, but I'll give it a go.

float sineTime = Mathf.Sin(Time.deltaTime); transform.Rotate(new Vector3(0, 0, 1) * sineTime * 30);

I hope this is useful for you.

\$\endgroup\$
  • \$\begingroup\$ As Trevor once told me, I'll pass on: The Hermite basic interpolator P(t) = 3t^2 - 2t^3 (for 0 <= t <= 1) is often used because it's faster to calculate than the sine. (Interestingly, that comment of his was on my first answer, as this comment is to yours. Consider this your inheritance. :D) \$\endgroup\$ – Anko Feb 12 '14 at 20:54
  • \$\begingroup\$ Heheh, thanks very much. It just immediately jumped to mind, but I'm intrigued now, so I'll give it a go and try it out! :-) \$\endgroup\$ – James K Feb 13 '14 at 20:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.