Unity3D Slerp 旋转速度
Posted
技术标签:
【中文标题】Unity3D Slerp 旋转速度【英文标题】:Unity3D Slerp rotation speed 【发布时间】:2013-12-02 13:26:58 【问题描述】:我正在使用 Unity3D。我想旋转一个对象以面向鼠标指针的方向,但允许最大旋转速度,例如“每秒最大 100 度”。
文档中有一个示例,但它没有做我想要的。 我认为Time.time应该是Time.deltaTime,我真的无法理解最后一个参数的作用。它应该是与起始向量相加的数字吗?http://docs.unity3d.com/Documentation/ScriptReference/Quaternion.Slerp.html
另外,我无法真正理解最后一个参数的作用。轮换时间到了吗?
我现在使用的代码
Plane plane = new Plane(Vector3.up, 0);
float dist;
void Update ()
//cast ray from camera to plane (plane is at ground level, but infinite in space)
Ray ray = Camera.mainCamera.ScreenPointToRay(Input.mousePosition);
if (plane.Raycast(ray, out dist))
Vector3 point = ray.GetPoint(dist);
//find the vector pointing from our position to the target
Vector3 direction = (point - transform.position).normalized;
//create the rotation we need to be in to look at the target
Quaternion lookRotation = Quaternion.LookRotation(direction);
//rotate towards a direction, but not immediately (rotate a little every frame)
transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * rotationSpeed);
我认为弱点在 Slerp 的第三个参数中,但我不知道该放什么。
【问题讨论】:
参数为:开始旋转,结束旋转,到目前为止已经完成的旋转的分数。当使用Time.deltaTime
并使用当前变换而不是第一次开始旋转时的变换时,那么第三个参数基本上就是这一帧应该旋转多少。您现在的代码是否有效?
不,它几乎是立即旋转。
【参考方案1】:
此代码有效,但我不确定它是否 100% 正确。
Plane plane = new Plane(Vector3.up, 0);
float dist;
void Update ()
//cast ray from camera to plane (plane is at ground level, but infinite in space)
Ray ray = Camera.mainCamera.ScreenPointToRay(Input.mousePosition);
if (plane.Raycast(ray, out dist))
Vector3 point = ray.GetPoint(dist);
//find the vector pointing from our position to the target
Vector3 direction = (point - transform.position).normalized;
//create the rotation we need to be in to look at the target
Quaternion lookRotation = Quaternion.LookRotation(direction);
float angle = Quaternion.Angle(transform.rotation, lookRotation);
float timeToComplete = angle / rotationSpeed;
float donePercentage = Mathf.Min(1F, Time.deltaTime / timeToComplete);
//rotate towards a direction, but not immediately (rotate a little every frame)
//The 3rd parameter is a number between 0 and 1, where 0 is the start rotation and 1 is the end rotation
transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, donePercentage);
【讨论】:
我知道您通常应该避免只说“谢谢”之类的 cmets,但我花了几天时间寻找解决方案,虽然我找到了很多答案......但没有一个能正常工作。这非常有效,所以谢谢!【参考方案2】:您需要为插值维护一个单独的变量并更新每一帧。否则,您的 Time.deltaTime * rotationSpeed 将永远超过 0-1 范围。
private float _RawLerp;
private float _Lerp;
public float _Speed;
public transform _Source;
public transform _Target;
private transform _TransformCache; // the transform for my game object, set in the Awake method
public void Update()
_RawLerp += Time.deltaTime * _Speed;
_Lerp = Mathf.Min(_RawLerp, 1);
_TransformCache.rotation = Quaternion.Slerp(
_Source.TargetRotation(),
_Target.TargetRotation(),
_Lerp);
【讨论】:
谢谢,重点是理解第三个参数必须在 0-1 范围内。我会发布固定代码。 @user1600770 如果 theodox 回答了你的问题,你应该接受这个答案。 @Jerdak 他给了我正确的提示,但这并不是我所需要的。我无法保持固定的目标旋转,因为我需要每帧更改它以跟随鼠标。我会给+1,但我接受下面的固定代码。 Theodox,这对你来说够公平吗?以上是关于Unity3D Slerp 旋转速度的主要内容,如果未能解决你的问题,请参考以下文章
UNITY3D:如何将 NavMeshAgent 行走速度设置为 0,但让他向玩家旋转
unity3d 中如何让一个物体一端固定,另一端随另一物体运动,就像弹簧一样