脚本Unity3D - 打开门不会停止旋转

时间:2015-03-20 14:36:12

标签: unity3d unityscript

是的..这是我第一次在这里提问,所以如果我遗漏任何重要细节我会道歉,我会尽力提供相关信息。

这是我的问题:我正在用一个门打开一个柜子,一扇门工作得很好。然而,另一扇门被镜像并沿同一旋转打开,使其向内打开而不是向外打开 我的猜测(作为一个完整的初学者,请注意)就是那个

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

1 个答案:

答案 0 :(得分:1)

你误解了Slerp的作用。您希望它的行为更像RotateTowards

与任何线性插值函数一样,

Slerp采用两个值fromto,然后返回另一个值为t%的值他们。这有时非常有用,但在这里并不是你想要做的事情。

另一方面,

RotateTowards采用两个值currenttarget,然后将currenttarget转动最多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的文档建议您避开360度when working with Euler angles以上的角度。

您可以通过为要应用的每个轮换构建单独的四元数来解决此问题:

//compose and apply a separate quaternion for rotation
var rotated = transform.rotation * Quaternion.Euler(0, DoorOpenAngle, 0);
openRot = rotated.eulerAngles;