- Home /
Place child GameObject at absolute world position
I've been developing in Unity for years and I can't believe I'm stumped by something that should be very simple. I want to instantiate a GameObject and place it at a world position but I also want to parent it to a twisted mess of a tree of GameObjects (all different rotations/scales of the objects in the tree). Seems simple enough. The Unity Editor can figure it out. I can spawn the object but not parent it, run it in the editor, hit pause and then drag the GameObject to the node I want and, lo and behold, it stays put.
But programmatically? That's been a nightmare. I've tried setting the parent transform right IN the Instantiate call. I've tried transform.SetParent() with a true for keepworldposition. I've tried TransformPoint. I've tried a half dozen other things besides this too, and the object keeps moving on me. I do not know the relative position for that complex transform but I also don't want the GameObject to not be parented because I want it deleted when the root is deleted.
Is it even possible to parent a GameObject to somewhere in the bottom of a twisted mess of an object tree but make sure it starts off at an absolute world position? Of course I don't care that the object would move with the parent. In fact, the parent won't be moving. I can't even set it's initial position properly.
Answer by sacredgeometry · Jan 01, 2021 at 07:20 PM
EDIT
This does appear to be broken in that version of Unity. I suggest you report it as a bug and roll back to a previous version
EDIT B
On testing it seems to be fixed in the last LTS version and the latest non LTS versions. So it is likely that it is just this version that has this problem.
transform.position = new Vector3(...)
Description: The world space position of the Transform. The position property of a GameObject’s Transform, which is accessible in the Unity Editor and through scripts. Alter this value to move a GameObject. Get this value to locate the GameObject in 3D world space.
https://docs.unity3d.com/ScriptReference/Transform-position.html
I'm not sure what the confusion is here, you can always set its position relative to the world. If its un-parented and you parent it (I think) it retains its position in world space it just updates its local space coordinates relative to its hierarchy.
Video
https://www.youtube.com/watch?v=MsLrajJXTl4&ab_channel=sacredgeometry
This actually does not work. That was the first thing I tried, hours ago. Just myObject.transform.position = myPos right after I parented it. It ends up below the ground in the different direction from the parent that it should be. It's in the general area but NOT at myPos.
Perhaps I'm using a buggy version of Unity? I'm using 2020.1.17f.
Please see the video I just uploaded .. is that not the behaviour you are looking for?
Thanks so much, I didn't realize you created a video just to answer my question. That was nice. No one has done that before. Okay, if I'm understanding it correctly, when you run it in the editor, node #3 is moving to the world origin via the code "this.transform.position = new Vector3()", which I know is 0,0,0 since C# automatically initializes all values to be zero.
So this is what I'm looking for, yes. But if it works at 0,0,0, why wouldn't it work somewhere else in my world? I tried setting the transform.position (not localPosition) to the absolute location in my world (like 575,50,230 or whatever it was - it's deter$$anonymous$$ed programmatically). The problem is, whether I parent it first or after setting the position, it will not stay there when the object is parented to my hierarchy of objects with all different scales and rotations.
sacredgeometry, I don't see my most recent comment in the hierarchy above. If I click "Show $$anonymous$$ore Comments", it stops with your comment about testing with other values. Does answers.unity.com have the same problem as GameObjects' positions?? LOL But I didn't see that comment until I wrote this whole thing but I'll post it again anyway. Thanks for looking into it :) Yeah, it's very counterintuitive behaviour.
Here's my original reply that is disappearing:
Thanks for even testing it in my version. I hope you didn't have to download it just for that quick test.
This is SO weird. Here's my code:
var bobber=(GameObject)Instantiate(Resources.Load("bobber"));
// bobber.transform.position=pos;
bobber.transform.parent=fish.line.transform;
bobber.transform.position=pos;
//old code, tried it this way too...
// var bobber=(GameObject)Instantiate(Resources.Load("bobber"),pos,Quaternion.identity,fish.line.transform);
So, if I simply instantiate the object on its own and set it to the calculated position it needs to be it, it stays at: 2783.991f, 175.7f, 4639.482f (the correct location;) But parenting it to my hierarchy moves it to: 2809.843f, 170.3355f, 4645.75f Well, the position in the editor showed a local position so I hit pause, dragged it out to the root and then copied down this position.
This is driving me crazy. I have no scripts that are altering this object's position after the fact. Are you aware of anything that could be in the hierarchy of objects I parented it to that could throw off setting transform.position? I know you don't know my hierarchy (it's a U$$anonymous$$A character's bones), but can you think of anything that can throw off Unity's transform.position function?
I appreciate all the help you've given me.
I have moved your answer to a top level comment and not to worry downloading it didnt take all that long.
So running the same tests in the version you are running seems to indicate its always being set to its parents root position i.e. Vector3(0,0,0). I have absolutely no idea why that is but its definitely not normal behaviour for every version previous to it and doesnt seem to be documented to have changed.
There is a more recent version 2020.2.1f1
I am downloading it now to see if its fixed in that.
You'll probably have the answer before me because I just realized I don't ever want to upgrade until I back up my entire game first, and it's huge (24GB compressed). Starting to compress my whole project directory now....
Oh just an aside unless you are just playing around I would suggest not working on any non Long-term support (LTS) versions as they are liable to maybe be broken or more likely for things to change.
It think what I did last month was I downloaded the latest stable version at the time. I should upgrade while you are doing it. I'm always hesitant to upgrade often because it often breaks my code and I like to take care of a whole bunch of issues at once instead of incrementally. Perhaps, incrementally is better though because it's less overwhel$$anonymous$$g :) I guess the reason is I'm usually in the middle of something and don't want to fix extra bugs introduced by Unity, or deprecated behaviours or functions.
With this bug, I'm surprised I haven't witnessed lots of other weirdness in my game, like missing objects or objects located where they shouldn't be. That's what really surprises me.
Answer by ChristmasEve · Jan 02, 2021 at 08:10 PM
I fixed this by having the bobber on the end of my fishing line be a separate, unparented entity and keeping a reference to it in a data structure so I can kill it when the line disappears.
There is either a bug in all recent versions of Unity (at least since 2018) or object.transform.position isn't meant to set a child object to an absolute position in the world. The final position is influenced by all of the scales and rotations in the hierarchy of parents, parents of parents, etc, under which the object sits. The only solutions are to keep the object at the very top-level (global level), parented to an object at 0,0,0 scale 1,1,1 rot 0,0,0, or to parent it to the root of your object as long as that object doesn't move or turn, of course (which was my case).
The is the only acceptable answer so far. I jumped the gun on accepting the other answer but he was extremely helpful and very appreciated.
Answer by ReactGA · Jan 10 at 06:10 AM
I know this quite late, @ChristmasEve or anyone is still facing this issue, What i noticed is that if you set the relative world position of the child object in the same frame it is parented, then for some unknown reasons, it snap to another position.
The solution is obviously to parent the object in a frame and set its world position in the next (or one of the successive frames), either with a coroutine or an Invoke (with a delay). Although the object does flicker in that frame (if its in view of the camera) due to unity first setting its position to a (random i guess) position and you are resetting the object back to where you want it to be. A quick work around for this is to duplicate the object and disable the original (to keep the visual), parent the original, then after resetting the original's position, enable it back and discard the duplicate.
Transform myChildobj, myParentObject;
IEnumarator ParentChild(){
Vector3 childOriginalWorldPos = myChildobj.position;
// to keep the visual if it's within the camera's view
GameObject duplicate
= Instantiate(mychildobj,mychildobj.position,mychildobj.rotataion).gameObject;
//you can disable the renderer instead
myChildobj.gameobject.SetActive(false);
//you can use setParent as well with true or false
myChildobj.parent = myParentObject;
yield return null; // to wait for the next frame
myChildobj.position = childOriginalWorldPos ;
Destroy(duplicate);
}