Creating an object relative to the parent object

Hi, I need to create an object relative to the parent object, that is, I need to take into account the position of the object in space relative to the parent, because the parent object can move. How can this be done?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SensorsSpawn : MonoBehaviour
{
    public Transform parent;
    public GameObject sensor;
    bool isCreated = false;
   
    public void CreateSensor(GameObject obj, Transform pos, bool isCr)
    {
        if (isCr)
        {
            Instantiate(obj, Vector3.zero, Quaternion.identity, pos);
        }
        isCreated = false;
    }
    public void OnButtonClick()
    {
        isCreated = true;
        CreateSensor(sensor, parent, isCreated);
    }
}

You’re doing it here. Has “parent” been assigned a value?

This says:

“Instantiate obj at Vector3.zero, not rotated, and parented to pos.”

Do you mean to supply parent as the fourth argument?

Also, pos is a TERRIBLE name for a Transform because pos implies “position”, and that is only a tiny fraction of what a Transform is.

Always be sure to name things to enhance understanding your code. Naming a Transform as pos is actually very destructive to understanding.

The function is called from below it, where parent is what is passed into the function.

2 Likes

Ha! Good spot… I didn’t even look there since CreateSensor() is public.

In any case, I stand by my variable / argument name assessment: naming a Transform as pos is just vandalizing the codebase for no good reason. :slight_smile:

Agreed

1 Like

Ok, but how to create an object relative to the sides of the parent? That is, let’s say an object has a certain “correct” direction where it should look, and it is necessary that when creating an object, this direction is preserved. If the “correct” direction is understood as the Z axis, then when creating the object, the direction of the Z axis was in the opposite direction from the parent object, how can this be done?

7629922--949567--Безымянный.png

When you Instantiate something, if you give it a non-null parent argument, then the position and rotation arguments become local, eg. relative to the parent.

Try it out, it’s easy to see with a few lines of code.

1 Like

You’re passing in Vector3.zero right now - just pass in something else. If you want to spawn 2 units in front of the parent, try new Vector3(0,0,2) for example.

1 Like

Thank you, I figured it out, but how to change the rotation of an object relative to the parent, just now if you rotate the parent object, and then create a child, then the child does not rotate

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SensorsSpawn : MonoBehaviour
{
    public Transform parent;
    public GameObject sensor;
    bool isCreate = true;

   
    private void CreateSensor(GameObject obj, Transform parentPos)
    {
        if (isCreate)
        {
            Instantiate(obj, new Vector3(parentPos.position.x, parentPos.position.y+4, parentPos.position.z), Quaternion.Euler(0, 180f, 0), parentPos);
        }
        isCreate = false;
    }
    public void OnButtonClick()
    {
        CreateSensor(sensor, parent);
    }
}

Something weird is going wrong. When you rotate the parent, it does rotate all of its children. Which indicates that the thing you’re spawning is not actually being made a child of the desired parent. This is why I asked up there if you were certain that parentPos actually had been assigned, because if you’d accidentally left it null, you’d get a parentless object spawned as you were seeing. However, you’re accessing parentPos’s position in this new code and not getting an exception, so clearly it’s not null. That’s a contradiction - let’s see if we can figure out what it is.

That instantiate call is currently full of stuff you’ve added to try and compensate for whatever this weird wrong thing is, so let’s get that back to a simple version that isn’t trying to fix problems elsewhere:

            var spawned = Instantiate(obj, parentPos);
spawned.transform.localPosition = new Vector3(0f, 4f, 2f);

This will create your object, make it a child of the parentPos, set it at that parent’s (0,4,2) relative position. And when you later rotate that parent, the child will rotate with it.

Note: I separated the position setting into a new line because Instantiate has some confusing, but documented, behavior with regard to world vs local space in the all-parameter override: “If the position and rotation are specified, they are used as the object’s position and rotation in world space.” This is, tbh, weird - I think any experienced dev would expect that to be local space by default. In practice, that particular override is hardly ever used - since I was under the wrong impression about what space it was in I clearly have never used that override, and I’ve been using Unity 16 years. Usually you want to either instantiate under a parent (and therefore will want the position to be relative to that parent), or instantiate at a particular place in worldspace (not caring what the parent is), but almost never both. In your scenario, you care about the object’s parentage and its local position, but not its world position. So we end up with setting local position after spawning.

This wrong assumption - that the position and rotation supplied in this method would be in the parent’s local space - was I think shared by both you and me in the first couple of comments up there, and probably explains the original question. However it would not explain why the spawned object isn’t moving/rotating with the parent.

So anyway - after you have that code, run it and see what happens. Check where the object spawned in the Hierarchy window - is it a child of the parent you expected? It should be, but I have a sneaking suspicion that it isn’t. If it isn’t, then you may have some other script on the object being spawned setting its own parent to null, or something like that.

If it is correctly parented, then check to see if the child moves when the parent object moves. If so, problem solved? If not, then maybe there’s some code running on the child object forcibly setting transform.position and/or transform.rotation, which will overwrite movement it inherits from its parent.

1 Like

Thanks a lot, it works. I finally learned how to do it!