右。。这是我第一次在这里提问,所以我很抱歉,如果我遗漏了任何重要的细节,我会尽我所能提供相关信息。
我的问题是:我正在使用一个打开橱柜的门的脚本,而一扇门可以正常工作。然而,另一扇门是镜像的,并沿着相同的旋转方向打开,使其向内而不是向外打开
我的猜测(作为一个完全的初学者,请注意)是
openRot = new Vector3 (defaultRot.x, defaultRot.y + DoorOpenAngle, defaultRot.z
需要更改为负DoorOpenAngle(只需将+替换为-即可翻转旋转方向)
然而,这反而让门旋转得非常快,而且它并没有停止"打开",只是在一个无限的循环中旋转了整整360度。下面的脚本是用于正常工作的门的脚本,如果我像上面的建议一样将角度更改为负值,那么门永远不会停止的原因还有什么
我猜还有另一段代码由于尝试简单的镜像旋转而发生冲突,很抱歉,如果根据您自己的标准,这看起来很混乱,请尽我所能进行格式化。
var smooth = 2.0;
var DoorOpenAngle = 90.0;
private var open : boolean;
private var enter : boolean;
private var defaultRot : Vector3;
private var openRot : Vector3;
function Start()
{
defaultRot = transform.eulerAngles;
openRot = new Vector3 (defaultRot.x, defaultRot.y + DoorOpenAngle, defaultRot.z);
}
//Main function
function Update (){
if(open)
{
//Open door
transform.eulerAngles = Vector3.Slerp(transform.eulerAngles,
openRot, Time.deltaTime * smooth);
}
else
{
//Close door
transform.eulerAngles = Vector3.Slerp(transform.eulerAngles,
defaultRot, Time.deltaTime * smooth);
}
if(Input.GetKeyDown("f") && enter){
open = !open;
}
}
function OnGUI(){
if(enter){
GUI.Label(new Rect(Screen.width/2 - 75, Screen.height - 100, 150, 30), "Press 'F' to open the cabinet");
}
}
您误解了Slerp
的作用。您期望它的行为更像RotateTowards
。
Slerp
与任何线性插值函数一样,取两个值from
和to
,然后返回另一个值,即它们之间的t
%。这有时很有用,但不是你想做的。
另一方面,RotateTowards
取两个值current
和target
,然后将current
向target
旋转至多maxRadiansDelta
并返回。这更接近于你想要的行为。
由于我们处理的是旋转,所以使用Quaternion.RotateTowards
会更容易。基本概念是相同的。
假设你想让门每秒旋转30度:
//convert euler angles to quaternion
//you can do this earlier, but this is fine for now
var openRotQ = Quaternion.Euler(openRot);
//calculate rotation
var maxDegrees = Time.deltaTime * 30;
var newRot = Quaternion.RotateTowards(transform.rotation, openRotQ, maxDegrees);
//apply rotation
transform.rotation = newRot;
如果在这些更改后仍然不起作用,值得注意的是,Unity的文档建议您在使用Euler角度时避免使用360度以上的角度。
你可以通过为你想要应用的每个旋转构建一个单独的四元数来解决这个问题:
//compose and apply a separate quaternion for rotation
var rotated = transform.rotation * Quaternion.Euler(0, DoorOpenAngle, 0);
openRot = rotated.eulerAngles;