How to rotate object backwards 180 degrees in Update ?

private void Update()
{
  
float y = transform.eulerAngles.y;
                    if (y < 180)
                    {
                        targetAngles = transform.eulerAngles + 180f * Vector3.up;
                        transform.eulerAngles = Vector3.Lerp(transform.eulerAngles, targetAngles, 3f * Time.deltaTime);
                    }
}

I want to do it in Update without using coroutine. The problem is that if i don’t use the y < 180 condition it will keep rotating nonstop 360 degrees, but using the condition y < 180 didn’t help, now the object is not rotating at all.

I want the object to rotate backwards once.

Why not just make an animation and play it?

If an animation doesn’t do it, perhaps a tweening package like DOTWeen or ITween?

Otherwise, you can’t read from eulerAngles. Here’s why:

https://starmanta.gitbooks.io/unitytipsredux/content/second-question.html

If you just want to do it yourself in a coroutine, eg, poor man’s animation, something like this might work:

IEnumerator Flip()
{
  float angle = 0;
  do {
    angle += 100 * Time.deltaTime;
    if (angle > 180) angle = 180;  // clamp
    transform.rotation = Quaternion.Euler( angle, 0, 0);
    yield return null;
  } while( angle < 180);
}
1 Like

The main goal is automatic prevent from the player to walk too far.
When he walk too far he wait 3 seconds then start rotating and move back.

but it’s stuttering and i can’t figure out yet what cause the stuttering.

The problem is when using coroutine with moving the player the same time it’s stuttering.
that is why i wanted to do the rotation in the Update.

This is my script.

This is the lines in the Update i’m trying to make the rotation backwards 180 degrees :

targetAngles = transform.eulerAngles + 180f * Vector3.up;
 transform.eulerAngles = Vector3.Lerp(transform.eulerAngles, targetAngles, 3f * Time.deltaTime);

The goal is to move the player and rotate the same time but it’s stuttering.
The second the player start rotating and moving it’s stuttering when the rotating is over the stuttering stop.

I have already a DoRotate method to use with coroutine and it is rotating but also stuttering.
I’m not sure what part is making the stuttering but i think it’s the rotating.

The first rotating part is towards another object the second rotating by 180 degrees is because i don’t have any object to rotate towards so i want the player just to rotate backward.

if (rotateTowardsObject)
                {
                    Vector3 targetDirection = objectToRotatetowards.position - transform.position;
                    float singleStep = 3f * Time.deltaTime;
                    Vector3 newDirection = Vector3.RotateTowards(transform.forward, targetDirection, singleStep, 0.0f);
                    transform.rotation = Quaternion.LookRotation(newDirection);
                }

                if (rotateBackwards)
                {
                        targetAngles = transform.eulerAngles + 180f * Vector3.up;
                        transform.eulerAngles = Vector3.Lerp(transform.eulerAngles, targetAngles, 3f * Time.deltaTime);
                }

The script :

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityStandardAssets.Characters.ThirdPerson;
using Cinemachine;

public class DistanceCheck : MonoBehaviour
{
    public Transform objectToRotatetowards;
    public float slowDownLerpDuration;
    public float speedUpLerpDuration;
    public float rotationSpeed;
    public GameObject descriptionTextImage;
    public TextMeshProUGUI text;
    public ThirdPersonUserControl thirdPersonUserControl;

    private Animator anim;
    private float timeElapsed = 0;
    private float startValue = 1;
    private float endValue = 0;
    private float valueToLerp = 0;
    private bool startRotating = false;
    private bool slowOnBack = true;
    private bool exited = false;
    private Vector3 exitPosition;
    private float distance;
    private bool rotateTowards = false;
    private bool rotateBackwards = false;
    private bool rotateTowardsObject = false;
    private Vector3 targetAngles;


    void Start()
    {
        anim = transform.GetComponent<Animator>();
    }

