unity3d 使用Unity 3D中的MoveRotation将玩家转向某个Angular

u91tlkcl  于 2022-11-16  发布在  Angular
关注(0)|答案(3)|浏览(284)

有人告诉我,Rigidbody.MoveRotation是Unity 3D中在固定位置之间旋转播放器同时检测命中的最佳方法。然而,虽然我可以在固定位置之间平滑移动:

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);
            }

我不知道如何在固定位置之间平滑旋转。我可以使用Rigidbody.MoveRotation(Vector3 target);立即旋转到我想要的Angular ,但我似乎找不到一种方法来做上述旋转。
注意:Vector3.Distance是唯一能阻止抖动的东西。有人有什么想法吗?

lnxxn5zx

lnxxn5zx1#

因此,您希望随时间设置旋转值的动画,直到它达到某个值。
在Update方法中,你可以使用Lerp方法将对象旋转到一个点,但是如果你使用Lerp方法,你永远不会真正到达这个点。它将永远旋转(总是更接近那个点)。
您可以使用下列项目:

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;
        }
    }
 
}

因此,如果当前对象Angular 和所需Angular 之间的距离大于0.01f,则它直接跳到所需位置并停止执行Lerp方法。

mzsu5hc0

mzsu5hc02#

您可以更进一步,使用推文库在旋转之间补间。
DOTween
你可以这样称呼它:
transform.DoRotate(target, 1f)在1秒内旋转到目标。
或者甚至添加回调。
transform.DoRotate(target, 1f).OnComplete(//any method or lambda you want)

pkln4tw6

pkln4tw63#

首先,MoveRotation不接受Vector3,而是接受Quaternion
一般来说,你的抖动可能来自于过冲-你可能移动得比你的球员和目标之间的实际距离更远。
您可以通过使用Vector3.MoveTowards来避免该位,Vector3.MoveTowards可以防止目标位置的任何过冲,例如

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!");
}

然后,您可以简单地将相同的概念应用于旋转,方法基本上与Quaternion.RotateTowards相同

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!");
}

相关问题