Example #1
0
    /// <summary>
    /// Handles horizontal movement on the XZ plane.
    /// </summary>
    /// <param name="horizontalVelocity"></param>
    /// <param name="entity"></param>
    /// <param name="currPos"></param>
    /// <param name="currRot"></param>
    /// <param name="controller"></param>
    /// <param name="collider"></param>
    /// <param name="collisionWorld"></param>
    private void HandleHorizontalMovement(
        ref float3 horizontalVelocity,
        ref Entity entity,
        ref float3 currPos,
        ref quaternion currRot,
        ref CharacterControllerData controller,
        ref PhysicsCollider collider,
        ref CollisionWorld collisionWorld)
    {
        if (MathUtils.IsZero(horizontalVelocity))
        {
            return;
        }

        float3 targetPos = currPos + horizontalVelocity;

        NativeList <ColliderCastHit> horizontalCollisions = PhysicsUtils.ColliderCastAll(collider, currPos, targetPos, ref collisionWorld, entity, Allocator.Temp);

        PhysicsUtils.TrimByFilter(ref horizontalCollisions, ColliderData, PhysicsCollisionFilters.DynamicWithPhysical);

        if (horizontalCollisions.Length > 0)
        {
            // We either have to step or slide as something is in our way.
            float3 step = new float3(0.0f, controller.maxStep, 0.0f);
            PhysicsUtils.ColliderCast(out ColliderCastHit nearestStepHit, collider, targetPos + step, targetPos, ref collisionWorld, entity, PhysicsCollisionFilters.DynamicWithPhysical, null, ColliderData, Allocator.Temp);

            if (!MathUtils.IsZero(nearestStepHit.Fraction))
            {
                // We can step up.
                targetPos         += (step * (1.0f - nearestStepHit.Fraction));
                horizontalVelocity = targetPos - currPos;
            }
            else
            {
                // We can not step up, so slide.
                NativeList <DistanceHit> horizontalDistances = PhysicsUtils.ColliderDistanceAll(collider, 1.0f, new RigidTransform()
                {
                    pos = currPos + horizontalVelocity, rot = currRot
                }, ref collisionWorld, entity, Allocator.Temp);
                PhysicsUtils.TrimByFilter(ref horizontalDistances, ColliderData, PhysicsCollisionFilters.DynamicWithPhysical);

                for (int i = 0; i < horizontalDistances.Length; ++i)
                {
                    if (horizontalDistances[i].Distance >= 0.0f)
                    {
                        continue;
                    }

                    horizontalVelocity += (horizontalDistances[i].SurfaceNormal * -horizontalDistances[i].Distance);
                }

                horizontalDistances.Dispose();
            }
        }

        horizontalCollisions.Dispose();
    }