Now that we can SceneManager.LoadScene ( .. , {ADDITIVE}), is there a method or a way to (FASTER) find all objects in a SPECIFIC SCENE?
Something like the old GameObject.Find, but with maybe secondary optional attribute of scene_Id/scene_name like this:
GameObject.Find ("object_name", "scene_name");
I checked docs but didn’t see anything new in this regard. Id like to only search in specific scene (and save time - save BIG for bigger scenes). Should i create Feature request for this? What do You think?
I don’t know if you are still looking for a solution. You can get all the objects from a scene using this:
// get a reference to the scene you want to search.
Scene s = SceneManager.GetSceneByName("sceneName");
GameObject[] gameObjects = s.GetRootGameObjects();
Then search through the array. This should work with additive scenes.
If you’re deeply concerned about time, then using GameObject.Find probably isn’t the best choice to begin with. As for executing code in specific scenes, you can use the GetActiveScene() method.
using UnityEngine;
using UnityEngine.SceneManagement;
public class FindScriptInActiveScene : MonoBehaviour
{
void Start()
{
Scene activeScene = SceneManager.GetActiveScene();
// Find all instances of MyScript in the active scene
MyScript[] scripts = FindObjectsByType<BaseSceneGameplayController>(FindObjectsInactive.Include, FindObjectsSortMode.None);
// Filter for instances that are part of the active scene
foreach (MyScript script in scripts)
{
if (script.gameObject.scene == activeScene)
{
Debug.Log("Found MyScript instance in the active scene: " + script.gameObject.name);
return;
}
}
}
}
If thats the case, then you need to use events and generic lists/dictionaries
An approach like this would be good: (Read about events and delegates)
Attach a script like this for all your gameobjects which you want to be search in scenes
using UnityEngine;
using System.Collections;
public class GameObjectEvents : MonoBehaviour {
public static event System.Action<GameObject> notifyAwake;
public static event System.Action<GameObject> notifyDeath;
// Use this for initialization
void Start ()
{
//Notify if any listeners are present about its awake status
if(notifyAwake != null)
notifyAwake(gameObject);
}
void OnDestroy()
{
// tell any listeners if present that this gameobject is dying
if(notifyDeath != null)
notifyDeath(gameObject);
}
}
and now have this script where you can access the scene specific gameobjects
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class GameObjectEventsHandler : MonoBehaviour {
//Dictionary of specific scene gameobjects
Dictionary<string, List<GameObject>> specificSceneObjects = new Dictionary<string, List<GameObject>>();
//Listen to the events
void OnEnable()
{
GameObjectEvents.notifyAwake += HandlenotifyAwake;
GameObjectEvents.notifyDeath += HandlenotifyDeath;
}
void OnDisable()
{
GameObjectEvents.notifyAwake -= HandlenotifyAwake;
GameObjectEvents.notifyDeath -= HandlenotifyDeath;
}
void HandlenotifyAwake (GameObject obj)
{
//if there are no objects for this scene then create a new list with the current scene list name
if(!specificSceneObjects.ContainsKey(Application.loadedLevelName))
specificSceneObjects.Add(Application.loadedLevelName, new List<GameObject>());
//now add the gameobject which sent this event upon awake/start to this list
specificSceneObjects[Application.loadedLevelName].Add(obj);
}
void HandlenotifyDeath (GameObject obj)
{
//if the dicitonary has this object then remove it upon object destroy
if(specificSceneObjects.ContainsKey(Application.loadedLevelName))
{
if(specificSceneObjects[Application.loadedLevelName].Contains(obj))
specificSceneObjects[Application.loadedLevelName].Remove(obj);
}
}
}
Use scene manager if u r using new unity 5.3
If scene manager can give which scene is currently loading(the additive one) then u will have to feed that value into the dictionary key instead of loaded scene name which will give the one which was loaded before
Now you will have a dictionary of gameobjects for that scene .
and you can access its list like this :
List<GameObject> objList = GameObjectEventsHandler.specificSceneObjects["your scene you want"];
now you can iterate through this list to find any object by using list.first or something similar methods