Hello noob learning code alert. Im trying to piece together an attempt to randomly generate some objects (p) inside a 100x100 pixel space, over time. If anyone can help it would be hugely appreciated. Ive started with the concept of creating an array of the three different prefabs i want to spawn. I then fill the array in the unity UI with my prefabs. Then im trying to create a little function that Instantiates one of the objects from the array, at a random position within a 100x100 pixel area. Top Down Ortho, so no Y, but at a random time too : / Code (csharp): var pArray : GameObject[]; var p : GameObject = pArray[Random.Range(0, pArray.length)]; function Spawn(){ Instantiate (p, Vector3(Random.Range(0,100), 0, Random.Range(0,100)), Quaternion.identity);; Invoke("Spawn", Random.Range(0.0, 1.0)); } I get an error saying: NullReferenceException: Object reference not set to an instance of an object UnityScript.Lang.Extensions.get_length (System.Array a) spawn..ctor () (at Assets/Scripts/spawn.js:3) which just confuses me... it looks like it doesnt think i have any objects in my array - which i do? sorry if this is rookie crap, but im coming from a artist bg, and have never really used arrays and random before - learning. thanks in advance for your time AA
not only do you not have objects in your array, you may not even have an array. arrays are references, so: Code (csharp): //fail //"object reference not set to an instance of an object" var foo : int[]; foo[0] = 1; //win var foo : int[] = new int[1]; foo[0] = 1; There are other reasons you may get this error. You'd have to show us how you are populating GameObject[] to avoid getting more guesses
thanks for the reply harmless, just trying to get my head around it. I am creating the pArray[] in my script, and then literally in the Unity UI, in the inspector, it gives me a P Array with the number 0. I change it to 3 and link the three empty slots to basic cube prefabs in my project. Is this the wrong way to setup an array? i see you are defining your array items in your script? should i be only doing it that way? im trying a few things, so thanks for the help, any more info to help me think about it is always appreciated! thanks AA
You need to put the Random call in the function itself, and reference the array element. Also I'm not sure that making Spawn a recursive function is a good idea: Code (csharp): var pArray : GameObject[]; function Start () { Invoke("Spawn", Random.Range(0.0, 1.0)); } function Spawn(){ Instantiate (pArray[Random.Range(0, pArray.Length)], Vector3(Random.Range(0,100), 0, Random.Range(0,100)), Quaternion.identity); } If you want Spawn to be called continuously, you can put it in a loop. --Eric
thanks so much people for your help on this I had a bash at wrangling my little test code tonight and got this working: Code (csharp): var pArray : GameObject[]; function Start () { InvokeRepeating("Spawn", 3, Random.Range(0.0, 3.0)); } function Spawn(){ Instantiate (pArray[Random.Range(0, pArray.Length)], Vector3(Random.Range(-5,5), 0, Random.Range(-5,5)), Quaternion.identity); } so it spawns the little prefabs in a random position at random intervals within an area. 2 follow up topics 1. the area itself. I have tried playing around with units, but i was wondering if anyone knew if there was a standard way to define an area by boundaries of an ortho camera? or if there is a formula for screen pixels to Unity units, through the camera? 2. xcuse my ignorance, but why is calling the "spawn" function continuously a bad thing? is it memory? or buggy? thanks again for the (as usual) excellent forum tips, youve made this noob's evening AA
1. Camera.ScreenToWorldPoint The docs are your friend 2. Calling a function repeatedly isn't an issue, if it is the right thing to do. Without getting into detail, calling a function recursively with Invoke is unclear. Will it work as you intend? Are there any side effects? Does it work with CancelInvoke? There are only disadvantages and unknowns. InvokeRepeating provides the functionality.
The only problem with this is that Random.Range is called once when the function is called, so the delay will always be the same during any given run, but will change the next time you run the game. I suspect you have something more like this in mind: Code (csharp): while (true) { Invoke("Spawn", 3); yield WaitForSeconds(Random.Range(0.0, 3.0)); } That way the delay is random between every Invoke. --Eric
thanks again for the response! ScreenToWorldPoint looks like what i was searching for - i use the docs often, but sometimes its hard to find something you know of, but is named differently to how you're used to in some packages always good for me to rtfm though ... AA