I wanna be a pirate, too! | Unity Physics
Simulating Rigidbody Players on Rigidbody Vehicles in Unity
When developing games that feature rigidbody-based players on moving platforms or vehicles, such as ships, boats, or elevators, the challenge often lies in achieving smooth, realistic movement without resorting to hacky solutions like directly parenting the player to the vehicle. While parenting might seem like a quick fix, it can lead to a myriad of issues, such as glitchy physics interactions and an unrealistic feel. A more robust and scalable solution involves leveraging Unity's physics engine, specifically its friction properties and force applications, to simulate stable, real-time interactions between rigidbody players and vehicles. In this article, we’ll dive into why physics-first approaches should always be prioritized, and how to implement them effectively.
Why Avoid Parenting Techniques?
Directly parenting a rigidbody player to a moving platform or vehicle may seem like a simple solution, but it’s essentially a shortcut that ignores the natural physics interactions between two objects. By removing the actual physics simulation, you’re forcing the player object to inherit the exact transformations of the platform. This can lead to jittery movements, unnatural behavior when interacting with other physical objects, and poor scalability for more complex physics simulations.
For example, if your vehicle is bouncing or tilting slightly due to wave motion or terrain, a parented player won’t react dynamically to those forces. This breaks immersion and makes the system brittle for more advanced mechanics, such as jumping or collisions. By prioritizing the physics system, you maintain a higher level of immersion and open doors to more natural and complex player interactions.
Using Unity’s Friction and Delta Forces
Fortunately, Unity's physics engine provides a much more elegant solution. You can simulate players on vehicles by leveraging the interaction between their colliders and friction forces. Here’s how you can approach it:
Adjust the Friction of Player and Vehicle Colliders: The physics interaction between a player and a moving platform largely depends on friction values. Ensure that both the player's collider and the vehicle's surface collider have appropriate friction settings. Higher friction values will make the player "stick" to the surface better, whereas lower friction will allow for more sliding or slipping—useful for scenarios like icy or wet surfaces.
PhysicMaterial frictionMaterial = new PhysicMaterial(); frictionMaterial.dynamicFriction = 1.0f; frictionMaterial.staticFriction = 1.0f; playerCollider.material = frictionMaterial;
By tweaking these values, you can control how well the player adheres to the vehicle’s surface as it moves.
Apply Delta Forces for Stability: To ensure the player remains in a relatively stable position on the moving vehicle, you can apply small delta forces based on the vehicle's motion. This technique allows the player to dynamically adjust their position and velocity based on the platform's movement without breaking immersion.
Here’s an example implementation:
Vector3 deltaForce = (vehicleRigidbody.velocity - playerRigidbody.velocity) * stabilityFactor; playerRigidbody.AddForce(deltaForce, ForceMode.VelocityChange);
This keeps the player more or less "locked" in place relative to the moving vehicle while still preserving the physical integrity of the interaction. The stabilityFactor
can be adjusted to fine-tune how aggressively the player follows the vehicle.
Handling Non-Physical Players
If your player character is not a rigidbody (i.e., using CharacterController
or direct Transform
manipulation), you can still apply similar principles, though the interaction will be based on the transform instead of physics forces. The key is still to avoid directly parenting the player and instead update the player’s position and velocity based on the vehicle's motion.
For non-physical players, this would look something like:
Vector3 platformVelocity = vehicleTransform.position - lastFrameVehiclePosition; playerTransform.position += platformVelocity; lastFrameVehiclePosition = vehicleTransform.position;
This ensures the player follows the vehicle’s movement smoothly without needing to rely on Unity’s physics engine, while still maintaining dynamic control over how they interact with moving platforms.
Conclusion
Simulating rigidbody players on moving platforms or vehicles in Unity doesn’t need to involve hacky techniques like parenting. By relying on Unity’s physics engine, friction properties, and delta force applications, you can achieve smooth, realistic interactions that scale well for complex systems. This approach also keeps your game's physics interactions more immersive and believable, allowing for richer gameplay experiences.
Whether you’re designing a boat ride or a complex spaceship, remember to let physics do the heavy lifting. For non-physical players, the same principles apply—just with a more transform-based approach. By prioritizing physics-first solutions, your game will benefit from more natural, stable, and scalable movement interactions.