- Home /
GameObject instantiates too many objects in update
Hello, I wrote a code that should instantiate a prefab (edgePrefab) just when two other objects (node1 and node2) appear in the scene. However, as soon as both the objects appear in the scene, the prefab is instantiated continuosly in a loop.
I tried to use a bool to instantiate the object just once, but the problem in my code is that nodeSource and nodeTarget never become null.
I don't want to destroy those objects, I just would like the prefab to appear in the scene only one time, as soon as the other two objects are both present in the scene.
Here is my code:
using UnityEngine;
using System.Collections;
public class DrawConnections : MonoBehaviour {
public GameObject edgePrefab;
bool firstUpdate = false;
GameObject nodeSource = null;
GameObject nodeTarget = null;
Vector3 pos = new Vector3(0, 0, 0);
void Start () {
}
void Update () {
if (firstUpdate != true) {
nodeSource = GameObject.Find("Node1");
nodeTarget = GameObject.Find("Node2");
}
if (nodeSource != null && nodeTarget != null)
{
// Debug.Log("Nodes exist");
//Instantiate(edgePrefab, pos, Quaternion.identity);
GameObject oneEdge = Instantiate(edgePrefab, pos, Quaternion.identity) as GameObject;
nodeSource = null;
nodeTarget = null;
firstUpdate = true;
}
}
}
Notice that if I put in the start function
Debug.Log("I start");
I see that the console prints "I start" many times... This shouldn't happen and I think this is the real cause of my problem (that's why the bool value doesn't work). Why is the start funcion executed on each frame? Strange thing is if I comment line 30 (GameObject oneEdge = Instantiate...), then the start function is executed just once (i.e. "I start" printed just once in the console)
Thank you in advance for your help.
modify the 25 line like
if (nodeSource != null && nodeTarget != null && firstUpdate == false)
In 34 line you given that
firstUpdate = true;
Thus 25th line will execute only once . After firstUpdate become true . Thus 25th line's condition become false
And avoid 32 and 33 lines
I already tried this, but it doesn't change the behavior. The problem is that I think the code is entirely executed on each frame: if I put in the start function Debug.Log("I start"); I see the console prints "I start" many times... This shouldn't happen and I think this is the real cause of my problem.
where do you call on this class? (and why not just call it Edge in s$$anonymous$$d of DrawConnections?)
The class is attached to an empty object in the scene. I don't think the name is important (I could call it "moon" and it should work anyway)): to me it makes sense "semantically" in the whole picture of the project, since I have a drawNodes too.
how many times and where is called on this object? (considering the start is called so many times i think it gets called somewhere in an update or draw call)
sidenote: wouldn't drawEdges be more semantic? but namecalling and stuff, doesn't really matter as long as you are consequent.
Answer by Hoeloe · Oct 23, 2013 at 06:01 PM
You're never setting firstUpdate to anything other than false, so it's always running the code repeatedly.
Regardless, that's kind of what the Start method is for - to execute things once only, at the start of the game, and let Update handle the rest. Rather than having all of this code in Update, just put the bits defining nodeSource and nodeTarget, followed by the Instantiate, in Start.
Start is slightly different from Awake in that Start guarantees that all objects are loaded into the scene before Unity calls it, while Awake doesn't. This means that GameObject.Find will work perfectly well in Start.
Oh, and one more thing - you don't need to assign the result of Instantiate to anything if you aren't going to use it in the code later. Since you're defining it as a temporary variable, the code just discards it immediately anyway, so there is literally no point in creating that variable.
I corrected to firstUpdate = true (also in the code I posted) but it has the same exact behavior... it keeps instantiating the object. And I don't understand why. The reason I need to use the update is that I'm building a scene where the user will create a number of objects ("nodes"), and he will be able to select with the mouse a pair of them: when the pair is selected a third object (an edge connecting the two nodes) will be created. At the moment I'm defining nodeSource and nodeTarget within that script, but later they will be public variable defined somewhere else and the script will just wait to have both the variables different than null, will plot the edge and clear those variables until they become different than null again... That's what I'm trying to achieve. PS I'm assigning the result of instantiate to a variable cause I'm gonna use it later (I just posted here the simplified code that creates the loop problem)
If that's the case, then this code isn't the problem. The code you have as that example will work.
Oh, I do want to say that when you're dealing with boolean types, it's usually more readable if you use the ! operator, rather than "!= true". Expressions in conditionals have to evaluate to booleans, so you can just write any boolean expression (including just a boolean variable) in the statement. By prefixing a ! to it, you invert the boolean statement, so if(boolean != true)
becomes if(!boolean)
, which is a little easier to read, especially when you have longer conditions.
If it's not the code, how do I tackle the issue? The code is simply attached to an object in the scene, and it works when I comment line 30. However, when line 30 (instantiate) is executed, the script is exectuted multiple times (including the start function, that should be run just once by default). Any other ideas on how to solve?
It is the code, just not that part of the code. Commenting out lines isn't guaranteed proof that the error lies in that line. For example, any code that sets nodeSource and nodeTarget will cause Instantiate to run again, even if it's not in that script file.
Actually, what is the edgePrefab object? $$anonymous$$y guess is that it has this script attached to it, so the code is only running once, but on each object as it is instantiated.
Answer by Dave-Carlile · Oct 23, 2013 at 05:59 PM
On line 32...
nodeSource = null;
nodeSource = null;
Shouldn't the second line be nodeTarget? And you'd need to set firstUpdate
to true
instead of false
after that to prevent setting the node variables again.
yes sorry. this is a typo. I corrected it and it has the same behavior
Your answer
![](https://koobas.hobune.stream/wayback/20220613120516im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Using multiple yields in a Coroutine 1 Answer
Distribute terrain in zones 3 Answers
Multiple Cars not working 1 Answer
Refrencing Instantiated Object 1 Answer