How can we be notified the moment an object is instanced in the scene ?
primitives , sprites, prefabs ..all sorts of good stuff can be instanced into a scene :)
So , the hierarchy KNOWS when an new object is instanced , because we can see the object appear in the hierarchy.
For optimization purposes it would be extremely good to be able to know when something i created so that we only need to call something like GameObject.Find once a thing is created.
I know that this is completely possible but I have found no documentation on it.
umm a rough example of what i'm looking for is
private List<GameObject> ladies = new List<GameObject>();
if(SomeUnityClass.ObjectCreated == true)
{
ladies = GameObject.FindGameObjectsWithTag("BeautifulWomen").ToList();
}
Answer by gcoope · Jan 06, 2017 at 05:01 PM
Quite a broad question, depends what you want to track the instantiation of, as well as how you're instantiating it in the first place.
One option would be to look at giving a spawn callback to objects using Actions/Events.
With this you would have a manager 'listening' for any spawn events. Then on any objects you're creating you would trigger a spawn event from Start() or Awake() which would then be picked up by your manager. There's a bit more to it than that, but I would definitely have a look into using events of some form!
thanks for suggesting this , it seems useful, I have not used these much. I guess that the HOW it is being instanced is important for this.
I would need every method which calls any spawning function to subscribe to my event right ? if so then I cant use it at all. unless i can listen for any spawn event from in one single script
Answer by JoshBaz · Jan 06, 2017 at 04:04 PM
I am not good with lists so I used array. Also i used the timer as an example since I don't think its good for optimization if you search for objects in everyframe. You don't really need the timer. Also since you're using a List<GameObject>
or Array in my case you should use GameObject.FindGameObjectsWithTag("BeautifulWomen");
instead of GameObject.FindWithTag("BeautifulWomen");
since you want to manage more than one object.
GameObject[] ladies; //The collection of ladies you are managing
GameObject[] firstSetOfLadies; //The collection of ladies you recieve whenever you search for new ladies
public float ladyTime;
void Start(){
ladies = GameObject.FindGameObjectsWithTag("BeautifulWomen");
ladyTime = 0f;
}
void FixedUpdate(){
ladyTime += Time.deltaTime;
if(ladyTime >= 5f)
ladyTime = 0f;
else
return;
//Search for Objects
newSetOfLadies = GameObject.FindGameObjectsWithTag("BeautifulWomen");
if(ladies.length == 0){
ladies = newSetOfLadies;
Debug.Log("First set of ladies!");
return;
}
//Compares each lady to the ladies you currently have. If the lady is new you are notified.
for(int i = 0; i < newSetOfLadies.Length; i++){
GameObject l = newSetOfLadies[i];
int nomatch = 0;
for(int a = 0; a < ladies.Length; a++){
if(l != ladies[a])
nomatch++;
}
if(nomatch == ladies.Length)
Debug.Log(l.name + " is a new lady!");
}
//Sets the array of ladies to the new set of ladies
ladies = newSetOfLadies;
//Displays number of ladies currently
if(ladies.Length > 0)
Debug.Log("I have " + ladies.Length + " ladies!");
else
Debug.Log("No Ladies... :,-(");
}
hahaha i enjoyed reading that :D
Forget searching every frame , I don't want to even search after every 10 or 20 frames . I only want to search once any new object is added to the scene.
The introduction of multiple arrays and time functions and the extra for loops while calling newSetOfLadies = GameObject.FindGameObjectsWithTag("BeautifulWomen");
under FixedUpdate would make the process really slow.
Lists are actually quite easy to use. for example Here is a really fast way of populating a List of with object that we want to find.
private List<GameObject> ladies = new List<GameObject>();
private int LadyCount =-1;
void Update()
{
// you completely avoid the need to call FindObjectWithTag every frame of every couple frames
if(LadyCount < ladies.Count)
{
ladies = GameObject.FindObjectWithTag("BeautifulWomen").ToList;
LadyCount = ladies.Count;
}
//If you want to trigger a search all you have to do is set LadyCount to -1 or any number less than 0;
}
However this too can be optimized to automatically do a search ... only we we could be told when a new object is added to the scene or hierarchy >.>
If you have a game where many things are spawned in the scene then sure the search will be triggered just as often but will still be faster then if you didn't use this method.
However spawning and destroying object is costly so better to leave those in the scene and activate and reuse them when you need to , that way you don't call the search frequently at all.
Answer by UnityCoach · Jan 06, 2017 at 05:37 PM
You can make your List a property (variable + accessor) and add an event in it, like :
public delegate void LadiesChange(List<GameObject> ladies) ;
public event LadiesChange LadiesChanged;
private List<GameObject> _ladies;
public List<GameObject> Ladies
{
get { return _ladies; }
set
{
if (value != _ladies)
{
_ladies = value;
if (LadiesChanged != null)
LadiesChanged(_ladies);
}
}
}
Your answer
Follow this Question
Related Questions
How to find GameObject in script? 1 Answer
What to use instead of GameObject.Find and GetComponent 2 Answers
GameObject.Find not working? 1 Answer
How to find all GameObjects in Hierarchy by name and put them in an Array[] ? (C#) 1 Answer
Way of Finding/accessing a variable from another script though another variable? 1 Answer