用旋转定义相对点
Defining a relative point with rotations
我想得到一个相对点(所以它是当前位置 + 方向向量 3)
这样当我旋转游戏对象时它仍然处于相同的相对点
示例:(假设当旋转为 0 时它在 x 轴上距离游戏对象 1 个单位,当旋转为 -90 时它应该在 z 轴上距离游戏对象 1 个单位)
这是我尝试过的:(中心是相对于游戏对象的距离的 vector3)
boxPos = new Vector3(
center.x + transform.position.x + (transform.rotation.eulerAngles.y * (1 / 360) * center.x),
center.y + transform.position.y,
center.z + transform.position.z + (0.5f - (transform.rotation.eulerAngles.y * (1 / 360) * center.z))
);
有什么办法吗?
经过多次建议...结果如下:
测试 1:
代码:
private void OnDrawGizmos()
{
//center is a value I defined... it is the relative point
//no need to care about extents... that's just box size
Vector3 objectPosition = transform.position;
Quaternion rotation = transform.rotation;
boxPos = (rotation * (center - objectPosition)) + objectPosition;
Gizmos.matrix = Matrix4x4.TRS(Vector3.zero, transform.rotation, transform.localScale);
Gizmos.color = Color.red;
Gizmos.DrawWireCube(boxPos, new Vector3(extents.x * 2, extents.y * 2, extents.z * 2));
}
结果:
0-0-0 POSITION: it renders as if it was shifted center/-2
units away from the expected point (as expected from the other notices).
ROTATION: makes it behave weirdly
MOVEMENT: doesn't affect it at all
OTHER NOTICES: boxPos is just center/-2
(so if center is 1, -2, 3
boxPos would be -0.5, 1, -1.5
)
测试 2:
代码:
private void OnDrawGizmos()
{
//no need to care about extents... that's just box size
//first child of the object is just an empty object... shifted by center values... this is always in the intended relative point of the object
boxPos = transform.TransformPoint(gameObject.transform.GetChild(0).position);
Gizmos.matrix = Matrix4x4.TRS(Vector3.zero, transform.rotation, transform.localScale);
Gizmos.color = Color.red;
Gizmos.DrawWireCube(boxPos, new Vector3(extents.x * 2, extents.y * 2, extents.z * 2));
}
结果:
0-0-0 POSITION: it rendered perfectly as expected.
ROTATION: makes it shift away (but around) from the object.
MOVEMENT: also makes it shift way in the direction of movement (with a shift of value: position * (center/2)
which makes the overall movement *1.5 of the expected movement every 1 unit in any direction)
测试 3:
代码:
private void OnDrawGizmos()
{
//no need to care about extents... that's just box size
//first child of the object is just an empty object... shifted by center values... this is always in the intended relative point of the object
boxPos = transform.TransformPoint(transform.InverseTransformPoint(gameObject.transform.GetChild(0).position));
Gizmos.matrix = Matrix4x4.TRS(Vector3.zero, transform.rotation, transform.localScale);
Gizmos.color = Color.red;
Gizmos.DrawWireCube(boxPos, new Vector3(extents.x * 2, extents.y * 2, extents.z * 2));
}
结果:
0-0-0 POSITION: it rendered perfectly as expected.
ROTATION: makes it shift away (but around) the object.
MOVEMENT: it works perfectly as expected.
测试 4:
代码:
private void OnDrawGizmos()
{
//center is a value I defined... it is the relative point
//no need to care about extents... that's just box size
Vector3 objectPosition = transform.position;
Quaternion rotation = transform.rotation;
point = transform.TransformPoint(transform.InverseTransformPoint(gameObject.transform.GetChild(0).position));
boxPos = (rotation * (point - objectPosition)) + objectPosition;
Gizmos.matrix = Matrix4x4.TRS(Vector3.zero, transform.rotation, transform.localScale);
Gizmos.color = Color.red;
Gizmos.DrawWireCube(boxPos, new Vector3(extents.x * 2, extents.y * 2, extents.z * 2));
}
结果:
0-0-0 POSITION: it rendered perfectly as expected.
ROTATION: makes it shift away (but around) the object.
MOVEMENT: it works perfectly as expected.
测试 5:
代码:
private void OnDrawGizmos()
{
//center is a value I defined... it is the relative point
//no need to care about extents... that's just box size
//first child of the object is just an empty object... shifted by center values... this is always in the intended relative point of the object
boxPos = Matrix4x4.TRS(Vector3.zero, transform.rotation, transform.localScale).inverse.MultiplyPoint(transform.GetChild(0).position);
Gizmos.matrix = Matrix4x4.TRS(Vector3.zero, transform.rotation, transform.localScale);
Gizmos.color = Color.red;
Gizmos.DrawWireCube(boxPos, new Vector3(extents.x * 2, extents.y * 2, extents.z * 2));
}
结果:
0-0-0 POSITION: it rendered perfectly as expected.
ROTATION: it works perfectly as expected.
MOVEMENT: it works perfectly as expected.
有一个数学方程可以解决这个问题。假设对象旋转有 Quaternion rotation;
,游戏对象有 Vector3 objectPosition;
,局部点有 Vector3 point;
space,等式是 (rotation * (point-objectPosition)) + objectPosition
Vector3 objectPosition = transform.position;
Quaternion rotation = transform.rotation;
Vector3 point = Vector3(1, 0, 0);
Vector3 worldSpacePoint = (rotation * (point-objectPosition)) + objectPosition;
// if rotation is -90 degrees on the Y axis and objectPosition is zero, worldSpacePoint will be Vector3(0, 0, 1)
对于必须取消旋转和缩放而不是 child 位置的特定用例,我会这样做:
Vector3 boxPos = Matrix4x4.TRS(Vector3.zero, transform.rotation, transform.localScale)
.inverse.MultiplyPoint(transform.GetChild(0).position);
通常情况下,我会说你已经在使用转换,所以只需使用 InverseTransformPoint
来计算 object 的本地位置,如果你想转换回世界位置,你可以使用 TransformPoint
:
Transform target;
Vector3 relativePos;
// ...
Vector3 relativePos = transform.InverseTransformPoint(target.position);
// ...
Vector3 worldPos = transform.TransformPoint(relativePos);
我想得到一个相对点(所以它是当前位置 + 方向向量 3)
这样当我旋转游戏对象时它仍然处于相同的相对点
示例:(假设当旋转为 0 时它在 x 轴上距离游戏对象 1 个单位,当旋转为 -90 时它应该在 z 轴上距离游戏对象 1 个单位)
这是我尝试过的:(中心是相对于游戏对象的距离的 vector3)
boxPos = new Vector3(
center.x + transform.position.x + (transform.rotation.eulerAngles.y * (1 / 360) * center.x),
center.y + transform.position.y,
center.z + transform.position.z + (0.5f - (transform.rotation.eulerAngles.y * (1 / 360) * center.z))
);
有什么办法吗?
经过多次建议...结果如下:
测试 1:
代码:
private void OnDrawGizmos()
{
//center is a value I defined... it is the relative point
//no need to care about extents... that's just box size
Vector3 objectPosition = transform.position;
Quaternion rotation = transform.rotation;
boxPos = (rotation * (center - objectPosition)) + objectPosition;
Gizmos.matrix = Matrix4x4.TRS(Vector3.zero, transform.rotation, transform.localScale);
Gizmos.color = Color.red;
Gizmos.DrawWireCube(boxPos, new Vector3(extents.x * 2, extents.y * 2, extents.z * 2));
}
结果:
0-0-0 POSITION: it renders as if it was shifted
center/-2
units away from the expected point (as expected from the other notices).
ROTATION: makes it behave weirdly
MOVEMENT: doesn't affect it at all
OTHER NOTICES: boxPos is just
center/-2
(so if center is1, -2, 3
boxPos would be-0.5, 1, -1.5
)
测试 2:
代码:
private void OnDrawGizmos()
{
//no need to care about extents... that's just box size
//first child of the object is just an empty object... shifted by center values... this is always in the intended relative point of the object
boxPos = transform.TransformPoint(gameObject.transform.GetChild(0).position);
Gizmos.matrix = Matrix4x4.TRS(Vector3.zero, transform.rotation, transform.localScale);
Gizmos.color = Color.red;
Gizmos.DrawWireCube(boxPos, new Vector3(extents.x * 2, extents.y * 2, extents.z * 2));
}
结果:
0-0-0 POSITION: it rendered perfectly as expected.
ROTATION: makes it shift away (but around) from the object.
MOVEMENT: also makes it shift way in the direction of movement (with a shift of value:
position * (center/2)
which makes the overall movement *1.5 of the expected movement every 1 unit in any direction)
测试 3:
代码:
private void OnDrawGizmos()
{
//no need to care about extents... that's just box size
//first child of the object is just an empty object... shifted by center values... this is always in the intended relative point of the object
boxPos = transform.TransformPoint(transform.InverseTransformPoint(gameObject.transform.GetChild(0).position));
Gizmos.matrix = Matrix4x4.TRS(Vector3.zero, transform.rotation, transform.localScale);
Gizmos.color = Color.red;
Gizmos.DrawWireCube(boxPos, new Vector3(extents.x * 2, extents.y * 2, extents.z * 2));
}
结果:
0-0-0 POSITION: it rendered perfectly as expected.
ROTATION: makes it shift away (but around) the object.
MOVEMENT: it works perfectly as expected.
测试 4:
代码:
private void OnDrawGizmos()
{
//center is a value I defined... it is the relative point
//no need to care about extents... that's just box size
Vector3 objectPosition = transform.position;
Quaternion rotation = transform.rotation;
point = transform.TransformPoint(transform.InverseTransformPoint(gameObject.transform.GetChild(0).position));
boxPos = (rotation * (point - objectPosition)) + objectPosition;
Gizmos.matrix = Matrix4x4.TRS(Vector3.zero, transform.rotation, transform.localScale);
Gizmos.color = Color.red;
Gizmos.DrawWireCube(boxPos, new Vector3(extents.x * 2, extents.y * 2, extents.z * 2));
}
结果:
0-0-0 POSITION: it rendered perfectly as expected.
ROTATION: makes it shift away (but around) the object.
MOVEMENT: it works perfectly as expected.
测试 5:
代码:
private void OnDrawGizmos()
{
//center is a value I defined... it is the relative point
//no need to care about extents... that's just box size
//first child of the object is just an empty object... shifted by center values... this is always in the intended relative point of the object
boxPos = Matrix4x4.TRS(Vector3.zero, transform.rotation, transform.localScale).inverse.MultiplyPoint(transform.GetChild(0).position);
Gizmos.matrix = Matrix4x4.TRS(Vector3.zero, transform.rotation, transform.localScale);
Gizmos.color = Color.red;
Gizmos.DrawWireCube(boxPos, new Vector3(extents.x * 2, extents.y * 2, extents.z * 2));
}
结果:
0-0-0 POSITION: it rendered perfectly as expected.
ROTATION: it works perfectly as expected.
MOVEMENT: it works perfectly as expected.
有一个数学方程可以解决这个问题。假设对象旋转有 Quaternion rotation;
,游戏对象有 Vector3 objectPosition;
,局部点有 Vector3 point;
space,等式是 (rotation * (point-objectPosition)) + objectPosition
Vector3 objectPosition = transform.position;
Quaternion rotation = transform.rotation;
Vector3 point = Vector3(1, 0, 0);
Vector3 worldSpacePoint = (rotation * (point-objectPosition)) + objectPosition;
// if rotation is -90 degrees on the Y axis and objectPosition is zero, worldSpacePoint will be Vector3(0, 0, 1)
对于必须取消旋转和缩放而不是 child 位置的特定用例,我会这样做:
Vector3 boxPos = Matrix4x4.TRS(Vector3.zero, transform.rotation, transform.localScale)
.inverse.MultiplyPoint(transform.GetChild(0).position);
通常情况下,我会说你已经在使用转换,所以只需使用 InverseTransformPoint
来计算 object 的本地位置,如果你想转换回世界位置,你可以使用 TransformPoint
:
Transform target;
Vector3 relativePos;
// ...
Vector3 relativePos = transform.InverseTransformPoint(target.position);
// ...
Vector3 worldPos = transform.TransformPoint(relativePos);