Version: 2017.4
LanguageEnglish
  • C#
  • JS

Script language

Select your preferred scripting language. All code snippets will be displayed in this language.

Physics.ComputePenetration

Suggest a change

Success!

Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable.

Close

Submission failed

For some reason your suggested change could not be submitted. Please <a>try again</a> in a few minutes. And thank you for taking the time to help us improve the quality of Unity Documentation.

Close

Cancel

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

Parameters

colliderAThe first collider.
positionAPosition of the first collider.
rotationARotation of the first collider.
colliderBThe second collider.
positionBPosition of the second collider.
rotationBRotation of the second collider.
directionDirection along which the translation required to separate the colliders apart is minimal.
distanceThe distance along direction that is required to separate the colliders apart.

Returns

bool True, if the colliders overlap at the given poses.

Description

Compute the minimal translation required to separate the given colliders apart at specified poses.

Translating the first collider by direction * distance will separate the colliders apart if the function returned true. Otherwise, direction and distance are not defined.

One of the colliders has to be BoxCollider, SphereCollider CapsuleCollider or a convex MeshCollider. The other one can be any type.

Note that you aren't restricted to the position and rotation the colliders have at the moment of the call. Passing position or rotation that is different from the currently set one doesn't have an effect of physically moving any colliders thus has no side effects on the scene.

Doesn't depend on any spatial structures to be updated first, so is not bound to be used only within FixedUpdate timeframe.

Ignores backfaced triangles and doesn't respect Physics.queriesHitBackfaces.

This function is useful to write custom depenetration functions. One particular example is an implementation of a character controller where a specific reaction to collision with the surrounding physics objects is required. In this case, one would first query for the colliders nearby using OverlapSphere and then adjust the character's position using the data returned by ComputePenetration.

#pragma strict
// 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 extends MonoBehaviour {
	public var radius: float = 3f;
	public var maxNeighbours: int = 16;
	private var neighbours: Collider[];
	public function Start() {
		neighbours = new Collider[maxNeighbours];
	}
	public function OnDrawGizmos() {
		var thisCollider: var = GetComponent.<Collider>();
		if (!thisCollider)return ;
		// nothing to do without a Collider attached
		var count: int = Physics.OverlapSphereNonAlloc(transform.position, radius, neighbours);
		for (var i: int = 0; i < count; ++i) {
			var collider: var = neighbours[i];
			if (collider == thisCollider)// skip ourself
			var otherPosition: Vector3 = collider.gameObject.transform.position;
			var otherRotation: Quaternion = collider.gameObject.transform.rotation;
			var direction: Vector3;
			var distance: float;
			var overlapped: boolean = Physics.ComputePenetration(thisCollider, transform.position, transform.rotation, collider, otherPosition, otherRotation, direction, distance);
			// draw a line showing the depenetration direction if overlapped
			if (overlapped) {
				Gizmos.color = Color.red;
				Gizmos.DrawRay(otherPosition, direction * distance);
			}
		}
	}
}
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); } } } }