Unity有时想获取两个物体之间的相对坐标,但是又不想设置为父子关系。可以用下列代码:
void ComputeLocalTransform(Transform Father, Transform Son)
{
localPosition = Father.InverseTransformPoint(Son.position);
localRotation = Quaternion.Inverse(Father.rotation) * Son.rotation;
}
不建议将四元数改成欧拉角,我尝试过,有可能会出现位姿不一致,猜测原因可能是万向节自锁,也没去验证。 同样,通过反运算可以再求回去,由局部坐标再返回世界坐标:
void ComputeTransform(Transform Father, Transform Son)
{
Position = Father.TransformPoint(Son.localPosition);
Rotation = Father.rotation * Son.localRotation;
}
用来测试的代码也贴上来,可以自己尝试一下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestLocal : MonoBehaviour
{
private Vector3 localPosition;
private Vector3 localEulerAngels;
private Quaternion localRotation;
private Vector3 Position;
private Vector3 EulerAngels;
private Quaternion Rotation;
public GameObject father;
public GameObject son;
private bool x,y,z;
void Start()
{
}
void Update()
{
Test();
if (this.transform.parent != null)
{
ComputeLocalTransform(this.transform.parent, this.transform);
Debug.Log("ComputeLocalTransform");
if (localPosition != this.transform.localPosition)
{
Debug.LogError(this.name + "localPosition is wrong");
Debug.LogError((localPosition - this.transform.localPosition).magnitude.ToString("f4"));
Debug.LogError((localPosition - this.transform.localPosition).ToString("f4"));
}
if (localRotation != this.transform.localRotation)
{
Debug.LogError(this.name + "localRotation is wrong");
}
ComputeTransform(this.transform.parent, this.transform);
Debug.Log("ComputeTransform");
if (Position != this.transform.position)
{
Debug.LogError(this.name + "Position is wrong");
Debug.LogError((Position - this.transform.position).magnitude.ToString("f4"));
Debug.LogError((Position - this.transform.position).ToString("f4"));
}
if (Rotation != this.transform.rotation)
{
Debug.LogError(this.name + "Rotation is wrong");
}
}
}
void ComputeLocalTransform(Transform Father, Transform Son)
{
localPosition = Father.InverseTransformPoint(Son.position);
localRotation = Quaternion.Inverse(Father.rotation) * Son.rotation;
}
void ComputeTransform(Transform Father, Transform Son)
{
Position = Father.TransformPoint(Son.localPosition);
Rotation = Father.rotation * Son.localRotation;
}
void Test()
{
float speed = 5f;
this.transform.Rotate(Vector3.right * Time.deltaTime * speed);
this.transform.Rotate(Vector3.forward * Time.deltaTime * speed);
this.transform.Rotate(Vector3.up * Time.deltaTime * speed);
if(this.transform.position.x > 3)
{
x = false;
}
if (this.transform.position.x < -3)
{
x = true;
}
if (this.transform.position.y > 3)
{
x = false;
}
if (this.transform.position.y < -3)
{
y = true;
}
if (this.transform.position.z > 3)
{
z = false;
}
if (this.transform.position.z < -3)
{
z = true;
}
if(x)
{
this.transform.position = new Vector3(this.transform.position.x + 0.6f * Time.deltaTime, transform.position.y, transform.position.z);
}
else
{
this.transform.position = new Vector3(this.transform.position.x - 0.6f * Time.deltaTime, transform.position.y, transform.position.z);
}
if (y)
{
this.transform.position = new Vector3(this.transform.position.x, transform.position.y + 0.6f * Time.deltaTime, transform.position.z);
}
else
{
this.transform.position = new Vector3(this.transform.position.x, transform.position.y - 0.6f * Time.deltaTime, transform.position.z);
}
if (z)
{
this.transform.position = new Vector3(this.transform.position.x , transform.position.y, transform.position.z + 0.6f * Time.deltaTime);
}
else
{
this.transform.position = new Vector3(this.transform.position.x, transform.position.y , transform.position.z - 0.6f * Time.deltaTime);
}
}
}
不知道为什么运行一段时间后local Position会报错,但是Debug出来显示距离其实没有没有差别,可能是精度的问题吧。
四元数虽然比较难理解,但是是个好东西,建议大家以后表示位姿都用四元数。 如果有错误,请大家指正。
|