Search Unity

Resources.FindObjectsOfTypeAll() PERMANENTLY effects changes after stop playing?!

Discussion in 'Editor & General Support' started by MrLucid72, Jul 9, 2017.

  1. MrLucid72

    MrLucid72

    Joined:
    Jan 12, 2016
    Posts:
    996
    I have this code:

    Object[] allGameObjsInScene = Resources.FindObjectsOfTypeAll(typeof(GameObject))

    It's supposed to iterate through gameobjects and turn them all on (for the purpose of loading the scene faster async instead of just show a frozen screen. AsyncOps for loading a scene only goes so far) -- unless it has a dummy object that says not to (then it's skipped and the dummy obj is destroyed).

    Welp... this code apparently permanently changes and even "applies" the prefab changes in your resource folder. I'm not talking until you press the "stop" button: Even after. WHOA!

    Luckily I have collab and can revert 2 days ago before I implemented this.

    The docs say

    > It will also list internal stuff, therefore please be extra careful the way you handle the returned objects.

    I knew it would list internal stuff -- I also know the definition of the "internal" keyword.

    Is this a bug? Or did the doc person forget to add this? Or if it's me, please explain :)
     
    Last edited: Jul 9, 2017
  2. Dreamwriter

    Dreamwriter

    Joined:
    Jul 22, 2011
    Posts:
    472
    Perhaps it’s because you were changing objects while the scene was still loading...those changes may end up changing the scene itself since the changes are being made while the scene thinks it isn’t finished loading.

    Just a theory. In a similar situation, if you spawn GameObjects while the game is being shut down, those GameObjects stay in the scene afterwards.
     
  3. MrLucid72

    MrLucid72

    Joined:
    Jan 12, 2016
    Posts:
    996
    > Perhaps it’s because you were changing objects while the scene was still loading to do things the game engine wasn’t designed to do?

    Resources is Unity API, not C# -- it doesn't seem out of bounds at all to gather objects then turn them active or !active ~ at least not to have this effect. That's interesting about the shutting down thing. Overall, this is a really scary call. I found that, as of 2016 (forgot which ver), you can actually grab all objects in the scene with SceneManager and do stuff with them. 2nd answer (not the "best" answer) >> http://answers.unity3d.com/questions/158172/findsceneobjectsoftype-ignoring-the-inactive-gameo.html

    This post above is also how I found out how to gather inactive objects in the first place with the "accepted answer".
     
  4. Dreamwriter

    Dreamwriter

    Joined:
    Jul 22, 2011
    Posts:
    472
    My point was, if you’re telling a scene to load asynchronously and then using that call as a hack to access objects before the scene is done loading and properly initialized (as it sounds to me like you are doing), that seems to me to definitely be something the engine programmers wouldn’t expect anybody would ever do, so could have unexpected consequences.

    The call to GetObjectsOfTypeAll is definitely powerful, back in the day it was even an internal undocumented call that people discovered. Eventually Unity made it official, I think because it was the only way to truly see all objects currently in memory (I used to use it to find leaked objects staying in memory between scene loads in Mobile games).
     
  5. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    The "internal" stuff here is not internal as in the keyword, but internal as in stuff used by the engine that you generally don't need to know about.

    Resources.FindObjectsOfTypeAll gets you both assets and live things in the game. As always, editing assets at runtime is a permanent change. It's only things in the scene that gets reverted. This is similar to eg. having a prefab assigned to a public GameObject field, and then editing the prefab instead of an instantiated copy - the prefab change is now permanent.
     
  6. MrLucid72

    MrLucid72

    Joined:
    Jan 12, 2016
    Posts:
    996
    mind = blown

    Thanks for the explanation, whew.. switching to SceneManager to get the objects in scene then get !active children via their transform seemed to be wayyyyyyyyyyyyyy less scary.
     
    Last edited: Jul 10, 2017