Search Unity

Question Changing transform properties from script has no effect - engine overrides it?

Discussion in 'Scripting' started by SassyPantsy, Mar 28, 2023.

  1. SassyPantsy

    SassyPantsy

    Joined:
    May 17, 2020
    Posts:
    142
    Hi all, really weird situation I've got for myself.
    So I have a chain of game objects that spawn each other, in a way that is dependent on information coming from a server.
    It's a menu, with 3D .gltf models that are downloaded at runtime and displayed as elements on the menu (thanks, Tarodev).
    I have a UI system with a canvas configured to screen space - camera, and an orthographic camera set up to view the canvas and its contents (with correct culling mask layers and so on). Those three objects sit as children of a "System" game object, which is a prefab instantiated at runtime, that has a script running the whole charade. The hierarchy goes:

    Prefab Root: UI System script (instantiated from somewhere else)
    - 1st child: Canvas set to camera space
    - 1st canvas child: 3D models parent
    - Model Prefab (instantiated at runtime)
    - Model Graphic (downloaded)
    - Model Prefab (instantiated at runtime)
    - Model Graphic (downloaded)
    - etc...
    - 2nd canvas child: ortho-camera set up to view canvas contents

    So this is my order of execution:

    The root transform of the prefab is an empty rect-transform containing a manager script. This get instantiated at runtime from a different game object. Then, I lookup my scene's base camera and add the orto-camera to the stack so it would render on top of other things. All good here.
    A line later, I detach the canvas object so it wouldn't have a parent - otherwise it would be a child of another canvas - by running canvas.transform.SetParent(null). Then, according to the amount of 3d models coming in, I instantiate a 'Model Prefab', which serves as a parent to the downloaded .gltf model, and has a script on it that does some stuff. Afterwards, I download and import the gltf models, and enlarge them so they can be seen (3D objects parented to a canvas are rendered ~10 times smaller).
    Each object execute a sort of Init() function on every object it instantiates, where I set up some data, graphics, and transformation values. All of it runs fine, except for the following:

    1. canvas.transform.SetParent(null). - Doesn't do anything. The canvas is still a child of the prefab. Writing canvas.transform.parent = null doesn't do anything either, aside from Unity warning me about it.
    2. The "Model Prefab" game object I instantiate comes with a scale of 0, 0, 0 for some reason, even though in the prefab file, the scaling is (1, 1, 1).
    The weirdest thing, is that after I instantiate the object, I set its localScale from script to be a new Vector3(1,1,1), (also tried Vector3.one), yet its still (0,0,0) for some reason, even after the Init() function ends. The code just doesn't seem to work!
    3. If I run the same code as put above after a GetKeyDown check on Update, it works perfectly! The canvas gets detached from its parent, the objects are scaled correctly, the same code runs just as intended on a different frame.

    Which leads me to believe there's something inside the engine's order of execution that I'm missing. It's either that, aliens, or my sleep deprivation. But something's really strange is happening. By the way, I promise I don't have anything else that controls these transforms' properties. My code isn't the one overriding what I'm trying to do (I triple checked, and am gonna quadruple check).

    Now obviously setting up a crude timer to change the values after a set period of time will justWorkTM, but I really want to understand what's going on here.

    Any help would be appreciated!
     
  2. SassyPantsy

    SassyPantsy

    Joined:
    May 17, 2020
    Posts:
    142
    Well after a good night's sleep, I've fixed it, meaning sleep deprivation remains the greatest source of unsolvable bugs. I still don't know what was causing this to happen.

    The fix was simple. I've placed debug statements and saw that my code's order of execution is -
    Awake()
    AssignValues() - My initialization method on each object
    Start()

    I didn't know a piece of written code could come before Start(), but I guess it can. I still don't know why transform changes are being applied to some of my objects, but maybe it is some forgotten line of my own code.

    Gonna keep this up for the next generation of sleep deprived developers. Go to sleep folks.