Unity3d 围绕父轴旋转子对象时遇到困难

Unity3d 围绕父轴旋转子对象时遇到困难,unity3d,rotation,unity5,quaternions,euler-angles,Unity3d,Rotation,Unity5,Quaternions,Euler Angles,我知道在旋转方面有一百万个问题,我试着读了很多东西,但我似乎无法解决这个问题 我能想到的唯一正确解释它的方法就是用一些画得不好的图表,就这样吧 我有一个父对象和一个子对象(在这里它被表示为一个模具,相对的面加起来是7),这个图中的轴是父X、Y和Z方向 起点: 我希望子对象有两个方法,我将调用RotateZ和RotateXRotateZ和RotateX应将子骰子绕父级Z轴和X轴旋转90度 RotateX: 罗塔雷斯: 我目前拥有的代码是 void RotateZ(int value) {

我知道在旋转方面有一百万个问题,我试着读了很多东西,但我似乎无法解决这个问题

我能想到的唯一正确解释它的方法就是用一些画得不好的图表,就这样吧

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

起点:

我希望子对象有两个方法,我将调用
RotateZ
RotateX
RotateZ
RotateX
应将子骰子绕父级Z轴和X轴旋转90度

RotateX:

罗塔雷斯:

我目前拥有的代码是

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);
}
我应该注意到pivot是父对象

如果孩子从
(0,0,0)
旋转开始,用
(0,0,0)
起点反复调用
RotateZ
RotateX
,这似乎效果很好。例如,如果我调用
RotateX
然后调用
RotateZ
,就会出现这个问题

在最初的
RotateX
调用之后,它将如下所示,给孩子一个
(90,0,0)
的旋转

然后在
RotateZ
之后,期望的结果如下:

但我最终得到的结果是:


我真的不知道我做错了什么。我觉得我已经达到了欧拉角的极限,我需要学习四元数来避免这个问题。我需要什么样的旋转函数才能得到想要的结果?

看起来你需要的是一个非常棒的调用

旋转的 这是团结中最重要的事情之一

不要忘记
RotateAround
围绕向量旋转-任何向量

巨大的小费。。。 在视频游戏工程中,一种普遍存在的技术是:你使用标记,意思是“仅仅是一个空的游戏对象”,你可以将其附加到对象上,也可以将其附加到对象上

通常,您会将对象临时附着到标记,以便移动它,然后再次将其从标记中删除。 下面是如何在代码中实现它。制作一个标记“controlRotator”

  • 使controlRotator成为controlObject的子对象

  • 使其在局部完全笔直:即,与父对象的方向完全相同,即,局部旋转=标识

  • 接下来,巧妙地将controlObject的世界位置设置为smallCube的世界位置…

  • 你的smallCube,记下它的父对象。将smallCube从父对象上移除

  • 下一步,暂时将smallCube作为controlRotator的子级

  • …现在你可以

  • 任意旋转控制旋转器!
  • 您只需旋转控制旋转器,而不是小立方体

    请注意,您现在正在做您要求做的事情,您正在使用controlObject的轴旋转smallCube。聪明吧

  • 最后,将smallCube放回步骤4中保存的父级
  • 这正是你要做的。在实践中,这是如此普遍,以至于你会有一个扩展或函数来做它

    请注意,可以根据需要动态创建GameObject controlRotator,并在扭曲后将其删除(这只是一个数学抽象)

    进一步提示。。。 此操作应在controlObject上运行。制作一个名为

    TwistSomethingOnMyAxis.cs
    
    把它放在控制对象上

    只需要一个电话

     public void twistThisThing(Transform twistIt) {}
    
    你要做的是,当你想要扭曲小立方体时,你实际上调用了控制对象上的TwistSomethingOnMyAxis。你看到了吗?就像

    TwistSomethingOnMyAxis:twistor = 
      controlObject.GetComponent<TwistSomethingOnMyAxis>();
    twistor.twistThisThing( smallCube , .. 90 degrees on Y or whatever .. );
    
    TwistSomethingOnMyAxis:twistor=
    controlObject.GetComponent();
    twistor.TwistThis(小立方体,…Y轴90度或其他角度);
    

    我希望这是有意义的!享受!

    你有一个惊人的问题。永远不要出于任何原因使用四元数。这是非常令人困惑的统一手册中提到的四元数;它们仅用于特定的内部用途,与任何正常的游戏编程完全无关。在任何情况下,你所要寻找的都是旋转环绕。请注意,你也可以我只想设置.eulerAngles。@JoeBlow我最初使用的是euler角度,有完全相同的问题。我知道euler角度有一些限制,它们无法完成这项工作,这就是为什么存在四元数的原因。我想这可能是我尝试切换实现的原因之一。我知道它们更容易混淆和混淆使用起来更容易,但如果遇到万向节锁,你别无选择,只能使用它们,我不认为你从不使用它们的观点是正确的。这很简单:我会在回答中解释。我也会给你一个绝对重要的提示。谢谢
    旋转环绕
    完成了这项工作!我已经阅读了你的提示,我想我已经开始理解这一步了,以及它们将如何工作。我将尝试一下!听起来我已经学会了一个非常有用的技巧!谢谢!对于进一步的技巧,它在静态帮助器类中作为静态方法比在可以附加的组件中工作得更好吗?另外,进一步的技巧很好,我的直觉是将这种类型的逻辑放在静态帮助器c中的静态方法中lass,或者将方法扩展到一个类型上,但是在Unity中,我真的需要在组件中考虑更多,这样它就可以附加到任何类型,任何东西都可以被赋予TwistHi GP的行为,很高兴它解决了这个问题。你知道,绝对不使用静态(作为一个规则)在Unity中,把这放在一边。它只是不适用于ECS系统。有一件事,如果你是一个有经验的程序员,第一次玩弄Unity,扩展(类别)是Unity体验的核心:)随时随地使用扩展。关于组件,你真的一针见血,这很有教育意义。