C# 我想把相机从一个四元数调到另一个四元数
我想实现将相机从原始四元数旋转到目标四元数 然后我使用了以下代码:C# 我想把相机从一个四元数调到另一个四元数,c#,unity3d,rotation,quaternions,C#,Unity3d,Rotation,Quaternions,我想实现将相机从原始四元数旋转到目标四元数 然后我使用了以下代码: public class CameraMove : MonoBehaviour { public static bool start = false; public Vector3 targetPosition; public Quaternion targetRotation; public float speed = 0.1f; void Start() {
public class CameraMove : MonoBehaviour
{
public static bool start = false;
public Vector3 targetPosition;
public Quaternion targetRotation;
public float speed = 0.1f;
void Start()
{
StartCoroutine(cameraRotate());
}
IEnumerator cameraRotate()
{
// Trigger cameraMove until clicking the sphere
yield return new WaitUntil(() => start == true);
while (transform.localRotation!=targetRotation)
{
transform.localRotation = Quaternion.Lerp(transform.localRotation, targetRotation, speed * Time.deltaTime);
yield return null;
}
}
}
然而,相机根本没有旋转,idk为什么使用
Quaternion.Lerp
或Quaternion.Slerp
在您始终有一个距离开始旋转距离的百分比时使用。但是,您有当前旋转、目标旋转和速度。这更适合使用四元数。旋转方向:
IEnumerator cameraRotate()
{
// Trigger cameraMove until clicking the sphere
yield return new WaitUntil(() => start);
while (transform.localRotation != targetRotation)
{
transform.localRotation = Quaternion.RotateTowards(transform.localRotation,
targetRotation, speed * Time.deltaTime);
yield return null;
}
}
作为替代方案,我想在这里留下一个实际使用Lerp
的解决方案
这样做的巨大优势在于,您还可以添加“缓入”和“缓出”,例如使用或甚至使用其他数学计算来更改旋转的动画
它还允许您精确控制旋转所需的时间以及必须旋转多少度。在下面的示例中,我再次使用你的速度值(以度/秒为单位)计算了持续时间,但你也可以简单地通过一个固定的持续时间,如1或2秒
公共类CameraMove:MonoBehavior
{
公共静态bool start=false;
公共向量3目标位置;
//更容易调整欧拉角
公共矢量3目标;
//现在,以度/秒为单位设置旋转速度
公共浮子速度=90f;
void Start()
{
start例程(cameraRotate());
}
私人IEnumerator cameraRotate()
{
//触发cameraMove直到单击球体
返回新的等待时间(()=>start==true);
var startRotation=transform.localRotation;
var finalRotation=四元数.Euler(targetRotation);
//角度差/每秒角度=>持续时间(秒)
变量持续时间=四元数角度(起始旋转、最终旋转)/速度;
var timePassed=0f;
while(通过的时间<持续时间)
{
//使用此因子,您可以获得线性旋转,就像使用四元数一样。旋转方向。。。
var lerpFactor=通过时间/持续时间;
//…巨大的优势:您现在可以在旋转中添加缓进和缓出!
var smoothdlerpfactor=Mathf.SmoothStep(0,1,lerpFactor);
transform.localRotation=Quaternion.Lerp(开始旋转、结束旋转、平滑旋转因子);
//添加到时间传递中,以避免超调
timaPassed+=Mathf.Min(持续时间-已通过的时间,Time.deltaTime);
收益返回空;
}
//确保完成后将旋转设置为固定
transform.localRotation=最终旋转;
}
}
更多关于简化数学结帐的精彩例子
e、 g.我们有轻松进出:
var lerpFactor = passedTime / duration;
smoothedLerpFactor = Mathf.SmoothStep(0, 1, lerpFactor);
e、 只是放松一下
var lerpFactor = passedTime / duration;
smoothedLerpFactor = Mathf.Sin(lerpFactor * Mathf.PI * 0.5f);
e、 g.只是放松一下
var lerpFactor = passedTime / duration;
smoothedLerpFactor = 1f - Mathf.Cos(lerpFactor * Mathf.PI * 0.5f);
e、 g.指数式放松
var lerpFactor = passedTime / duration;
smoothedLerpFactor = lerpFactor * lerpFactor;
您还可以多次使用它们,甚至可以增加平滑效果,例如超级平滑步骤;)
是的,我检查过了,它仍然不能工作。我在考虑我的目标是正确的值。这是我从inspector检查的(x,y,z)值,对吗?x,y,z是四元数的euler表示,但不能直接将这些值用作四元数x,y,z,w@ChenJi尽量使用公共矢量3 targetRotation
(更易于调整欧拉角度),并在旋转方向上使用四元数.euler(targetRotation)
。或者在循环开始前更有效地存储此值一次;)感谢~您的详细回答,在旋转方面学到了很多很棒的答案!如果您想要使用不同的宽松,您会改变什么?这将是对var smoothdlerpfactor
行的更改,对吗?没错!结账你可以使用很多其他的数学例子
var lerpFactor = passedTime / duration;
smoothedLerpFactor = Mathf.SmoothStep(0, 1, Mathf.SmoothStep(0, 1, lerpFactor));