版本:Unity 6 (6000.0)
语言中文
  • C#

Physics.ComputePenetration

建议更改

成功!

感谢您帮助我们提高 Unity 文档的质量。虽然我们无法接受所有提交内容,但我们会认真对待来自用户的每一项建议更改,并针对适用内容进行更新。

关闭

提交失败

由于某种原因,您的建议更改提交失败。请在几分钟后<a>重试</a>。感谢您抽出时间来帮助我们提高 Unity 文档的质量。

关闭

取消

声明

public static bool ComputePenetration(Collider colliderA, Vector3 positionA, Quaternion rotationA, Collider colliderB, Vector3 positionB, Quaternion rotationB, out Vector3 direction, out float distance);

参数

colliderA 第一个碰撞体。
positionA 第一个碰撞体的坐标。
rotationA 第一个碰撞体的旋转。
colliderB 第二个碰撞体。
positionB 第二个碰撞体的坐标。
rotationB 第二个碰撞体的旋转。
direction 将碰撞体分开所需的移动方向(最小化)。
distance direction 方向上将碰撞体分开的距离。

返回值

bool 如果碰撞体在给定的姿势下重叠,返回 True。

描述

计算将给定碰撞体在指定姿势下分开所需的最小移动量。

如果函数返回 true,沿着 direction * distance 方向移动第一个碰撞体将使碰撞体分开。否则,不定义 direction 和 distance。

其中一个碰撞体必须是盒子碰撞体、球体碰撞体、胶囊状碰撞体或凸多边形网格碰撞体。另一个可以是任意类型。

请注意,并不限制您对碰撞体进行调用时的位置和旋转。传递的位置或旋转与当前设置的位置或旋转不同,不会对物理上移动任何碰撞体产生影响,因此对场景没有产生副作用。

不依赖于任何要首先更新的空间结构,因此不必只在 FixedUpdate 时间范围内使用。

忽略背面三角形,不遵守 Physics.queriesHitBackfaces

此函数对于编写自定义穿透判定函数非常有用。一个具体的示例是角色控制器的实现,其中需要对与周围物理对象的碰撞做出特定的反应。在这种情况下,首先应使用 OverlapSphere 查询附近的碰撞体,然后使用 ComputePenetration 返回的数据调整角色的位置。

using UnityEngine;

// Visualises the minimum translation vectors required to separate apart from other colliders found in a given radius // Attach to a GameObject that has a Collider attached. [ExecuteInEditMode()] public class ShowPenetration : MonoBehaviour { public float radius = 3f; // show penetration into the colliders located inside a sphere of this radius public int maxNeighbours = 16; // maximum amount of neighbours visualised

private Collider[] neighbours;

public void Start() { neighbours = new Collider[maxNeighbours]; }

public void OnDrawGizmos() { var thisCollider = GetComponent<Collider>();

if (!thisCollider) return; // nothing to do without a Collider attached

int count = Physics.OverlapSphereNonAlloc(transform.position, radius, neighbours);

for (int i = 0; i < count; ++i) { var collider = neighbours[i];

if (collider == thisCollider) continue; // skip ourself

Vector3 otherPosition = collider.gameObject.transform.position; Quaternion otherRotation = collider.gameObject.transform.rotation;

Vector3 direction; float distance;

bool overlapped = Physics.ComputePenetration( thisCollider, transform.position, transform.rotation, collider, otherPosition, otherRotation, out direction, out distance );

// draw a line showing the depenetration direction if overlapped if (overlapped) { Gizmos.color = Color.red; Gizmos.DrawRay(otherPosition, direction * distance); } } } }