0
\$\begingroup\$

Hi I have the following code snippet in Unity and I am trying to smoothly reset my orientation. However the code below snaps my object in default orientation. Any suggestions why this would be happening?

using System.Collections.Generic;
using UnityEngine;

public class Cube : MonoBehaviour
{
    public bool aligning = false;

    public Quaternion TargetQuaternion;
    public float animationTime;
    public float animationDuration = 2.0f;
    public float t = .0f;
    private bool set = false;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        float rotspeed = 3.0f;
        float movespeed = 10.0f;
        if(Input.GetKey(KeyCode.UpArrow))
        {
            transform.position += transform.forward * movespeed * Time.deltaTime;
        }
        if (Input.GetKey(KeyCode.DownArrow))
        {
            transform.position -= transform.forward * movespeed * Time.deltaTime;
        }
        if (Input.GetKey(KeyCode.RightArrow))
        {
            Quaternion q = Quaternion.identity;
            q.SetAxisAngle(new Vector3(0, 1, 0), rotspeed * Time.deltaTime);
            transform.rotation *= q;
        }
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            Quaternion q = Quaternion.identity;
            q.SetAxisAngle(new Vector3(0, 1, 0), -rotspeed* Time.deltaTime);
            transform.rotation *= q;
        }

        if (aligning)
        {
            t = animationTime / animationDuration;
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 0, 0), t);
            animationTime += Time.deltaTime;
            if (animationTime >= animationDuration)
            {
                aligning = false;
                animationTime = 0.0f;
            }
        }
    }
}
```
\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

This is probably something you would want to do with Coroutines. Coroutines are like functions, however, unlike functions, they can span over more than one frame. Coroutines are good for time based changes. For example fading one colour into another colour. Heres an example of a coroutine that would reset the players orientation.

// A coroutine is defined by an IEnumerator
private IEnumerator ResetOrientation(float duration) {
    // these will only be called once when the coroutine starts
    float elapsed = 0f;
    Vector3 originalRotation = transform.eulerAngles;
    Vector3 targetRotation = (0, 0, 0);

    // The while will iterate every frame until the specified duration is met
    while (elapsed < duration) {
        // Increase the elapsed time by deltaTime
        elapsed += Time.deltaTime;
        // Lerp linearly interpolates between two values
        transform.eulerAngles = Vector3.Lerp(originalRotation, targetRotation, elapsed / duration)
        // Return null and wait for the next frame
        yield return null;
    }
}

You can call the coroutine anywhere simply using StartCoroutine(ResetOrientation(2f)) and passing a duration in seconds as an argument, in this case it would do it over 2 seconds. Hope this fixes your issue.

EDIT: Also, never use transform.position -= transform.forward * movespeed * Time.deltaTime; setting an objects position is a very bad way to move things, as it completely ignores physics and collisions. Typically this can lead to wall clipping and stuttery movement, I highly recommend you search for a different way to move that suits your needs.

\$\endgroup\$

You must log in to answer this question.

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