/// <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 CharacterControllerComponent 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();
            }
            /// <summary>
            /// Handles vertical movement from gravity and jumping.
            /// </summary>
            /// <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 HandleVerticalMovement(
                ref float3 verticalVelocity,
                ref Entity entity,
                ref float3 currPos,
                ref quaternion currRot,
                ref CharacterControllerComponent controller,
                ref PhysicsCollider collider,
                ref CollisionWorld collisionWorld)
            {
                controller.VerticalVelocity = verticalVelocity;

                if (MathUtils.IsZero(verticalVelocity))
                {
                    return;
                }

                verticalVelocity *= DeltaTime;

                NativeList <ColliderCastHit> verticalCollisions = PhysicsUtils.ColliderCastAll(collider, currPos, currPos + verticalVelocity, ref collisionWorld, entity, Allocator.Temp);

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

                if (verticalCollisions.Length > 0)
                {
                    RigidTransform transform = new RigidTransform()
                    {
                        pos = currPos + verticalVelocity,
                        rot = currRot
                    };

                    if (PhysicsUtils.ColliderDistance(out DistanceHit verticalPenetration, collider, 1.0f, transform, ref collisionWorld, entity, PhysicsCollisionFilters.DynamicWithPhysical, null, ColliderData, Allocator.Temp))
                    {
                        if (verticalPenetration.Distance < -0.01f)
                        {
                            verticalVelocity += (verticalPenetration.SurfaceNormal * verticalPenetration.Distance);

                            if (PhysicsUtils.ColliderCast(out ColliderCastHit adjustedHit, collider, currPos, currPos + verticalVelocity, ref collisionWorld, entity, PhysicsCollisionFilters.DynamicWithPhysical, null, ColliderData, Allocator.Temp))
                            {
                                verticalVelocity *= adjustedHit.Fraction;
                            }
                        }
                    }
                }

                verticalVelocity = MathUtils.ZeroOut(verticalVelocity, 0.0001f);
                verticalCollisions.Dispose();
            }