变换 Unity 坐标

Transforming Unity coordinates

我在 Unity 中的 A、B、C 处有三个对象。我想将它们的坐标转换为一个新坐标系,该坐标系以 A 点为新原点 (0, 0, 0),以 AB 为新 x 轴的线,以 AC 为新 y 轴的线。如何在这个新坐标space中获取A、B、C的新坐标?

我查看了 transform.InverseTransformPoint(),但我不确定如何让它在这里工作。

更简单的 - non-maths - 解决方案是

  1. 将对象 A、B、C 放在同一个父对象下
  2. 平移和旋转父对象而不是单独旋转所有对象 => 让 Unity 为您计算
  3. 可选择在完成后将它们再次放置在之前的位置 - 或者如果您仍希望能够更改它们的 localPosition 和 localRotation,请将它们保持在旋转的父项下。

否则使用例如Transform.TransformPoint 没有育儿

我将两者都添加到了示例管理器中

public class CoordinateManager : MonoBehaviour
{
    [Header("References")]
    public Transform objectA;
    public Transform objectB;
    public Transform objectC;

    [Header("Coordinate-System Settings")]
    public Vector3 A;
    public Vector3 AB;
    public Vector3 AC;

    [ContextMenu("Apply New Coordinates")]
    public void ApplyNewCoordinates()
    {
        // just for making sure this transform is reset
        transform.position = Vector3.zero;
        transform.rotation = Quaternion.identity;
        transform.localScale = Vector3.one;

        // Make this object parent of objectA,objectB and objectC keeping their current transforms
        // For reverting it later store current parents
        var parentA = objectA.parent;
        var parentB = objectB.parent;
        var parentC = objectC.parent;

        objectA.SetParent(transform);
        objectB.SetParent(transform);
        objectC.SetParent(transform);

        // place this object to the new pivot point A
        // and rotate it to the correct axis
        // so that its right (X) vector euqals AB
        // and its up (Y) vector equals AC
        // Unity will handle the rotation accordingly
        transform.position = A;
        transform.right = AB;
        transform.up = AC;

        // Optionally reset the objects to the old parents
        objectA.SetParent(parentA);
        objectB.SetParent(parentB);
        objectC.SetParent(parentC);
    }

    // Use this method to place another object in the coordinate system of this object
    // without any parenting
    public void SetPosition(Transform obj, Vector3 relativePosition)
    {
        // sets the obj to relativePosition in the 
        // local coordinate system of this rotated and translated manager
        obj.position = transform.TransformPoint(relativePosition);

        // adjust the rotation
        // Quaternions are added by multiplying them
        // so first we want the changed coordinate system's rotation
        // then add the rotation it had before
        obj.rotation = transform.rotation * obj.rotation;
    } 

    // Only for visualization of the pivot point A and the 
    // AB(red) and AC(green) axis in the SceneView
    private void OnDrawGizmos()
    {
        Gizmos.color = Color.white;
        Gizmos.DrawWireSphere(A, 0.1f);

        Gizmos.color = Color.red;
        Gizmos.DrawLine(A, A + AB);

        Gizmos.color = Color.green;
        Gizmos.DrawLine(A, A + AC);
    }
}