2016-06-10 45 views
0

我知道有一百万个关于旋转的问题,我尝试了很多东西,但我似乎无法解决这个问题。旋转父轴附近的困难

我能想到正确解释它的唯一方法是用一些描绘得很差的图表,所以在这里!

我有一个父对象,子对象(在这里它被表示为,其中相对的面加起来7的模具),在该图中的轴是父母X,Y,Z方向

启动点:

Starting point

我希望孩子对象有两个方法,我会打电话给RotateZRotateXRotateZRotateX应该以90度的步长围绕父母Z和X轴旋转子骰子。

RotateX:

Starting pointRotateX

RotateZ:

Starting pointRotateZ

我目前拥有的代码是这样

void RotateZ(int value) { 
    transform.rotation *= Quaternion.AngleAxis(90f * value, pivot.transform.forward); 
} 

void RotateX(int value) { 
    transform.rotation *= Quaternion.AngleAxis(90f * value, pivot.transform.right); 
} 

我要指出的是支点的父对象

这似乎工作的伟大,如果孩子开始于(0, 0, 0)旋转,一边喊RotateZRotateX(0, 0, 0)起点的伟大工程。例如,如果我拨打RotateX,然后RotateZ,则会出现此问题。

在初始RotateX之后,它会看起来像这样,给孩子轮换(90, 0, 0)

Starting pointRotateX

然后,RotateZ后所期望的结果是这样的:

After RotateXenter image description here

而是我结束了这一点:

After RotateXAfter RotateXZ

我真的很茫然,我做错了什么。我有一种感觉,我已经达到了欧拉角所能做到的极限,我需要学习四元数来防止这个问题。我需要什么旋转功能才能获得理想的结果?

+0

你有一个壮观的问题。 **由于任何原因,切勿使用Quaternion。**在Unity手册中提到它们是非常令人困惑的;它们仅用于特定的内部使用,与任何正常的游戏编程完全无关。无论如何,你正在寻找的是** RotateAround **。享受 – Fattie

+0

请注意,您可能只想设置.eulerAngles。 – Fattie

+0

@JoeBlow我最初使用欧拉角度,并有完全相同的问题。我知道他们不会做这项工作的欧拉角度有限制,这就是四元数存在的原因。我认为这可能是其中的一种情况,这就是为什么我尝试切换实施的原因。我知道他们更容易混淆,使用起来也更简单,但如果碰上万向节锁,您没有选择,只能使用它们,我不认为您从不使用它们的观点是正确的。 – GP89

回答

2

它看起来像你需要的是真正真棒呼叫

RotateAround

它在团结是最重要的一个。RotateAround doco

不要忘记身边RotateAround旋转时矢量 - 任何载体。

巨大的尖...

在视频游戏工程无处不在的技术是:你用标记” - 这意味着只是一个空洞的游戏对象 - 你重视的对象,或者您附上您的对象。

很多时候,你暂时的对象附加到一个标记,以便再次移动它,然后从标记中删除。

这里是如何做到这一点的代码。做一个标记“controlRotator”。 ..

  1. 化妆controlRotator 您controlObject的孩子。

  2. 使其笔直的地方:即只需一模一样取向父,controlObject,即局部旋转=身份

  3. 接下来,巧妙设置controlObject的世界上的地位,以完全WORLD smallCube的位置...

  4. your smallCube,记下它的父母。把小立方从那个父母那里拿走。

  5. 下一个,暂时使smallCube controlRotator

的孩子......现在你可以...

  • 以任何你喜欢的方式旋转controlRotator!
  • 您只需旋转controlRotator,而不是小的立方体。

    注意,你现在做正是你要求做,您使用的controlObject的轴旋转smallCube 。聪明的权利?

  • 最后,把smallCube回你在步骤4
  • 保存父这正是你怎么做。在实践中,这是很平常的,你会有一个扩展或功能来做到这一点。

    请注意,可以根据需要随时使GameObject controlRotator正常运行,并在扭转后摆脱它。 (这只是一个数学抽象。)

    更多提示...

    此操作应该在“on”controlObject上工作。制作一个名为

    TwistSomethingOnMyAxis.cs 
    

    并将其放在CONTROLOBJECT上。

    这将有一个呼叫

    public void twistThisThing(Transform twistIt) {} 
    

    你要做的就是,当你想要扭动小方块,你居然打电话到TwistSomethingOnMyAxis上的控制对象。你看?所以像

    TwistSomethingOnMyAxis:twistor = 
        controlObject.GetComponent<TwistSomethingOnMyAxis>(); 
    twistor.twistThisThing(smallCube , .. 90 degrees on Y or whatever ..); 
    

    我希望是有道理的!请享用!

    +0

    感谢'RotateAround'完成了这项工作!我已阅读了您的提示,我想我已经开始了解这些步骤以及它们的工作方式。我会试一试!听起来像我学到了一个非常有用的技巧!谢谢!对于更进一步的技巧,作为静态帮助器类中的静态方法,而不是可以连接的组件,它会更好地工作。 – GP89

    +0

    另外提示是好的,我的直觉是把这种类型的逻辑放在一个静态帮助类的静态方法中,或者将该方法扩展到一个类型上,但是在Unity中我真的需要考虑更多的组件,以便它可以被附加到任何类型,并且任何东西都可以被赋予Twist的行为 – GP89

    +0

    嗨GP,很高兴它解决了这个问题。你知道,defintely *不要*在Unity中使用静态(通常),把它放在一边。它仅适用于ECS系统。有一件事,如果你是一位经验丰富的程序员第一次和Unity混蛋,**扩展**(类别)是统一体验的核心:) http://stackoverflow.com/a/35629303/294884使用扩展到处而且总是。 – Fattie