Пример #1
0
    bool ProcessCollisions(float3 position, ref float3 displacement, ref float3 remainingDisplacement)
    {
        var result = new CollisionShape.Contact();

        result.contactDistance = float.MaxValue;
        result.shape           = null;

        var normalizedDisplacement = math.normalizesafe(displacement);

        var numContacts = collisionShape.CollisionCastAll(
            position, normalizedDisplacement,
            math.length(displacement), layerMask);

        for (int i = 0; i < numContacts; i++)
        {
            var contact = collisionShape[i];

            if (contact.shape == null)
            {
                continue;
            }

            if (math.dot(normalizedDisplacement, contact.contactNormal) > -epsilon)
            {
                continue;
            }

            if (contact.contactDistance < result.contactDistance)
            {
                result = contact;
            }
        }

        if (result.shape != null)
        {
            state.current.isColliding = true;

            state.current.collider              = result.contactCollider;
            state.current.colliderContactPoint  = result.contactPoint;
            state.current.colliderContactNormal = result.contactNormal;

            var adjustedDisplacement = float3.zero;

            if (result.contactDistance > extraSpacing)
            {
                adjustedDisplacement =
                    math.normalizesafe(displacement) *
                    math.min(result.contactDistance -
                             extraSpacing, math.length(displacement));
            }
            else if (result.contactDistance < extraSpacing)
            {
                adjustedDisplacement =
                    math.normalizesafe(result.contactPoint - result.contactOrigin) *
                    (result.contactDistance - extraSpacing);
            }

            remainingDisplacement += displacement - adjustedDisplacement;

            displacement = adjustedDisplacement;

            return(true);
        }

        return(false);
    }