Random Instantiate of Zombies

I’ve added this script to the main camera of the FPS controller but it doesn’t work and it doesn’t give me any error. I want just to instantiate randomly up to 50 Zombies near my position (target). I assign to target the FPS Controller and to zombie the Zombie prefab but it doesn’t work.

static var horde = 0.0;
var timeToWait = 0.0;
var minTime = 2.0;
var maxTime = 15.0;
var posMin = 50.0;
var posMax = 120.0;
var target : Transform;
var zombie : Transform;
var pos : Transform;

function Start () {
	if (target == null && GameObject.FindWithTag("Player"))
		target = GameObject.FindWithTag("Player").transform;
	hordeLoop();
}

function hordeLoop() {
	while(true) {
		if(horde<50) {
			timeToWait=Random.Range(minTime,maxTime);
			Debug.Log(timeToWait);
			yield WaitForSeconds(timeToWait);
			pos.position.y=target.position.y;
			pos.position.x=target.position.x+Random.Range(posMin,posMax);
			pos.position.z=target.position.z+Random.Range(posMin,posMax);
			Instantiate(zombie,pos.position,target.rotation);
			horde=horde+1;
		}
	}
}

SOLUTION: Thank you to Aldonaletto for the solution and to all of yours for help. This is my final script and it works. It creates randomly around me up to 50 zombies and each time I kills one it regenerates me other zombies.

static var horde = 0.0;
var timeToWait = 0.0;
var minTime = 1.0;
var maxTime = 3.0;
var posMin = 3.0;
var posMax = 5.0;
var target : Transform;
var zombie : Transform;
var pos : Vector3;

function Start () {
	if (target == null && GameObject.FindWithTag("Player"))
		target = GameObject.FindWithTag("Player").transform;
	hordeLoop();
}

function hordeLoop() {
	while(true) {
		if(horde<50) {
			timeToWait=Random.Range(minTime,maxTime);
			yield WaitForSeconds(timeToWait);
			// create a forward vector with length between posMin and posMax
			pos = Vector3.forward * Random.Range(posMin, posMax);
    		// rotate it a random angle in the horizontal plane
    		pos = Quaternion.Euler(0, Random.Range(0, 360), 0) * pos;
    		pos.z = target.position.z + pos.z;
    		pos.x = target.position.x + pos.x;
    		// set y to a few meters above the player to avoid falling through the ground
    		pos.y = target.position.y + 1;
			Instantiate(zombie,pos,target.rotation);
			horde=horde+1;
		}
		else {
		yield;
		}
	}
}

I think calling that while(true) from your Start() method is hanging Unity, since it never exits that loop. Your yield is only called while the horde is being filled; after that it’s just an infinite loop.

Perhaps what you meant is to combine the while & the if statements in that function, ex:

  while(horde<50)

Unless you’re doing that infinite loop because the value of horde gets depleted when the monsters are killed and you want them to regenerate? If so I think just moving the yield statement outside of the if(horde<50) is what you want. You just want to avoid Unity hanging on while(true) { } without yielding.

EDITED: You never initialize pos, only declared it as a Transform. That’s why you’re getting that error message. Also I’m not sure you can just use a bare Transform like that, not attached to a GameObject. Instead maybe you want pos to be a Vector3, ex:

    static var horde = 0.0;
    var timeToWait = 0.0;
    var minTime = 2.0;
    var maxTime = 15.0;
    var posMin = 50.0;
    var posMax = 120.0;
    var target : Transform;
    var zombie : Transform;
    var pos : Vector3;
    
    function Start () {
        if (target == null && GameObject.FindWithTag("Player"))
           target = GameObject.FindWithTag("Player").transform;
        hordeLoop();
    }
    
    function hordeLoop() {
        while(true) {
           if(horde<50) {
             timeToWait=Random.Range(minTime,maxTime);
             Debug.Log(timeToWait);
             yield WaitForSeconds(timeToWait);
             pos.y=target.position.y;
             pos.x=target.position.x+Random.Range(posMin,posMax);
             pos.z=target.position.z+Random.Range(posMin,posMax);
             Instantiate(zombie,pos,target.rotation);
             horde=horde+1;
           }
        }
    }

yes I want to regenerate zombies…I’ve moved the yield statement outside of the if but it doesn’t generate anything…and the Zombie prefab works well, I’d tried to put it on the scene and when I press Play the zombie become to follow me…
The problem seems Instantiate…it doesn’t seem to work…
The Console tells me this “UnassignedReferenceException: The variable pos of ‘Horde’ has not been assigned.”…but in the script I assign the target.position with some modify…

This pos variable should be a Vector3 - if declared as a Transform, you must drag some object to the variable, or Unity will show that error. And @Jake 4 is right: when 50 zombies are crawling around, Unity will hang because the yield will never be reached. You can place an yield instruction in the else clause to fix this:

static var horde = 0.0;
var timeToWait = 0.0;
var minTime = 2.0;
var maxTime = 15.0;
var posMin = 50.0;
var posMax = 120.0;
var target : Transform;
var zombie : Transform;
var pos : Vector3; // pos must be a Vector3

function Start () {
    if (target == null && GameObject.FindWithTag("Player"))
       target = GameObject.FindWithTag("Player").transform;
    hordeLoop();
}

function hordeLoop() {
    while(true) {
       if(horde<50) {
         timeToWait=Random.Range(minTime,maxTime);
         Debug.Log(timeToWait);
         yield WaitForSeconds(timeToWait);
         // see note below about pos generation
         pos.y=target.position.y;
         pos.x=target.position.x+Random.Range(posMin,posMax);
         pos.z=target.position.z+Random.Range(posMin,posMax);
         Instantiate(zombie,pos,target.rotation);
         horde=horde+1;
       }
       else {
         yield; // free Unity if there are 50 zombies
       }
    }
}

NOTE: The zombies will only be created at positive offsets in x and z from the player. To fix this, you could change the pos generation to something like:

// create a forward vector with length between posMin and posMax
pos = Vector3.forward * Random.Range(posMin, posMax);
// rotate it a random angle in the horizontal plane
pos = Quaternion.Euler(0, Random.Range(0, 360), 0) * pos;
// set y to a few meters above the player to avoid falling through the ground
pos.y = target.position.y + 3;
Instantiate(zombie, pos, target.rotation); // instantiate the monster
...

Can You Please Give the Script in C#