回调函数 | 详解 |
---|---|
OnCollisionEnter (Collision) | 当前碰撞器开始接触另一个碰撞器时被调用。 |
OnCollisionStay (Collision) | 当前碰撞器持续接触另一个碰撞器时被调用。 |
OnCollisionExit (Collision) | 当前碰撞器停止接触另一个碰撞器时被调用。 |
物体发生碰撞时的碰撞数据存储于Collision对象中,相关属性:
//变形发生的阈值
[SerializeField] private float deformationThreshold = 5f;
//变形影响的半径
[SerializeField] private float deformationRadius = .5f;
private void OnCollisionEnter(Collision collision)
{
//两个碰撞对象的相对线性速度足够大时网格变形
if (collision.relativeVelocity.magnitude > deformationThreshold)
{
//撞击的物体
GameObject collideGameObject = collision.gameObject;
//物体上的网格
Mesh mesh = collideGameObject.GetComponent<MeshFilter>().sharedMesh;
//网格上的顶点数组
Vector3[] vertices = mesh.vertices;
//遍历撞击接触点
for (int i = 0; i < collision.contactCount; i++)
{
ContactPoint contactPoint = collision.GetContact(i);
//全局坐标转撞击物体的局部坐标
Vector3 world2LocalPoint = collideGameObject.transform.InverseTransformPoint(contactPoint.point);
//遍历网格顶点 顶点移位形成变形
for (int j = 0; j < vertices.Length; j++)
{
//网格顶点到撞击接触点的距离
float magnitude = (world2LocalPoint - vertices[j]).magnitude;
//在影响范围内
if (magnitude < deformationRadius)
{
//位移量
float delta = (deformationRadius - magnitude) / deformationRadius * .1f;
//位移
vertices[j] -= collideGameObject.transform
.InverseTransformDirection(collision.relativeVelocity) * delta;
}
}
}
//更新网格顶点
mesh.vertices = vertices;
mesh.RecalculateNormals();
mesh.RecalculateBounds();
//重启碰撞
collision.collider.enabled = false;
collision.collider.enabled = true;
}
}