[2D Physics] Fix Child Objects Detaching During bodyType Instantiation
Solution
Unity 2021.x - Unity 6.3.x
Published 14 days ago
An object instantiated as a child of another object using Instantiate does not remain attached to its parent or follow its movement. Attempts to instantiate the object using either Transform.localPosition or Transform.position result in the child appearing detached and stationary relative to the parent or at an incorrect global position.
Additionally, the instantiated object may render incorrectly, appearing as a primitive shape instead of its intended visual representation.
To ensure an instantiated child object moves with its parent, set its Rigidbody2D.bodyType property to Kinematic. For releasing the object, change its bodyType to Dynamic and clear its parent transform.
When instantiating a GameObject that needs to move with its parent, particularly if physics components are involved, the Rigidbody2D.bodyType property of the child object is crucial. If the child object possesses a Rigidbody2D component and is intended to be carried by a parent, its Rigidbody2D.bodyType should be set to Kinematic. This configuration allows the object to be moved directly via its Transform component, preventing physics forces from acting upon it independently and ensuring it follows the parent’s movement.
- Access the
Rigidbody2Dcomponent immediately after callingInstantiateon your prefab. - Set the bodyType to
RigidbodyType2D.Kinematicto disable simulation while the object is parented. - To release the object and restore physics interactions (e.g. for a projectile), switch the bodyType back to
RigidbodyType2D.Dynamic. - Call
transform.SetParent(null)to detach the object from the parent hierarchy.
Regarding the object appearing as a rectangle, this typically indicates an issue with rendering components. Verify that the instantiated GameObject’s prefab has a properly configured SpriteRenderer or MeshRenderer with an assigned asset.
Additional Tips
- Use
transform.SetParent(parent, false)to maintain local scale and position during instantiation. - For Unity 6, ensure you are using
linearVelocityinstead of the legacyvelocityproperty for more consistent physics behavior. - Check that the
Simulatedproperty on theRigidbody2Dis enabled, or the object will not trigger collisions even when bodyType is updated.
using UnityEngine;
public class ProjectileLauncher : MonoBehaviour
{
[SerializeField] private Transform shootPoint;
[SerializeField] private GameObject ballPrefab;
private GameObject currentBall;
void Start()
{
// Instantiate the ball prefab as a child of this object
currentBall = Instantiate(ballPrefab, shootPoint.position, shootPoint.rotation, transform);
// Set bodyType to Kinematic so it follows parent movement
if (currentBall.TryGetComponent<Rigidbody2D>(out Rigidbody2D rb))
{
rb.bodyType = RigidbodyType2D.Kinematic;
}
}
public void Launch()
{
if (currentBall != null)
{
// Detach and restore Dynamic physics
currentBall.transform.SetParent(null);
if (currentBall.TryGetComponent<Rigidbody2D>(out Rigidbody2D rb))
{
rb.bodyType = RigidbodyType2D.Dynamic;
rb.linearVelocity = transform.right * 10f;
}
}
}
}
Related Posts Haven't quite found a solution to your problem? We think these posts might help you.
Content inspired by a Unity discussion post.