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 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.
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).
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.