Physics.ComputePenetration
Declaration
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 | Вращение второго коллайдера. |
| направление | Направление, в котором перемещение, необходимое для разъединения коллайдеров, является минимальным. |
| расстояние | Расстояние в направлении, которое требуется для разъединения коллайдеров друг от друга. |
Возвращаемое значение
логическое True, если коллайдеры перекрываются в заданных позах.
Описание
Рассчитать минимальное перемещение, необходимое для разъединения данных коллайдеров в указанных позах.
Перевод первого коллайдера по направлению * расстоянию разделит коллайдеры, если функция возвращает true. В противном случае направление и расстояние не определены.
Один из коллайдеров должен быть BoxCollider, SphereCollider CapsuleCollider или выпуклым MeshCollider. Другой может быть любого типа.
Обратите внимание, что вы не ограничены позицией и вращением коллайдеров в момент вызова. Проходя позицию или вращение, которое отличается от текущего установленного, не имеет эффекта физического перемещения любых коллайдеров, таким образом, не имеет побочных эффектов на Scene.
Не зависит от каких-либо пространственных структур, которые должны обновляться в первую очередь, поэтому не обязательно использоваться только внутри FixedUpdate сроки.
Игнорирует обратные треугольники и не уважает Physics.queriesHitBackfaces.
Эта функция полезна для написания пользовательских функций депенетрации. Одним из конкретных примеров является реализация контроллера символов, где требуется специфическая реакция на столкновение с окружающими физическими объектами. В этом случае сначала можно запросить коллайдеры поблизости, используя OverlapSphere и затем настроить позицию символа, используя данные, возвращенные ComputePenetration.
using UnityEngine;
// Visualizes the minimum translation vectors (MTV) required to separate this object from overlapping colliders within a given radius. // Attach to a GameObject with a Collider component. // Note: To compute physics penetration both colliders have to be enabled. [ExecuteInEditMode] public class ShowPenetration : MonoBehaviour { // Radius in which to search for overlapping colliders private float radius = 3f;
// Maximum number of neighbors to check for overlap private int maxNeighbours = 16;
private Collider[] neighbours; private Collider thisCollider;
private void OnEnable() { neighbours = new Collider[maxNeighbours]; thisCollider = GetComponent<Collider>();
if (!thisCollider) Debug.LogWarning($"{nameof(ShowPenetration)} requires a Collider component.", this); }
private void OnDrawGizmos() { if (thisCollider == null) return;
int count = Physics.OverlapSphereNonAlloc(transform.position, radius, neighbours);
for (int i = 0; i < count; ++i) { Collider other = neighbours[i]; if (!other || other == thisCollider) continue;
if (Physics.ComputePenetration( thisCollider, transform.position, transform.rotation, other, other.transform.position, other.transform.rotation, out Vector3 direction, out float distance)) { // Draw penetration vector starting from the other collider's position. Gizmos.color = Color.red; Gizmos.DrawRay(other.transform.position, direction * distance); } } }
private void OnValidate() { radius = Mathf.Max(0f, radius); maxNeighbours = Mathf.Clamp(maxNeighbours, 1, 256); } }