예제 #1
0
        /// <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);
        }