- Home /
Trying to write enemy spawn in JS.
I'm very new to programming, so far this is what I have;
var enemyType : Transform;
var enemySocket : Transform;
function Update ()
{
if (Time.time >= 5)
{
Spawn ();
}
}
function Spawn ()
{
InvokeRepeating("enemyType", 5, 5);
Instantiate(enemyType, enemySocket.position, enemySocket.rotation);
CancelInvoke ();
}
Obviously, I'm missing something here, as it spawns a continuous stream of enemys and will not stop. I'm trying to get this code to a point where it can start and stop after various time intervals. (ex: spawn 4 enemies after 1 minutes, then spawn another 4 30 seconds after that and so on and so forth)
any help would be appreciated
Answer by SinisterRainbow · Jul 05, 2013 at 04:07 PM
well, Hello World to you. :) You are probably spawning an incredible amount by the looks of it =D.. In Update() you are calling Spawn() every frame at 5 seconds and every frame after that. Then inside spawn you are making all those repeat every 5 seconds.. If you mean to spawn once every 5 seconds, you need to have a variable to record how much time has passed, then reset it when you spawn your enemy. For example:
Note, i never use javascript, so not sure this will work directly, i'll try to guess it tho.. There are many better ways to do this, but using your code and experience, you can do this:
var spawnTime : float = 0.0f;
var turnOffUpdate1 : bool = false;
var maxTime : float = 500.0f;
function Update() {
if (spawnTime >= 30.0f && !turnOffUpdate1) {
Spawn();
turnOffUpdate1 = true;
}
if (spawnTime >= 300) { //i.e. reached 4 minutes and haven't done it yet
Spawn();
turnOffUpdate1 = false;
spawnTime = 0.0f;
}
spawnTime += Time.deltaTime;
}
function Spawn() {
//you can keep it like you have i think, but why invokerepeating then cancel? Just instantiate an enemy once here, forget the invoke repeating calls
}
So you see, it has to record how much time has passed, then only execute once it has. (after 30 seconds the first time).. the next one will spawn at around 4 minutes, then it will reset, and spawn after 30 seconds then 4 minutes again, rinse repeat. this is just one (not very good way) to do it. you likely will want a dictionary or array or list or something that will know spawn times later, but i don't know how new you are, you hopefully should be able to grasp this.
Answer by Rick74 · Jul 05, 2013 at 08:40 PM
Thanks so much for the help! I was able to plug this in an get it running, thank you so much! Could you possibly explain what && !turnOffUpdate is doing? I've figured out the rest of what you have done but I am uncertain about that line.
Thanks again!
np (note, you may want to make 'comments' ins$$anonymous$$d of questions in the future).
The && means "and also" the "!" means not. So, when update starts, it checks to see when spawnTime has reached 30 seconds && (and also) if turnOffUpdate1 is false (aka, !true "not true"). If i put just "&& turnOffUpdate1" i'm asking to see if turnOffUpdate1 is true. by putting "!" in front of it i'm asking to see if it is "not true" or "false".
Since it starts off as "false" !false = true so it will be true until we reach 30 seconds, that's when spawnTime >= 30.0f (so that becomes true), and our !turnOffUpdate1 is true so we execute the Spawn().. But after we execute, we want to now turn it OFF right? We only want to spawn one time. So we set turnOffUpdate1=true.. and !true means false, so this if statement won't execute again until we reset turnOffUpdate1..
The variable 'turnoffupdate1' is a bad choice of words perhaps, just know booleans are often used as switches. For example, plugging in a stove to an outlet is like a switch. if it's unplugged, no matter what you do to the dials on the stove, nothing happens. But as soon as you plug it in, the dials can do things.
Thanks again for the indepth explanation. I'm still confused as to what part of your code is telling Spawn () to only spawn 1 enemy?
Whenever I try to tinker with this code and let's say I want to add a third spawn time inbetween, it always just coughs out a s$$anonymous$$dy flow of enemies until that "spawn" window is up and your current code takes over.
(curious why CancelInvoke ();) isn't stopping the Spawn function.
You mentioned that turnOffUpdate true/false toggle only allows spawn to run once, but when I watch the code run, on the first if statement, it checks to see if it's off, runs spawn, then turns it on.
It's on until the next if statement, run's spawn, then turns it off, as well as resets timer.
so couldn't I theoretically just add another if statement for time check and then run spawn?;
if (spawnTime >= 45.0) { Spawn(); }
However, every different way I try this by getting the code to execute spawn, I'm back to an endless flow of enemies being generated.
thanks for your patience, i've only just started scripting a few weeks ago.
Yah, if you are only a couple weeks in you are nowhere near learning all the basics of program$$anonymous$$g. Such as loops, boolean types, floats, if statement logic.. There shoudl be great tuts online these days will make your life easier..
I'll try to explain it conceptually, as i'm not sure where you are misunderstanding. (also, where are you adding the 3rd spawn time? Post what you try and I will explain why that doesn't work)
Remember, in the Update() function, that function is called 1 time every frame. If your game is running at 60 frames per second, that's 60 times a second. SO if you just put
if (spawnTime >= 40.0) { Spawn(): }
Then every frame after you put this will spawn an enemy.
spawnTime = 39.9 // no spawn
spawnTime = 40.0 // Spawn!
spawnTime = 40.1 // Spawn!
..etc.
$$anonymous$$y boolean (flag it's sometimes called), can be either true or false. if you write this:
var bFlag : boolean = false;
if (bFlag) {
Debug.Log("Hi Rick");
}
it will never execute. since the value stored in bFlag has been set to 'false' and we never set it to true.
on the other hand if you did this:
var bFlag : boolean = false;
if (!bFlag) {
Debug.Log("Hi Rick for real this time");
}
it will print every time. In this case we are checking to see if it's not (!) true. This is a shortcut way of writing things. You can make it more explicit if it conceptually helps to write it this way:
var bFlag : boolean = false;
if (bFlag == true) { //<-- you can also write (bFlag != false)
Debug.Log("you won't see me");
}
if (bFlag != true) { //<-- you can also write (bFlag == false)
Debug.Log("You will see me everytime");
}
var spawnTime : float = 0.0; // records the time of delta time + 1
var turnOffUpdate : boolean = false; // true/false toggle set to default false
var maxTime : float = 500.0; // var for maxTime set to 500? this is never called is it?
var enemyType : Transform; //Object slot to attach my enemyPrefab which has a seperate behaviour script
var enemySocket : Transform; //Object slot to attach an empty game object used just for coordinates for Spawn
function Update () //constantly runs based on fps
{ if (spawnTime >= 10.0 && !turnOffUpdate) //if spawn time is greater than or equal to 10 and also var turnOffUpdate = false then
{ Spawn(); //run spawn function
turnOffUpdate = true; //toggle turnOffUpdate to true (stops if function)
} // if (spawnTime >= 15.0) // { // Spawn(); // } if (spawnTime >= 20.0) //if spawn time is greater than or equal to 20 then run spawn function
{
Spawn(); //run spawn function
turnOffUpdate = false; //toggles turnOffUpdate to false (since this wasn't part of the if statement how did this stop spawn?)
spawnTime = 0.0; //resets spawnTime to zero to start the process over again
}
spawnTime += Time.deltaTime; //declaration that spawnTIme = Time.deltaTime +1
}
function Spawn () { InvokeRepeating("enemyType", 0, 0); //repeats enemytype 0 times, over 0 seconds
Instantiate(enemyType, enemySocket.position, enemySocket.rotation); //enemyType gets information about spawn position, rotation CancelInvoke (); //stops the invoke
} //this function could probably work with just the instantiate line. //just wanted a way to possibly control how many enemy's spawn in each 'wave'
Thanks again, I commented here on each line and what I 'think' they do. I also commented out the part where I tried to put in another spawn event.
You've been a huge help, I have found some great resources online and tutorials I am currently running through!
Thanks for your time!
Good stuff. (btw - there's a code button for formatting you may want to use in the future, it makes things easier to read)
To answer you questions -in the "if (spawnTime >= 20.0) it only executes once because we reset spawnTime to 0.0, so next iteration of the game loop "if (spawnTime >= 20.0)" will be false.
As for spawnTime, spawnTime += Time.detlaTime is different. Time.deltaTime is the amount of time that passed between this frame and the time it took to complete the last frame ( "game loop"). It will vary from frame to frame, but it always gives you correct time.
I think perhaps how you are envisioning the execution of the program is causing a misunderstanding? O perhaps how variable memory storage is working? Understanding what a ValueType is versus a Reference type is quite important. Usually we are assigning values, booleans/ints/floats/many others are VALUE TYPE parameters. $$anonymous$$eaning basically, it gets it's very own storage space.
SO when we set turnOffUpdate = false; it stores false the moment we set it. If it was true before, anything before it will have seen it as true. (Setting something does not retroactively affect anything previous statements in a function.) T
InvokeRepeating you don't need. We could have used it but programmed in a slightly different manner.. i just opted not to for the example. there's always many ways to do the same thing.
Everything else you seem to get. $$anonymous$$eep reading, there's TONS to learn, it will just make you better all the time.
Your answer
Follow this Question
Related Questions
JS to C# converting issues.. 1 Answer
can anyone please help with enemy wave spawn? 0 Answers
Destroy and Spawn an Enemy 1 Answer
Help have script know how many enemies are in the world 1 Answer