Child with Rigidbody doesn't move with Parent with Rigidbody
Ok, so I have a helicopter prefab with a rigidbody to control movement. Attached as a child is a missile that has a rigidbody so I can use that when I launch. I had thought the child would move with the parent, but it does not. When the missile is fired, I change the parent to the root, to make it a separate object, and then use it's rigidbody to control movement.
Do I have to remove the rigidbody from the missile to get it to "stick" to the helicopter and move with its parent, then instantiate a rigidbody to the missile when it's launched? If so, how does that look? I mean, my code references a rigidbody, so I have to have the variable in there or the code won't compile. I can't find any way to set rigidbody active or not. I don't want to instantiate the whole missile from thin air, I want to fire the missile that's attached (as a child) to the helicopter. How would I do that?
So I think the problem is that I'm using AddRelativeForce on the Parent (helicopter's) Rigidbody to make it move, and the missile doesn't go with it. I'm still confused because the missile isn't the only child (the rotor and tail rotor are children that do stay with the helicopter), but it's the only child that isn't moving with the parent. It just sits wherever it was spawned and kinda shakes in place.
Tip: You can edit your question text with additional information, you don't need to add an extra comment. :)
A rigidbody parented to another rigidbody does not work very well.
Do I have to remove the rigidbody from the missile to get it to "stick" to the helicopter and move with its parent, then instantiate a rigidbody to the missile when it's launched?
Not quite. But your going the right direction.
You could lock the rigidbody's position via your script while the missile is not fired.
Have a look at Rigidbody.constraints.
Hope this helps.
Appreciate the response. That was the First thing I tried. Didn't work. When I move the helicopter with the forces applied to the rigidbodies, the missiles act like they're not children, i.e. they stay frozen where they are and watch the parent go bye bye.
In the "that's weird" category, I removed the Rigidbody from the child missile to see if it would work, and it still didn't work. So now I'm at a total loss! each part of the mesh is a child, the rotors are children, but the missiles are children that do not move, rigid body or not.
Do you have any code that uses the missiles transform?
$$anonymous$$aybe some script somewhere sets transform.position = transform.position;
in an Update function ?
Setting the constraints works for me. The child acts as a normal child and when "unfreezing" the position of the Rigidbody
, it falls down still rotating with the parent object:
public Rigidbody body;
void Update()
{
if(Input.Get$$anonymous$$ey($$anonymous$$eyCode.F))
{
body.constraints = RigidbodyConstraints.FreezePosition;
}
if(Input.Get$$anonymous$$ey($$anonymous$$eyCode.R))
{
body.constraints = RigidbodyConstraints.None;
}
}
Have a look at your scripts again and if that still won't show you what's causing this, try draging the FPS controller prefab into your scene and parent a new empty rigidbody object to it and see if you can get the wanted behaviour by checking "freeze position" in the inspector.
There might be something else totally wrong with the configuration, but i can't think of anything yet.
Answer by Tanoshimi2000 · Nov 25, 2015 at 01:22 PM
So I finally resolved this. After determining that it was in fact a RigidBody child of a parent with a RigidBody that was causing the difficulty, I removed the RigidBody from the Missile (child), and then instantiate just the RigidBody when it's fired:
// Command to fire the missile. Move it to it's own GameObject and start the tracking
public void FireMissile(Transform newTarget = null)
{
// Set the target, if one was supplied here
if (newTarget) Target = newTarget;
// Move to new GameObject
gameObject.transform.SetParent(GameObject.Find("Scene").transform, true);
// Activate it
Missile = transform.gameObject.AddComponent<Rigidbody>();
Missile.useGravity = true;
Missile.mass = 10f;
Missile.drag = 1;
Force = 1f;
Missile.useGravity = true;
transform.FindChild("Afterburner").gameObject.SetActive(true);
LaunchTime = Time.time; // Start the timer
IsFired = true;
}
This works exactly as I'd hoped, with two missiles attached to the helicopter, when fired, drop off the helicopter, move to the Scene object, and then fly like missile to the target.
This was originally what I thought I'd need to do, but wasn't sure. After rigorous testing, and some help from the community (thanks to Le Pampelmuse and OncaLupe), I was able to discount all other methods (except instantiating the entire object). To be quite honest, if I could just enable/disable the RigidBody Component, that would be the easiest way to do this.
That's very weird. Like I said once, using my example code, I can infinitely "drop" and "catch" a rigidbody parented to another rigidbody. It always falls down or it stays perfect in local space to its parent.
$$anonymous$$aybe the problem is the way you move your helicopter? Do you actually use forces or do you change the position directly?
So I move the helicopter using forces. Specifically, AddRelativeForce. I tried a bunch of different things. I even deleted the missile and put a basic cube in there. Once I added the Rigidbody the cube acted weird too. I think if you change the transform.position it's ok, but it if you move it with a force it's not. I could pause the game and if I move the helicopter the missiles move, but the forces do not move the child if it's a rigidbody.
Which makes sense. If you have a ball in the back of a pickup truck and you floor it, the ball SHOULD roll off the back, not stay stationary. Right?
Yes that would be correct. I believe the scientific term is inertia. Objects want to stay where they are rather than follow external forces.
But in the real world there are no parents or child objects, so i guess this is where we have to fake the realism and apearently it goes wrong when parenting a rigidbody to another one and adding force to the parent. Have you tried adding forces to the missile when it is still a child of the helicopter? Does it behave correctly then?
Having the editor in pause mode will not give you opportunities to observe physics since there are no physics calculations taking place.
The comment chain got too large. Can't reply to your last comment ;)
I have to disagree on the real world topic:
If you are traveling inside a car, the only thing keeping you comfortable in it, is the seat/doors/seatbelt and inertia.
If you were to sit on the roof and it would suddenly accelerate, you would roll down the back because nothing keeps you there. You could hold onto the roof, but that's the same principle as having the seat push against your back.
The loose missile inside the cockpit would perfectly reflect that.
If we live'd in a universe where humans are not affected by inertia, we would not need any seatbelts, because we would never fly out of the windscreen at a 200 mph impact, we would always be stationary inside it. Like a child object in Unity.
In the real world, there are only forces that...haha..force objects to act a certain way.
With parenting, a child behaves as if it was constantly inside a car, but didn't succumb to inertia or any other force that would change its speed, position or size in relation to the parent.
Sadly I lack the proper words to explain scientific terms in English to the standard they are in educational material. I'ts not a my native language.
Here a Wikipedia Page that explains why there are no child objects in the real world. I hope I could get my point across. I never tried to discuss scientific topics in English so please bear with me ;)
Answer by OncaLupe · Nov 25, 2015 at 06:47 AM
Here's what I would do in this situation.
On the helicopter, make the missile a basic object with just the renderer, no rigidbody or scripts. Have a separate object as a prefab that will be the fired missile with full movement code/collider/rigidbody. The helicopter can spawn this prefab when the game starts so it has a reference to it, then set it inactive so it doesn't appear in world. If you have more than one missile, spawn one for each that can be in air at once.
When you fire the missile, the helicopter code disables the on-heli model, moves the real missile to the same position, sets the missile active, then triggers the movement code to start. All done in the same frame there should be no visible change between them and since it's never parented to the helicopter it won't affect flight.
If you have reloading during the level, the fired missile can be just set inactive again on impact and left where it is till it's needed again. This helps performance by not creating/destroying objects that get reused. This is Object Pooling and is a good practice any time there's an object type that needs to be created/destroyed often (bullets/explosions/etc).
Hope this helps, good luck!
I appreciate that, and I would just instatntiate a bullet at fire time, but it seems wasteful when we have these models that are already attached, and then we just need to fire them off. Still, it is a good, practical example of how to do it, but it doesn't answer the question of why? RigidBody inside a RigidBody?
Answer by Donay · Apr 28, 2017 at 03:17 PM
I just had a similar issue… Do not setup a parent and children with a Rigidbody that are not IsKinematic. When you add a Rigidbody to the child GameObject the Transform is controlled by the physics engine. If the Parent GameObject also has a Rigidbody controlled by the physics engine the parent GameoObject will also try and update the child transform, that is already being updated via the physics engine! This leads to unpredictable results, especially if any of the Rigidbodys are connected by joints. Unpredictable results include Objects continually drifting. Physics objects not going to sleep. Feedback loops shaking objects apart.