Geometry Distorts on Parent Assignment

Hi,

I have a projectile that I want to attach to another object when they collide. I'm attempting to do this by parenting the projectile to the target object. I can see in the Hierarchy view that it does indeed get parented, but the geometry of the projectile, which is a sphere, gets squished. I can see in the Inspector that the Scale of the projectile has been changed so that is no longer a sphere. Here's my code:

if (objectHit.tag == "Socket") {
  BulbSocketController socketController = objectHit.GetComponent<BulbSocketController>();
  if (!socketController.HasBulb) {
    this.rigidbody.velocity = Vector3.zero;
    this.rigidbody.isKinematic = true;
    this.transform.parent = objectHit.transform;
    socketController.HasBulb = true;
  }
}

If I comment out this line:

//this.transform.parent = objectHit.transform;

the sphere is not squished. Any idea what's causing this behavior?

Thanks for your help!

Mal

If your parent object is non-uniformly scaled, there is no reliable way to avoid that child objects get scaled or skewed.

The best method is to design your objects such that you don't need to scale the parent object non-uniformly.

One thing you could do is make a new root object and make your scaled object a child of that. Then, once the projectile hits the scaled object, make the projectile a child of the root (which is not scaled) instead of making it a child of the scaled object. This of course requires that you have all the movement code affecting the root, and not the scaled object; otherwise the projectile will not move together with the object.

Try adding an intermediary empty GameObject then making that a child of the object with non-uniform scale. Use the empty gameobject as the parent.

@haydster7 's answer works beautifully and in my case adds nothing more than 2 lines of code.

Here’s what I had before (where I wanted to set the object in the script to be the child of the object in the collision:

transform.SetParent(collision.transform);

And here’s how I fixed it:

GameObject glue = new GameObject("Glue");
glue.transform.SetParent(collision.transform);
transform.SetParent(glue.transform);

Hi!

Parenting does indeed morph the geometry of objects. This is because the scale of an object is relative to its parent. For root objects, this means scale relative to the world, but for children it is scale relative to to root. An easy way to fix the situation you describe is to read the local scale of the object when it has no parent (transform.localScale) and after the object becomes a child, write to its lossy scale (transform.lossyScale). This won't be perfect (which is why it's called the lossy scale), but it computes the parent's scale and adjusts the child's scale accordingly. This will usually fix your geometry distortion.

Hope that helps! -CJ

If the reason you are parenting it is simply so that the object will "stick to" and follow the movements of the parent, you might consider, instead of parenting, having the new child object explicitly read the position of the "parent" each frame and follow it.

Following an object's position is easy; it might get a little harder if rotations are also occurring; Rune's solution of a new root object is probably easier in that case.