I am trying to make a model of a car. For this, I have the following hierarchy:
Originally, the only the object “PlayerCar” was a Rigid Body. The different wheels are all cylinders with a Mesh Collider attached.
This all worked fine, and when I spawn the car at a certain height, it drops down until the wheels collide with the ground:
Now, I want to attach Rigid Bodies to the different wheels. (Because I need the velocity vectors of the wheels in a script)
When I do this, the wheels still collide with the ground, but the link with the PlayerCar object (the pink cube) and the Body (blue) seems to break:
So now two questions:
Why is this?
I want the car body to stay in the same position relative to the wheels, but I also need the wheels to be a Rigid Body. How can I achieve this?
(P.S. I am very new to Unity, so this is probably a ‘stupid’ question… I did however search for a solution on the forums, but could not figure it out that way.)
Not a stupid question, but gets at the way that Unity structures physics.
A dynamic Rigidbody should only be in the root of an object, and all the parts of the object are (ideally) rigid, that is, they don’t change positions or rotations relative to that root.
If you need moving assemblies of parts, like robot arms or forklifts or doors, then you should be working with Joints. Each separate part is at its own root with its own Rigidbody, but are associated (a.k.a. attached) with each other using various kinds of Joint components. Do not try to parent one Rigidbody to another.
If you want to add physical behavior to the individual wheels, like a suspension, there is a “wheel collider” which kinda skips the Joint concept and does some of the work of creating a spring-like suspension on its own. This gets a bit complicated for this reply, but just wanted to let you know it exists.
Now, your actual stated reason was “{b}ecause I need the velocity vectors of the wheels.” It’s pretty easy to calculate the actual velocity of something without resorting to adding a Rigidbody to it.
Haven’t tested this but you should be able to drop these on any non-Rigidbody child and get world-space .velocity out of it. If you plan to freeze time, you may need more protection in the property code. In practice, your code can really just do this without a component, and just use the formula in line 7 to track the velocity of something.
[DefaultExecutionOrder(+10000)]
class MeasureVelocity: MonoBehaviour
{
private Vector3 lastPosition;
public float velocity =>
(transform.position - lastPosition) / Time.fixedDeltaTime;
public void FixedUpdate()
{
lastPosition = transform.position;
}
}