Eve*_*986 2 c# quaternions unity-game-engine
我是新手,我尝试开始使用Unity Engine.
有人可以解释一下,Quaternion.Slerp怎么样?因为我想以不同的角度90,180和270旋转一些物体.我可以在下面看到我的代码.不幸的是,当我添加180度时,对象会做出疯狂的事情,而不是将旋转放到(0,180,180)这个游戏对象.我想得到(180,0,0)
public float speed = 0.1F;
private float rotation_x;
void Update()
{
if (Input.GetButtonDown("Fire1"))
{
rotation_x = transform.rotation.eulerAngles.x;
rotation_x += 180;
}
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(rotation_x, transform.eulerAngles.y, transform.eulerAngles.z), Time.time * speed);
}
Run Code Online (Sandbox Code Playgroud)
Pro*_*mer 12
大多数示例包括他们官方网站上的Unity示例都以错误的方式使用Lerp.他们甚至懒得描述它在API文档中的工作原理.他们只是将它淀粉在Update()功能中并称之为一天.
Mathf.Lerp,Vector3.Lerp以及Quaternion.Slerp通过从一个位置/旋转变换到另一种与工作吨值(最后一个参数)被传递in.That 吨值也被知道为时间.
所述的最小吨值是0F和max为1F.
我将解释这一点,Mathf.Lerp以便更容易理解.两者的Lerp功能都是相同的Mathf.Lerp,Vector和Quaternion.
请记住,它Lerp采用两个值并在它们之间返回值.如果我们的值为1和10,我们会对它们执行Lerp:
float x = Mathf.Lerp(1f, 10f, 0f); will return 1.
float x = Mathf.Lerp(1f, 10f, 0.5f); will return 5.5
float x = Mathf.Lerp(1f, 10f, 1f); will return 10
Run Code Online (Sandbox Code Playgroud)
如您所见,t(0)返回传入的数字的最小值,t(1)返回传入的最大值,并t(0.5)返回最小值和最大值之间的中间点.你做错了,当你通过任何牛逼值,或.你功能中的代码就是这样做的.每秒都会增加,并且会在一秒钟内增加,所以你有问题.< 0> 1Update()Time.time> 1
它建议Lerp在另一个函数/ Coroutine中使用,而不是使用Updated函数.
注意:
Lerp在旋转方面,使用它有不好的一面.Lerp不知道如何用最短路径旋转对象.所以记住这一点.例如,您有一个具有0,0,90位置的对象.假设您想要将旋转从那里移动到0,0,120 Lerp有时可以向左旋转而不是向右旋转以到达新位置,这意味着需要更长的时间才能到达该距离.
假设我们想要(0,0,90)从当前旋转的任何位置进行旋转.下面的代码会将旋转更改为0,0,903秒.
轮流时间:
void Start()
{
Quaternion rotation2 = Quaternion.Euler(new Vector3(0, 0, 90));
StartCoroutine(rotateObject(objectToRotate, rotation2, 3f));
}
bool rotating = false;
public GameObject objectToRotate;
IEnumerator rotateObject(GameObject gameObjectToMove, Quaternion newRot, float duration)
{
if (rotating)
{
yield break;
}
rotating = true;
Quaternion currentRot = gameObjectToMove.transform.rotation;
float counter = 0;
while (counter < duration)
{
counter += Time.deltaTime;
gameObjectToMove.transform.rotation = Quaternion.Lerp(currentRot, newRot, counter / duration);
yield return null;
}
rotating = false;
}
Run Code Online (Sandbox Code Playgroud)
随时间增加角度旋转:
要在z轴上将对象旋转到90,下面的代码就是一个很好的例子.请理解将物体移动到新的旋转点并旋转它之间有区别.
void Start()
{
StartCoroutine(rotateObject(objectToRotate, new Vector3(0, 0, 90), 3f));
}
bool rotating = false;
public GameObject objectToRotate;
IEnumerator rotateObject(GameObject gameObjectToMove, Vector3 eulerAngles, float duration)
{
if (rotating)
{
yield break;
}
rotating = true;
Vector3 newRot = gameObjectToMove.transform.eulerAngles + eulerAngles;
Vector3 currentRot = gameObjectToMove.transform.eulerAngles;
float counter = 0;
while (counter < duration)
{
counter += Time.deltaTime;
gameObjectToMove.transform.eulerAngles = Vector3.Lerp(currentRot, newRot, counter / duration);
yield return null;
}
rotating = false;
}
Run Code Online (Sandbox Code Playgroud)
我的所有示例都基于设备的帧速率.您可以通过替换实时使用Time.deltaTime,Time.delta但需要更多计算.