- Home /
RTS Building Creation System Code not working (no errors)
var Prefab : Transform;
function OnGUI () {
if (GUI.Button(Rect(10,10,50,50),"Create")){
var gos : GameObject[];
gos = GameObject.FindGameObjectsWithTag("SetObject");
for (var g in gos){
if (g.GetComponent.<ControlObject>().isBuild){
Instantiate(Prefab, g.transform.position, Quaternion.identity);
}
}
}
}
For some reason this code doesn't do what i want it to do. I don't get any errors, but it doesn't work.
Basically what I'm trying to do is: Check every GameObject within a Array to see if there is a Boolean that is set to true called: 'isBuild' and if there is, then instantiate a prefab on top of them. Alright I'm making a RTS game, what this system is, is a build mode sort of thing. I'm trying to create a building maker, one like on Age of empires for instance. So i'm able to enable build mode, then select a building such as a house and then a grid appears(this is in a whole other script) the grid is 68x68 and if i click on one of the segments of the grid it will set: 'isBuild' true for that segment and then i can hit create and it will check every GameObject(grid segments) to see if: 'isBuild' is true in any of them, thus Instantiating a house(prefab) on top of that object. But yeah that's sort of the plot here. If anyone knows why this code isn't working, then please tell me :) Thanks in advance!
You shouldn't be calling FindGameObjectsWithTag() in an update loop (OnGUI is an update loop of sorts). You should cache the value of it and then iterate over that. You might consider using a Dictionary or Hashtable in order to correlate GameObjects to their Components, because getting all game objects with a certain tag and then all of the ControlObject components potentially twice every frame (OnGUI is called twice per frame) is going to really slow things down.
uhm no i only do it once. So once i set all the buildings to have the value: 'true' i then hit the create button once. And then it will instantiate buildings on all the ones that are true. so the line:
gos = GameObject.FindGameObjectsWithTag("SetObject");
Is only called once when i hit the create button.
Answer by Kiloblargh · Jul 05, 2013 at 06:10 PM
I think you just need to say;
for (var g : GameObject in gos)
or if that doesn't work:
for (var g : int = 0; g < gos.Length; g++)
{
if (gos[g].GetComponent.<ControlObject>().isBuild){...
More than that, you need to learn how to use Debug.Log. That would quickly tell you what is happening and what's not happening and where the error is coming up.
Also- never name a variable starting with a capital letter. Just. Don't.
I'm not sure if UnityEngine has such a thing as a Prefab
class, but if it did; calling your variable Prefab
instead of prefab
would break everything. You should probably come up with a more descriptive name anyway.
Okay what do you mean by
for (var g : int = 0; g < gos.Length g++)
{
if gos[g]...
??? Please more information.
That's a plain old for loop. I missed a ";" the first time. It means check gos[0], then increment and check gos{1], then increment and check gos[2], then increment and check gos[3], keep doing that as many times as there are objects in the array, then stop.
I always do it that way, so I don't know how well for (in )
works in UnityScript; I just recall having some problems with that in the past so I don't use it. It's a shortcut to iterating manually.
Answer by Noztradamuz · Jul 05, 2013 at 07:00 PM
Try to put this code in a separate function something like
void SpawnNewObject()
{
var gos : GameObject[];
gos = GameObject.FindGameObjectsWithTag("SetObject");
for (var g in gos){
if (g.GetComponent.<ControlObject>().isBuild){
Instantiate(Prefab, g.transform.position, Quaternion.identity);
}
and call it from the OnGUI button, but this is going to create an infinite loop if you not change the isBuild variable while you instantiate them.
try this:
void SpawnNewObject()
{
var gos : GameObject[];
gos = GameObject.FindGameObjectsWithTag("SetObject");
for (var g in gos){
if (g.GetComponent<ControlObject>().isBuild){
var temp = Instantiate(Prefab, g.transform.position, Quaternion.identity);
temp.GetComponent<ControlObject>().isBuild = false;
}
and as far as i know you dont need to use a dot before GetComponent<> just use brackets. i'm not very familiar with JS hope this do the job
This will be hard to put together because this code consists of c# and Javascript and i'm only good with Javascript :P
I just take your very code and edited sorry, ignore my "void SpawnNewObject()" metod and make one of your own, just make sure to take the returning gameobject from Instantiate to a new variable and then change the isBuild parameter