Changes to character velocity when jumping on a moving platform

krstjns

New member
Hello,

I've made some changes to how moving platforms change character velocity (CharacterLocomotion.cs).
Main effects of my changes:
  • Removes jitter and drift when jumping on a fast moving platform (tested with damping set to 0 on a platform moving 2000units/s)
  • Allows to override how velocity is applied when leaving a platform
Code:
@@ -247,6 +247,13 @@ namespace Opsive.UltimateCharacterController.Character
         private Vector3 m_PlatformVelocity;
         private bool m_GroundedMovingPlatform;
         private bool m_PlatformOverride;
+      
+        protected Vector3 m_PlatformDisconnectVelocity;
+        protected Quaternion m_PlatformDisconnectTorque = Quaternion.identity;
+        private bool m_ApplyPlatformDisconnectMovement;
+
+        protected float m_PlatformDisconnectVelocityMagMax = 0.01f;
+        protected float m_PlatformDisconnectTorqueMagMax = 0.01f;
 
         public Collider[] Colliders { get { return m_Colliders; } }
         public Collider[] IgnoredColliders { get { return m_IgnoredColliders; } }
@@ -548,6 +555,21 @@ namespace Opsive.UltimateCharacterController.Character
             // Rever the collision layer to the previous value.
             EnableColliderCollisionLayer(collisionLayerEnabled);
         }
+      
+        protected virtual bool UpdatePlaformDisconnectMovement()
+        {
+            var damping = m_MovingPlatformForceDamping * (m_TimeScale * TimeUtility.FramerateDeltaTime);
+          
+            m_PlatformDisconnectVelocity /= (1 + damping);
+            m_MoveDirection += m_PlatformDisconnectVelocity * Time.deltaTime;
+
+            m_PlatformDisconnectTorque = Quaternion.RotateTowards(m_PlatformDisconnectTorque, Quaternion.identity, damping);
+            m_Torque *= m_PlatformDisconnectTorque;
+
+            return m_PlatformDisconnectVelocity.magnitude > m_PlatformDisconnectVelocityMagMax ||
+                   Quaternion.Angle(m_PlatformDisconnectTorque, Quaternion.identity) > m_PlatformDisconnectTorqueMagMax;
+        }
+      
 
         /// <summary>
         /// Updates the position and rotation changes while on a moving platform.
@@ -559,12 +581,10 @@ namespace Opsive.UltimateCharacterController.Character
                     return;
                 }
                 // The character may have previously been on a platform and should inherit the platform movement.
-                var damping = m_MovingPlatformForceDamping * (m_TimeScale * TimeUtility.FramerateDeltaTime);
-                m_PlatformMovement /= (1 + damping);
-                m_MoveDirection += m_PlatformMovement;
-
-                m_PlatformTorque = Quaternion.RotateTowards(m_PlatformTorque, Quaternion.identity, damping);
-                m_Torque *= m_PlatformTorque;
+                if (m_ApplyPlatformDisconnectMovement)
+                {
+                    m_ApplyPlatformDisconnectMovement = UpdatePlaformDisconnectMovement();
+                }
                 return;
             }
 
@@ -1382,14 +1402,32 @@ namespace Opsive.UltimateCharacterController.Character
             // Update the grounded state. Allows for cleanup when the character hits the ground or moves into the air.
             if (m_Grounded != grounded) {
                 m_Grounded = grounded;
-                if (m_Grounded) {
-                    m_PlatformMovement = Vector3.zero;
-                    m_PlatformTorque = Quaternion.identity;
+                if (m_Grounded)
+                {
+                    m_ApplyPlatformDisconnectMovement = false;
+                    m_PlatformDisconnectVelocity = Vector3.zero;
+                    m_PlatformDisconnectTorque = Quaternion.identity;
+                }
+                else
+                {
+                    m_ApplyPlatformDisconnectMovement = true;
+                    m_PlatformDisconnectVelocity = GetPlatformDisconnectVelocity();
+                    m_PlatformDisconnectTorque = GetPlatformDisconnectTorque();
                 }
                 return true;
             }
             return false;
         }
+      
+        protected virtual Vector3 GetPlatformDisconnectVelocity()
+        {
+            return m_PlatformVelocity;
+        }
+
+        protected virtual Quaternion GetPlatformDisconnectTorque()
+        {
+            return m_PlatformTorque;
+        }
 
         /// <summary>
         /// Applies the final move direction to the transform.
 
Last edited by a moderator:
Thanks for the contribution. I will take a look at this but am removing the CharacterLocomotion attachment - not everyone who views this forum has a license to the controller :)
 
I've started looking in to how to add platform disconnect logic to the PUN add-on as well (same goal, reduce jitter/drift to 0 on fast moving platforms and allow extensions), any input is very welcome!
 
Top