유니티 MoveRotation - yuniti MoveRotation

I've been told that Rigidbody.MoveRotation is the best way in Unity 3D to rotate the player between fixed positions while still detecting hits. However, while I can move smoothly from fixed position to position with:

if (Vector3.Distance(player.position, targetPos) > 0.0455f) //FIXES JITTER 
            {
                var direction = targetPos - rb.transform.position;
                rb.MovePosition(transform.position + direction.normalized * playerSpeed * Time.fixedDeltaTime);
            }

I can't find out how to rotate smoothly between fixed positions. I can rotate to the angle I want instantly using Rigidbody.MoveRotation(Vector3 target);, but I can't seem to find a way to do the above as a rotation.

Note: Vector3.Distance is the only thing stopping jitter. Has anyone got any ideas?

유니티 MoveRotation - yuniti MoveRotation

derHugo

75k9 gold badges67 silver badges103 bronze badges

asked Nov 3 at 19:21

유니티 MoveRotation - yuniti MoveRotation

First of all MoveRotation doesn't take a Vector3 but rather a Quaternion.

Then in general your jitter might come from overshooting - you might be moving further than the distance between your player and target actually is.

You can avoid that bit by using Vector3.MoveTowards which prevents any overshooting of the target position like e.g.

Rigidbody rb;
float playerSpeed;
Vector3 targetPos;

// in general ONLY g through the Rigidbody as soon as dealing wit Physics
// do NOT go through transform at all
var currentPosition = rb.position;
// This moves with linear speed towards the target WITHOUT overshooting
// Note: It is recommended to always use "Time.deltaTime". It is correct also during "FixedUpdate"
var newPosition = Vector3.MoveTowards(currentPosition, targetPos, playerSpeed * Time.deltaTime);
rb.MovePosition(newPosition);

// [optionally]
// Note: Vector3 == Vector3 uses approximation with a precision of 1e-5
if(rb.position == targetPos)
{
    Debug.Log("Arrived at target!");
}

Then you can simply apply this same concept also to rotation by going through the equivalent Quaternion.RotateTowards basically just the same approach

Rigidbody rb;
float anglePerSecond;
Quaternion targetRotation;

var currentRotation = rb.rotation;
var newRotation = Quaternion.RotateTowards(currentRotation, targetRotation, anglePerSecond * Time.deltaTime);
rb.MoveRotation(newRotation);

// [optionally]
// tests whether dot product is close to 1
if(rb.rotation == targetRotation)
{
    Debug.Log("Arrived at rotation!");
}

answered Nov 4 at 11:00

유니티 MoveRotation - yuniti MoveRotation

derHugoderHugo

75k9 gold badges67 silver badges103 bronze badges

1

You can go one step further and use a tweeting library to tween between rotations.

DOTween

With that you can call it like this:

rigidbody.DoRotate(target, 1f) to rotate to target in 1 second.

Or even add callbacks.

rigidbody.DoRotate(target, 1f).OnComplete(//any method or lambda you want)

If at some point you want to cancel the tween yuou can save it on a variable and then call tween.Kill();

answered Nov 3 at 21:01

유니티 MoveRotation - yuniti MoveRotation

HorothenicHorothenic

6806 silver badges12 bronze badges

9

So, you want to animate the rotation value over time until it reaches a certain value.

Inside the Update method, you can use the Lerp method to keep rotating the object to a point, but you will never really reach this point if you use Lerp. It will keep rotating forever (always closer to the point).

You can use the following:

private bool rotating = true;
public void Update()
{
    if (rotating)
    {
        Vector3 to = new Vector3(20, 20, 20);
        if (Vector3.Distance(transform.eulerAngles, to) > 0.01f)
        {
            transform.eulerAngles = Vector3.Lerp(transform.rotation.eulerAngles, to, Time.deltaTime);
        }
        else
        {
            transform.eulerAngles = to;
            rotating = false;
        }
    }
 
}

So, if the distance between the current object angle and the desired angle is greater than 0.01f, it jumps right to the desired position and stop executing the Lerp method.

answered Nov 3 at 19:41

유니티 MoveRotation - yuniti MoveRotation

2