Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Instantiated object transform - position changes when setting parent

Discussion in 'Scripting' started by unity_NFuSXDE6zebcMg, Nov 15, 2022.

  1. unity_NFuSXDE6zebcMg

    unity_NFuSXDE6zebcMg

    Joined:
    Dec 2, 2020
    Posts:
    2
    Hello, I'm having a bit of an issue that I can't seem to resolve. Apologies ahead of time if I'm in the wrong forum! My problem initially looked like it would be simple, but I seem to be missing something. I'm essentially trying to create a "character switcher", so that a player can switch between character models at will.

    TLDR; Setting parent on a child game object sets incorrect position and I don't know how to fix.

    I have a singular character model at the moment which is populating a
    List<Gameobject>
    . The GameObject in the list is a prefab I created with a position of
    Vector3(0.0f, 0.0f, 0.0f);
    I instantiate the object using the following line of code.

    GameObject newPlayerModel = Instantiate(PlayableCharacters[characterIndex], new Vector3(0.0f, 0.0f, 0.0f), Quaternion.identity);


    Which drops the object at (0, 0, 0).. Great! It's further followed by -

    newPlayer.transform.SetParent(gameObject.transform, false);


    Which completely screws up the position of the instantiated object.

    I initially tried all sorts of variations of this, from setting the player model container (gameObject) position to (0,0,0), instantiating with the parent parameter (and not) in a variety of different overloads. I created a new script and assigned it to the child prefab which did one thing within the update() function,
    gameObject.transform.position = new Vector3(0.0f, 0.0f, 0.0f);
    and still nothing.

    For reference, the parent object position is
    Vector3(417.583893,67.929985,-108.508781)
    (copied straight from unity). When I instantiate, the child object position is
    Vector3(0, 0, 0)
    . When I
    .SetParent()
    the child object position then becomes
    Vector3(-417.583893,-67.325882,108.508781)
    which also strangely is the negative values of the parent. The documentation for .SetParent states "This method is the same as the parent property except that it also lets the Transform keep its local orientation rather than its global orientation. This means for example, if the GameObject was previously next to its parent, setting worldPositionStays to false will move the GameObject to be positioned next to its new parent in the same way."
    For reference, neither True, nor false work for worldPositionStays.

    Nothing I do seems to be working. If anyone knows of a solution to this issue please assist. I really appreciate any help given ahead of time I am just STUMPED. The ultimate goal is to keep the child position at (0, 0, 0) after instantiating and setting parent so that it will be on the parent object's position.
     
  2. kruskal21

    kruskal21

    Joined:
    May 17, 2022
    Posts:
    68
    Hi. The value of the worldPositionStays parameter should be dependent on what you want to do.

    1. If you want the child's world position to not change, then set it to true. This means that the physical place where you see the child object in the scene will not change. This will change the child's local position, which is the value you see in the child object's inspector. If the child's world position is 0, then its local position will be the exact negative of the parent's world position. Because Vector3(417, 67, -108) + Vector3(-417, -67, 108) = Vector3(0, 0, 0).

    2. If you want the child's local position to not change, then set it to false. This will not change the child's position in the inspector, and values you see will remain Vector3(0, 0, 0). This will change the child's world position, which is the physical place where you see the child object.

    In most cases you will want option 1. Which will not change where you see the child object. Just don't be scared by the values you see in the inspector, as they are the local position, not the world position, and don't usually matter much.
     
  3. unity_NFuSXDE6zebcMg

    unity_NFuSXDE6zebcMg

    Joined:
    Dec 2, 2020
    Posts:
    2
    Thank you for your response @kruskal21. After reviewing your answer and gaining a better understanding of what was happening with world position vs local position, I managed to get it to work with this.


    GameObject newPlayer = Instantiate(PlayableCharacters[characterIndex], new Vector3(gameObject.transform.position.x, gameObject.transform.position.y, gameObject.transform.position.z), Quaternion.identity);
    newPlayer.transform.SetParent(gameObject.transform, true);


    The character model spawns in at the player location and then I set the parent while keeping the world position and that did the trick! Thank you for all of your help it's been greatly appreciated.
     
    kruskal21 likes this.