Объявление
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 | Расстояние вдоль направления, необходимое для разделения коллайдеров. |
Возвращает
bool Верно, если коллайдеры перекрываются в заданных позах.
Описание
Вычислите минимальное перемещение, необходимое для разделения заданных коллайдеров в указанных позах.
Перемещение первого коллайдера по направлению * расстояние разделит коллайдеры, если функция вернет значение true. В противном случае направление и расстояние не определяются.
Один из коллайдеров должен быть BoxCollider, SphereCollider CapsuleCollider или выпуклым MeshCollider. Второй может быть любого типа.
Обратите внимание, что вы не ограничены положением и вращением коллайдеров в момент вызова. Прохождение положения или поворота, которые отличаются от установленных в данный момент, не приводит к физическому перемещению каких-либо коллайдеров, поэтому не оказывает побочных эффектов на сцену.
Не зависит от каких-либо пространственных структур, которые должны быть обновлены в первую очередь, поэтому не обязательно использовать их только в пределах временных рамок FixedUpdate.
Игнорирует перевернутые треугольники и не учитывает Physics.queriesHitBackfaces.
Эта функция полезна для написания пользовательских функций депроникновения. Одним из конкретных примеров является реализация контроллера персонажа, где требуется особая реакция на столкновение с окружающими физическими объектами. В этом случае нужно сначала запросить ближайшие коллайдеры с помощью OverlapSphere, а затем скорректировать положение персонажа, используя данные, возвращенные ComputePenetration.
using UnityEngine;
// Визуализирует минимальные векторы перемещения, необходимые для отделения от других коллайдеров, найденных в заданном радиусе
// Присоединяемся к GameObject, к которому присоединен Collider.
[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
);
// нарисуйте линию, показывающую направление отвода, если они перекрываются
if (overlapped)
{
Gizmos.color = Color.red;
Gizmos.DrawRay(otherPosition, direction * distance);
}
}
}
}