转载自:
https://blog.csdn.net/weixin_42397471/article/details/113364667
在工作中有时需要将模型的Position变为模型碰撞器的中心点位置,目前实现的思路是:
先给模型添加box碰撞器,然后获得box碰撞器的中点位置(对于规则物体该位置即为模型的中点位置),然后将该位置调整为模型网格的中点位置;
但是在进行网格相关处理时需要考虑到模型的旋转与缩放可能会影响操作;
public class MeshCenterPointToZero_WSY : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
if (!GetComponent<BoxCollider>())
{
return;
}
//记录模型碰撞器中心位置
Vector3 NewPos = transform.TransformPoint(GetComponent<MeshFilter>().mesh.bounds.center);
//记录旋转角度
//因为当Y和Z轴不归零时计算会出现问题
float X = transform.localEulerAngles.x;
float Y = transform.localEulerAngles.y;
float Z = transform.localEulerAngles.z;
//先将物体的旋转重置,缩放完毕后进行旋转复位
transform.localEulerAngles = new Vector3(X, 0, 0);
//记录偏移值
Vector3 PianYiv3 = new Vector3(0, 0, 0);
PianYiv3 = transform.position -
transform.TransformPoint(GetComponent<MeshFilter>().mesh.bounds.center);
//如果物体有缩放时,偏移值也应该进行缩放
PianYiv3 = new Vector3(PianYiv3.x / transform.localScale.x,
PianYiv3.y / transform.localScale.y,
PianYiv3.z / transform.localScale.z);
//网格点开始偏移
Vector3[] MeshV3 = GetComponent<MeshFilter>().mesh.vertices;
for (int i = 0; i < MeshV3.Length; i++)
{
MeshV3[i] += PianYiv3;
}
GetComponent<MeshFilter>().mesh.vertices = MeshV3;
GetComponent<MeshFilter>().mesh.RecalculateBounds();
GetComponent<MeshFilter>().mesh.RecalculateNormals();
GetComponent<MeshFilter>().mesh.RecalculateTangents();
//旋转复位
transform.localEulerAngles = new Vector3(transform.localEulerAngles.x, Y, Z);
//位置复位
transform.position = NewPos;
//碰撞器中心点重置
GetComponent<BoxCollider>().center = Vector3.zero;
}
}