Since the prerelease of ECS for Unity, motors have been supported by Unity Physics as of 1.0.0-pre.22. In Unity Physics, motors are a type of joint where one of the constraints that defines the joint exerts a drive force to move to a target. This target can be either position-based, so that the motor always attempts to move to this position, or velocity-based, so that the motor attempts to maintain a specified velocity. Four types of motors are supported (two position-based and two velocity-based types):
Before digging into each motor type, a reminder that you can find demos in the PhysicsSamples project on GitHub and detailed instructions in Unity documentation. The documentation features descriptions of how to set up each motor using several methods, including from a GameObject, from a C# script, or by using a Unity Physics Custom Authoring Component.
The rotational motor is a hinge-like joint that drives toward a target angle. The behavior is similar to an angular spring joint.
When developing this, one use case we had in mind was a swing door that closes by itself. Another could be maintaining a particular angle (for example, one that goes against gravity).
If we want to set up a self-closing swinging door, we could use a Hinge Joint with the following parameters on the Door GameObject, where the Connected Body is the Wall, a static Rigidbody. It’s important to note that to get the desired position-based motor behavior, Use Spring needs to be enabled and Use Motor needs to be disabled (which creates a velocity-based motor).
Let’s say we want to change our swinging door into a revolving door. Now, we're targeting a velocity rather than a position. To do this, you can use a cylinder GameObject as the parent body that has the motor on it and then add some Cube GameObject doors around it.
Have a look at the settings used to make a Hinge Joint into an angular velocity motor:
In the video above you can see that it’s possible to affect the simulation of the motor by either pushing it to go faster, or slowing it down. This is a result of setting the Motor Force to 1,000. Had it been set to infinity, there would have been no way to influence the motor.
A position motor is a prismatic-type joint that will drive towards a target position. The behavior of this motor type is very similar to a spring joint. You might use a position motor when you want a spring-like behavior, but want the spring to rest at a particular position. Another possible use case is for a moving platform, or a sliding door. Let’s say we want to make moving platforms.
To set up a position motor, use a Configurable Joint and set the Target Position, X Drive: Position Spring and X Drive: Maximum Force fields. Here’s a look at the Configurable Joint settings for the platform on the left that will move to the right:
In this video, the platforms bounce when they arrive at their target position, despite setting the Position Spring field. This happens because the motors are using Unity Physics default values for the spring and damping parameters when authored through the Inspector.
For now, we can get around this by creating the motor via scripting, and setting the SpringFrequency and SpringDamping directly. Authoring this type of motor via a script might be a preferable method, since there is more flexibility to project-specific code. You can set the spring and damping parameters, or have the motor wait a specified amount of time before changing directions.
Linear velocity motors are commonly used for a thruster on a rocket, but they can also be used to drive a train, a platform, or whatever else you can think of.
In this example, we made two simple rockets out of primitive shapes and placed a Configurable Joint on the Cylinder body. The rocket moving to the right has a mass of 10 kg and a target speed of 3 m/s, while the rocket moving to the left has a mass of 20 kg and a target speed of 4 m/s.
The screenshot below shows the parameters used for the right-moving rocket (all Configurable Joint options don’t fit on a single screen; those not displayed weren’t modified from the default setting). The parameter to focus on is the Target Velocity, which is set to -3, 0, 0 m/s. The target sign is set relative to where the body will be in the future, therefore the negative sign drives the rocket forward.
In the X Drive settings, the Position Damper is set arbitrarily to 10 and the Maximum Force is 2,000. The Maximum Force of the other rocket is 1,000. This difference influences how much the motor can be pushed around. For example, if the right-moving rocket had a Maximum Force of infinity, then it would stay its course while the other rocket would be pushed to the side.
With Unity Physics, you have access to foundational joint features to help you achieve a wide variety of use cases. Moving forward, we’re progressing toward the simplification of workflows and refining the functionality of built-in Physics components. This includes adding motor support for the spring and damping parameters in the built-in Physics authoring components, and expanding baking support for Configurable Joint authoring components. These planned improvements will help support robust joints, including those that move in more than one axis (example: active ragdolls).
Is there a use case that you want to see supported? Did you notice something confusing? Maybe you have some constructive feedback? Join the discussion in the Unity Physics forum and help further improve Unity Physics.