Search code examples
c#unity-game-enginerotationeuler-angles

Rotate GameObject back and forth


I would like to rotate an object back and forth between 90,-90 on the Y axis. The problem is I can set the object in the editor at -90, but when I run the project -90 suddenly becomes 270. Anyway here is the code that I'm using:

void Update()
{
    if (transform.eulerAngles.y >= 270)
    {
        transform.Rotate(Vector3.up * speed * Time.deltaTime);
    }
    else if (transform.eulerAngles.y <= 90)
    {
        transform.Rotate(Vector3.up * -speed * Time.deltaTime);

    }
}

It always gets stuck in the middle around 360 degrees. Help?


Solution

  • Just like moving GameObject back and forth, you can rotate GameObject back and forth with Mathf.PingPong. That's what it is used for. It will return value between 0 and 1. You can pass that value to Vector3.Lerp and generate the eulerAngle required to perform the rotation.

    This can also be done with a coroutine but Mathf.PingPong should be used if you don't need to know when you have reached the destination. Coroutine should be used if you want to know when you reach the rotation destination.

    public float speed = 0.36f;
    
    Vector3 pointA;
    Vector3 pointB;
    
    
    void Start()
    {
        //Get current position then add 90 to its Y axis
        pointA = transform.eulerAngles + new Vector3(0f, 90f, 0f);
    
        //Get current position then substract -90 to its Y axis
        pointB = transform.eulerAngles + new Vector3(0f, -90f, 0f);
    }
    
    void Update()
    {
        //PingPong between 0 and 1
        float time = Mathf.PingPong(Time.time * speed, 1);
        transform.eulerAngles = Vector3.Lerp(pointA, pointB, time);
    }
    

    EDIT:

    With the coroutine method that you can use to determine the end of each rotation.

    public GameObject objectToRotate;
    public float speed = 0.36f;
    
    Vector3 pointA;
    Vector3 pointB;
    
    
    void Start()
    {
        //Get current position then add 90 to its Y axis
        pointA = transform.eulerAngles + new Vector3(0f, 90f, 0f);
    
        //Get current position then substract -90 to its Y axis
        pointB = transform.eulerAngles + new Vector3(0f, -90f, 0f);
    
        objectToRotate = this.gameObject;
        StartCoroutine(rotate());
    }
    
    IEnumerator rotate()
    {
        while (true)
        {
            //Rotate 90
            yield return rotateObject(objectToRotate, pointA, 3f);
            //Rotate -90
            yield return rotateObject(objectToRotate, pointB, 3f);
    
            //Wait?
            //yield return new WaitForSeconds(3);
        }
    }
    
    bool rotating = false;
    IEnumerator rotateObject(GameObject gameObjectToMove, Vector3 eulerAngles, float duration)
    {
        if (rotating)
        {
            yield break;
        }
        rotating = true;
    
        Vector3 newRot = gameObjectToMove.transform.eulerAngles + eulerAngles;
    
        Vector3 currentRot = gameObjectToMove.transform.eulerAngles;
    
        float counter = 0;
        while (counter < duration)
        {
            counter += Time.deltaTime;
            gameObjectToMove.transform.eulerAngles = Vector3.Lerp(currentRot, newRot, counter / duration);
            yield return null;
        }
        rotating = false;
    }