Search Unity

FindObjectsOfType<> is broken when invoked from inside PrefabStage (nested prefabs)?

Discussion in 'Prefabs' started by a436t4ataf, May 24, 2019.

  1. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    216
    Is it just me? When I invoke this while viewing a prefabstage, I get returned results from a random scene in the project (not even the last-opened scene!). Seems to be returning objects from the first scene it finds in the project window?

    Also ... anyone know any other ways to find all components of type X, but that actually work with the new nested prefabs system?
     
  2. runevision

    runevision

    Unity Technologies

    Joined:
    Nov 28, 2007
    Posts:
    1,615
    FindObjectsOfType is a runtime API and runtime APIs can't return objects from Prefab stages since it could break your game logic. The API can't know if it's called from a main scene context or from a Prefab stage.

    Instead you can use
    StageUtility.GetCurrentStageHandle().FindComponentsOfType<T>()
     
    a436t4ataf likes this.
  3. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    216
    Excellent, thanks! Looks like that's exactly what I needed.

    Can I suggest:

    1. modify the FindComponentsOfType method to report an error if invoked while in a Prefab stage (since it's right now literally giving incorrect results, it shouldn't be allowed to execute)
    2. modify the docs for FCOT to explicitly say that there's a differnet method you should use in prefabstages!

    Docs here: https://docs.unity3d.com/ScriptReference/Object.FindObjectsOfType.html - don't mention any of this. There's no warning about the (current) incorrect results, and there's no advice on the existence of the StageUtility method.
     
  4. runevision

    runevision

    Unity Technologies

    Joined:
    Nov 28, 2007
    Posts:
    1,615
    Great!

    Can't do that. It's completely supported that your game code (in Play Mode for example) calls that method while you're also in Prefab Mode working on some Prefab.

    Agreed, we should do that.
     
  5. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    216
    I've been thinking about this.

    I am executing code within the callback for "PrefabStage.prefabStageOpened" -- at which point, you can guarantee that FindComponentsOfType is going to generate corrupt data. I believe this is a clear situation where it's correct and safe to block that method call (preferably with an error message explaining why!).

    I see your point that invocation in general could happen while a game is running, so you cannot globally disable all calls to the method just because a prefab pane is open "somewhere" in one of the many EditorWindow instances.