【问题标题】:Unity 3D - How to gllobaly rotate one object based on secondUnity 3D - 如何基于第二个全局旋转一个对象
【发布时间】:2023-03-04 18:46:01
【问题描述】:

我在 Unity 中遇到了一个非常大的旋转问题。我想要什么:

我有两个 3D 对象。只有一个用于玩家操作,第二个对象 Transform.rotation 和 Transform.position 取决于比例为 1/10 的第一个对象。这意味着如果我将第一个对象从 (0,0,0) 移动到 (10,30,90),那么 obj.2 将从 (0,0,0) 移动到 (1,3,9)。这很简单。但是我在旋转方面遇到了很大的问题。

我无法在正常变换上进行旋转,因为它基于“本地位置”。 下面我用最简单的 2D 对象情况提出我的问题:

正如您所见,当我将红色对象旋转 +90 度时,第二个对象旋转 +9 度,并且轴相对于世界变得不同。在 3D 世界中进行更多转换后,它会变得一团糟。例如,经过一些变换后,如果我想从我身上旋转 3D 对象(比如在摩托车上使用加速器),首先让第二个对象从左向右旋转(因为它基于对象轴)。

当然,使用 Transform.Rotate 代替 Transform.localRotate(或使用 Transform.EulerAngles 代替 Transform.localEulerAngles)不是一个解决方案,因为它只意味着对象是子对象(这种情况不是)。

我发现了什么:

使用 Transform.Rotate(Xdegree,Ydegree,Zdegree, Space.World) 是旋转第二个对象的解决方案!

我需要什么:

来自第一个(由玩家操作)对象的 Xdegree、Ydegree 和 Zdegree。

Transform.EulerAngles 和 Transform.Rotation 不起作用,因为它返回“本地对象”旋转。

所以...我知道如果 3D obj.2 旋转为 (0;30;0) 并且我使用 obj2.Rotate(45,0,0) 那么 obj.2 旋转将为 (~37.76;~ 39.23;~26.56),没关系。但我不知道如何转换另一种方式(从“本地”旋转 XYZ 到我可以在 Transform.Rotate() 上使用的度数(当然我会在最后将这个值(xyz)除以 10,因为我有 1 /10 移动刻度))

【问题讨论】:

  • can't make rotation on normal transform because it's based on "local position" .. 不,不是 .. 有transform.rotation 是全局旋转,有transform.localRotation 是局部旋转......还有transform.Rotate 由默认在本地空间中旋转,但您可以更改将 Space.World 作为最后一个可选参数传入,使其在全局空间中旋转...
  • Transform.EulerAngles and Transform.Rotation DOESN'T work because it's returns "local objects" rotations .. 再次,这是错误的。 transform.eulerAnglestransform.rotation 都在全局空间中.. 本地空间将是 transform.localEulerAnglestransform.localRotation ...
  • 还有 tranform.rotatearound
  • 是的,这就是我使用引号的原因...所以.. 如果您不同意,请回答我:我将 obj1 从 (0,30,0) 旋转到 (20,100,0)。 Diff (20,70,0) 我应该如何在 obj2.transform.Rotate (x,y,z) 上使用值以在 Inspector 视图中生成 (2,7,0)?
  • @BugFinder 那又怎样?

标签: c# unity3d rotation


【解决方案1】:

如果您需要一个 GameObject 具有另一个 GameObject 的 1/10 的旋转和位置,您可以使用类似:

//the player-controlled cube
public Transform t1;
//the 1/10 cube
public Transform t2;

void Update(){
    //set the position of t2 to 1/10 of the position of t1
    t2.position = 0.1f * t1.position;
    //get the axis and angle of t1's rotation
    t1.rotation.ToAngleAxis(out float angle, out Vector3 axis);
    //t2 should be rotated in the same direction (axis), but with 1/10th of the angle
    t2.rotation = Quaternion.AngleAxis(angle * 0.1f, axis);
}

编辑:要允许重置增量旋转和更改目标,您可以执行以下操作。注意:当它超过一个完整的圆圈时会出现故障,我不是四元数方面的专家,所以你必须自己弄清楚。

    //the player-controlled cube
    public Transform t1;
    //the 1/10 cube
    public Transform t2;
    private Vector3 t1originalPosition;
    private Quaternion t1originalRotation;
    private Vector3 t2originalPosition;
    private Quaternion t2originalRotation;

    void Start()
    {
        ResetTarget(t1);
    }

    void Update()
    {
        if (t1 != null)
        {
            //set the position of t2 to 1/10 of the position of t1
            t2.position = t2originalPosition + 0.1f * (t1.position - t1originalPosition);

            Quaternion t1Rotation = t1.rotation * Quaternion.Inverse(t1originalRotation);
            //get the axis and angle of t1's rotation
            t1Rotation.ToAngleAxis(out float angle, out Vector3 axis);

            //t2 should be rotated in the same direction (axis), but with 1/10th of the angle
            t2.rotation = Quaternion.AngleAxis(angle * 0.1f, axis) * t2originalRotation;
        }
        
    }

    public void ResetTarget(Transform target = null)
    {
        t2originalPosition = t2.position;
        t2originalRotation = t2.rotation;

        t1 = target;
        t1originalPosition = t1.position;
        t1originalRotation = t1.rotation;
    }

【讨论】:

  • 一段时间后我的 obj1 被重置。因此,如果我将位置从 X: 0 转换为 X: 100,则 obj2 X 应该是 10 (1/10),经过几秒钟 obj1 回到 X:0(但 obj2 不是)。如果我再次移动我的 obj1 但例如从 X:0 到 X:200,则 obj2 应该有 10 + 200 * 1/10 = 30
  • @SzymonWołyniec 我添加了一个更改目标的示例
  • 是的,但是正如您所写,制作 360 度会导致此解决方案无法正常工作,我前段时间就这样做了...我正在寻找完全有效的解决方案,而不仅仅是一个完全旋转:/
【解决方案2】:

使用四元数而不是欧拉角(xyz 旋转角)。并简单地将一个对象的全局旋转值(四元数)赋予另一个对象。 要将四元数相加,只需将它们相乘即可。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多