/// <summary> /// An implementation of the Pushback method that will store an overlap's resolution details. /// </summary> /// <param name="overlapHitCount"></param> /// <param name="position"></param> /// <param name="orientation"></param> /// <param name="tmpColliderBuffer"></param> /// <param name="tmpOverlapBuffer"></param> /// <param name="validOverlapsMask"></param> /// <param name="interactionType"></param> /// <param name="inflate"></param> /// <returns></returns> private bool StorePushback( ref int overlapHitCount, ref Vector3 position, Quaternion orientation, Collider[] tmpColliderBuffer, OverlapHit[] tmpOverlapBuffer, LayerMask validOverlapsMask, QueryTriggerInteraction interactionType, float inflate) { // Cache self Collider self = Collider(); int nbColliderOverlaps = Overlap( position, // pass position orientation, // pass orientation validOverlapsMask, // pass layermask interactionType, // pass interaction type tmpColliderBuffer, // pass collider buffer inflate); // pass inflate // filter out self OverlapFilters.FilterSelf(ref nbColliderOverlaps, // pass number of overlaps tmpColliderBuffer, // pass buffer self); // pass self to filter // if filtered overlaps exceed 0, solve iteration bool overlapsDetected = nbColliderOverlaps > 0; if (overlapsDetected) // attempt solve: { for (int j = 0; j < nbColliderOverlaps; j++) // loop through queried colliders and resolve the first valid penetration { Collider overlapCollider = tmpColliderBuffer[j]; Transform overlapTransform = overlapCollider.transform; if (Physics.ComputePenetration(self, position, orientation, overlapCollider, overlapTransform.position, overlapTransform.rotation, out Vector3 overlapNormal, out float overlapDistance)) { position += overlapNormal * (overlapDistance + 0.01F); if (overlapHitCount < tmpOverlapBuffer.Length) { tmpOverlapBuffer[overlapHitCount++] = new OverlapHit(overlapNormal, overlapDistance, overlapCollider); } break; } } } return(!overlapsDetected); }
/// <summary> /// The step called every iteration in the IterativePushback method call. <br/> /// You may want to hardcode this into your own collision response scripts as i haven't tested to see if its optimal with so many /// method calls passing in all these parameters over and over again. /// </summary> /// <param name="position"></param> /// <param name="orientation"></param> /// <param name="tmpColliderBuffer"></param> /// <param name="validOverlapsMask"></param> /// <param name="interactionType"></param> /// <param name="inflate"></param> /// <returns></returns> private bool Pushback( ref Vector3 position, Quaternion orientation, Collider[] tmpColliderBuffer, LayerMask validOverlapsMask, QueryTriggerInteraction interactionType, float inflate) { // Cache self for filters Collider self = Collider(); int nbColliderOverlaps = Overlap(position, orientation, validOverlapsMask, interactionType, tmpColliderBuffer, inflate); // Filter out self OverlapFilters.FilterSelf(ref nbColliderOverlaps, tmpColliderBuffer, self); // Check if overlap detection returns nothing or not bool isResolved = nbColliderOverlaps == 0; if (!isResolved) // attempt solve: { for (int j = nbColliderOverlaps - 1; j >= 0; j--) // loop through queried colliders and resolve the first valid penetration { Collider overlapCollider = tmpColliderBuffer[j]; // reference queried collider Transform overlapTransform = tmpColliderBuffer[j].transform; // reference queried transform if (Physics.ComputePenetration( self, // pass self position, // pass position orientation, // pass orientation overlapCollider, // pass overlapped collider overlapTransform.position, // pass its position overlapTransform.rotation, // pass its rotation out Vector3 overlapNormal, // output penetration normal out float overlapDistance)) // output distance { position += overlapNormal * (overlapDistance + 0.01F); // push position out of overlap break; } } } return(isResolved); }