    private void FixedUpdate()
    {
        if (startRotating)
        {
            if (rotateTowards)
            {
                if (rotateTowardsObject)
                {
                    Vector3 targetDirection = objectToRotatetowards.position - transform.position;
                    float singleStep = 3f * Time.deltaTime;
                    Vector3 newDirection = Vector3.RotateTowards(transform.forward, targetDirection, singleStep, 0.0f);
                    transform.rotation = Quaternion.LookRotation(newDirection);
                }

                if (rotateBackwards)
                {
                        targetAngles = transform.eulerAngles + 180f * Vector3.up;
                        transform.eulerAngles = Vector3.Lerp(transform.eulerAngles, targetAngles, 3f * Time.deltaTime);
                    
                    //StartCoroutine(DoRotate(2f));
                    //rotateBackwards = false;
                }
            }
        }

        if (exitPosition != new Vector3(0, 0, 0) && slowOnBack)
        {
            distance = Vector3.Distance(transform.position, exitPosition);
        }

        if (distance > 5 && slowOnBack)
        {
            slowOnBack = false;
            StartCoroutine(SlowDown());
        }
    }

    private void OnTriggerExit(Collider other)
    {
        if (other.tag == "NoExit")
        {
            rotateTowardsObject = true;
            rotateBackwards = false;
            descriptionTextImage.SetActive(true);
            if (other.TryGetComponent(out ColliderInfo info))
            {
                text.text = info.onExitText;
                rotateTowards = info.rotateTowards;
            }
            RepositionPlayer();
        }
        else if (other.tag == "NoEntry")
        {
            OnPlayerRepositioned();
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.tag == "NoExit")
        {
            OnPlayerRepositioned();
        }
        else if (other.tag == "NoEntry")
        {
            rotateTowardsObject = false;
            rotateBackwards = true;
            descriptionTextImage.SetActive(true);
            if (other.TryGetComponent(out ColliderInfo info))
            {
                text.text = info.onEnterText;
                rotateTowards = info.rotateTowards;
            }
            RepositionPlayer();
        }
    }

    private void RepositionPlayer()
    {
        exited = true;
        slowOnBack = true;
        exitPosition = transform.position;
        thirdPersonUserControl.enabled = false;
        StartCoroutine(SlowDown());
    }

    private void OnPlayerRepositioned()
    {
        exited = false;
        startRotating = false;
        text.text = "";
        descriptionTextImage.SetActive(false);
    }

    IEnumerator SlowDown()
    {
        timeElapsed = 0;

        while (timeElapsed < slowDownLerpDuration)
        {
            valueToLerp = Mathf.Lerp(startValue, endValue, timeElapsed / slowDownLerpDuration);
            anim.SetFloat("Forward", valueToLerp);
            timeElapsed += Time.deltaTime;

            yield return null;
        }

        if (exited)
        {
            yield return new WaitForSeconds(1.5f);

            startRotating = true;
            StartCoroutine(SpeedUp());
        }

        if (slowOnBack == false)
        {
            thirdPersonUserControl.enabled = true;
        }
    }

    IEnumerator SpeedUp()
    {
        timeElapsed = 0;

        while (timeElapsed < speedUpLerpDuration)
        {
            valueToLerp = Mathf.Lerp(endValue, startValue, timeElapsed / speedUpLerpDuration);
            anim.SetFloat("Forward", valueToLerp);
            timeElapsed += Time.deltaTime;

            yield return null;
        }
    }

    public IEnumerator DoRotate(float time)
    {
        var startRotation = transform.rotation;
        var newRotation = Quaternion.AngleAxis(180, Vector3.up) * transform.rotation;
        var progress = 0f;

        while (progress < 1)
        {
            progress += Time.deltaTime / time;
            transform.rotation = Quaternion.Slerp(startRotation, newRotation, progress);

            yield return null;
        }

        transform.rotation = newRotation;
    }
}

Small video clip showing the stuttering :
The stuttering start at 1:20

https://www.youtube.com/watch?v=-WjWebb_6kY

1 Like

I just use coroutines and an “I’m busy turning” boolean… super simple.

Set the boolean at the start of the coro, flip him around, disabling the control via that boolean, then turning control back on.

I do that on my Pilot Kurt game when you go near the boundaries of the mountains.

1 Like