本来是想写一个求A物体在B物体坐标系下的坐标。
写完了才发现有worldToLocalMatrix这个函数,后来查了查还有InverseTransformPoint这个函数。。。
没看API就直接写真血亏。
算了,就当是一次详解吧,直接上代码。
Vector3 world2Local(Transform _worldPosition) {
Matrix4x4 trans = new Matrix4x4(
new Vector4(1, 0, 0, 0),
new Vector4(0, 1, 0, 0),
new Vector4(0, 0, 1, 0),
new Vector4(-transform.position.x, -transform.position.y, -transform.position.z, 1));
Matrix4x4 rotZ = new Matrix4x4(
new Vector4(Mathf.Cos(-transform.eulerAngles.z * Mathf.PI / 180), Mathf.Sin(-transform.eulerAngles.z * Mathf.PI / 180), 0, 0),
new Vector4(-Mathf.Sin(-transform.eulerAngles.z * Mathf.PI / 180), Mathf.Cos(-transform.eulerAngles.z * Mathf.PI / 180), 0, 0),
new Vector4(0, 0, 1, 0),
new Vector4(0, 0, 0, 1));
Matrix4x4 rotX = new Matrix4x4(
new Vector4(1, 0, 0, 0),
new Vector4(0, Mathf.Cos(-transform.eulerAngles.x * Mathf.PI / 180), Mathf.Sin(-transform.eulerAngles.x * Mathf.PI / 180), 0),
new Vector4(0, -Mathf.Sin(-transform.eulerAngles.x * Mathf.PI / 180), Mathf.Cos(-transform.eulerAngles.x * Mathf.PI / 180), 0),
new Vector4(0, 0, 0, 1));
Matrix4x4 rotY = new Matrix4x4(
new Vector4(Mathf.Cos(-transform.eulerAngles.y * Mathf.PI / 180), 0, -Mathf.Sin(-transform.eulerAngles.y * Mathf.PI / 180), 0),
new Vector4(0, 1, 0, 0),
new Vector4(Mathf.Sin(-transform.eulerAngles.y * Mathf.PI / 180), 0, Mathf.Cos(-transform.eulerAngles.y * Mathf.PI / 180), 0),
new Vector4(0, 0, 0, 1));
Matrix4x4 Mview = (new Matrix4x4(
new Vector4(1, 0, 0, 0),
new Vector4(0, 1, 0, 0),
new Vector4(0, 0, 1, 0),
new Vector4(0, 0, 0, 1)
)) * rotZ * rotX * rotY * trans;
Vector4 Pworld = new Vector4(_worldPosition.position.x, _worldPosition.position.y, _worldPosition.position.z, 1);
Vector3 PLocal = Mview * Pworld;
//Vector4 Pcamera = transform.worldToLocalMatrix * Pworld;
Debug.Log(PLocal);
return PLocal;
}
就这样吧,注意Mview中rotZ*rotX*rotY*trans,
因为平常是先旋转再平移,所以这里要先平移再旋转,并且平常是先转z再转x再转y,所以这里是先y再x再z,详情请看unity shader 入门精要第67 和第76页。