/// <summary> /// Move the transform trying to stop being overlaping other colliders /// </summary> /// <param name="position">start position. Bottom of the collider</param> /// <returns>Final position</returns> Vector3 FixOverlaps(Vector3 position, Vector3 offset, out Vector3 nResult) { Vector3 nTemp = Vector3.zero; // what if you sum all the penetration directions to give the final result // and with each collision, add a CollisionFlag accordingly with the axis collided? CapsuleCollider coll = ownCollider as CapsuleCollider; //Vector3 p = position - (position - coll.transform.position) + (coll.bounds.center - new Vector3(0, coll.bounds.extents.y, 0)); //int nColls = Physics.OverlapCapsuleNonAlloc(p, new Vector3(p.x, p.y + coll.height, p.z), coll.radius, overlapingColliders, GroundLayer, QueryTriggerInteraction.Ignore); // when dead, collide onlly with the world LayerMask overlapMask; if (IsAlive) { overlapMask = m_SolidLayer | m_EnemyLayer; } else { overlapMask = m_SolidLayer; } int nColls = PhysicsExtensions.OverlapCapsuleNonAlloc(coll, offset, overlapingColliders, overlapMask, QueryTriggerInteraction.Ignore); for (int i = 0; i < nColls; i++) { Collider c = overlapingColliders[i]; if (c == ownCollider) { continue; // ignore itself } Vector3 normal; float dist; float dot; if (Physics.ComputePenetration(ownCollider, position, transform.rotation, c, c.transform.position, c.transform.rotation, out normal, out dist)) { // TODO: report bug if (float.IsNaN(normal.x) || float.IsNaN(normal.y) || float.IsNaN(normal.y)) { continue; } // depenetration value for preventing doors // from overlapping with player when it shouldn't dist += Depenetration; dot = Vector3.Dot(normal, Vector3.up); if (dot > m_Settings.SlopeLimit && dot <= 1) { Collisions = Collisions | CC_Collision.CollisionBelow; position += normal * dist; State &= ~CC_State.OnPlatform; } if (dot >= 0 && dot < m_Settings.SlopeLimit) { Collisions = Collisions | CC_Collision.CollisionSides; } if (dot < 0) { Collisions = Collisions | CC_Collision.CollisionAbove; } nTemp += normal; } } nResult = nTemp; return(position); }