Spawning enemies randomly without collisions

So i found this script where you send an invisable object to detect if there is a collision and if their isnt then you spawn your enemy.

the first is for the invisable object

// -- TeleportTester.js -- 
var allClear = true;

function OnCollisionEnter() {
    allClear = false;
}

The second one is the actual enemy

var testerPrefab : TeleportTester;  // drag tester prefab into this var
var wizardPrefab : Enemy;    

function TeleportTester( targetPos : Vector3 ) : Enemy {

    // test whether the target area is all clear:
    var tester = Instantiate( testerPrefab, targetPos, Quaternion.identity );
   yield new WaitForFixedUpdate();

    if (tester.allClear) {
        // all clear for wizard to appear!
        var wizard = Instantiate( wizardPrefab, targetPos, Quaternion.identity );
    return wizard ;
    }
    else {
        // maybe the calling function should pick a new spot and try again
       return null;
   }
}

whenever I try this though I get an error that tells me Enemy is not a known type in the enemy script at the teleporttester function. can anyone help?

As The_r0nin said, Enemy is not a type/class within the context of your project. The solution they provided is not entirely correct however because "Just change these to GameObject" doesn't quite capture what I assume they mean to describe.

As was said, in order for Enemy to be a type/class, you must define it as such either by declaring class Enemy or by naming one of your javascripts to be Enemy.js (which Unity will implicitly declare a class for). Enemy would be a `MonoBehaviour`.

The problem not addressed entirely is that your function `TeleportTester` is trying to return something of type Enemy, but you do not return objects of type Enemy. You try to return the value from `Instantiate` or a `null`. `Object.Instantiate` returns an `Object` and if your function tries to return the result as type `Enemy`, it will try to cast the `Object` to the type `Enemy`. `Instantiate` will not really let you Instantiate a `MonoBehaviour` as a `MonoBehaviour` must be attached to something. Also, you cannot set a reference to a script instance in the editor through your variable wizardPrefab.

Additionally, you have a type `TeleportTester` and a function `TeleportTester`. This may still compile, but is a bad idea. You should consider renaming the function to `TeleportTest`.

The simple fact of the matter is that what you are trying to do is very wrong and it would seem you misunderstand the concept of types and how prefabs work, so I will summarize the key points you seem to be missing:

  • Prefabs are pre-built `GameObject`s with already defined attributes. You set them up in the editor.
  • Just because you named a prefab "Enemy", it is still a `GameObject`, just one with the name "Enemy".
  • When you `Instantiate`, it will create the `Object` you pass it, if it is possible. Generally you will `Instantiate` a `GameObject` or some `Component` of a `GameObject`. `Instantiate` will still instantiate the `GameObject`, but if you passed it a given `Component`, it will get the `Component` from the `GameObject` it just instantiated and return that.
  • If you want to `Instantiate` a prefab with a script attached, you merely need to attach the script to the prefab and the instantiated instance of the prefab will have it too.
  • If you want to add a script to something, you would need an instance of the `GameObject` or one of it's attached `Component`s and would then call `instanceName.AddComponent(scriptType);`
  • If you want a reference to an instance of a script attached to something, you would need an instance of the `GameObject` or one of its attached `Component`s and would then call `instanceName.GetComponent(scriptType);`

That said, what The_r0nin likely meant was something like:

  • change `wizardPrefab` to type `GameObject`
  • if you want to return an Enemy script attached to the `wizardPrefab` you just instantiated, you would `return wizard.GetComponent(Enemy);` otherwise, change your function to return type `GameObject` and wherever you call it, adjust your code appropriately.

"Enemy" is a class name (you can see this because your prefab is declared as that type: var wizardPrefab : Enemy;). This means that you need a script on your enemy items named "Enemy" or a separate class you declare in a script called "Enemy". Just like "GameObject" or "int" are types, "Enemy" is a typr that you haven't defined in your code, so it's telling you that you can't declare or return variables of type "Enemy". Just change these to GameObject and see if your scripts work...

So i've got a functional script now that will spawn enemies randomly within whatever range. It still needs some tweaking but it works.

var allClear = true;
var teleporter= gameObject;
var range= 10;
var player= transform;
var wait = 5;

InvokeRepeating("ZombieSpawn",1,5);

function ZombieSpawn() {
var i= Random.value* range;
var j= Random.value* range;
var k=Random.value* range;
var pos=Vector3(i,j,k)+player.position;

Instantiate (teleporter, pos, Quaternion.identity); 

}
function OnCollisionEnter() {
    allClear = false;
}