Random.Range Set up:

What I have going on is, my player is placed int he center, and the enemy comes from all angles coming towards the center.

I have this code on the enemy to set the starting position and position its placed after being killed.

using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour {
	
	private float x, y, z;
	
	void Start () 
	{
	    StartPosition();
	}
	public void SetPositionAndSpeed()
	{
		x = Random.Range(-50, 50f);
		y = 0.0f;
		z = Random.Range(-30f, 30f);
		transform.position = new Vector3(x, y, z);
	}
    public void StartPosition()
    {
		x = Random.Range(-70, 70f);
		y = 0.0f;
		z = Random.Range(-50f, 50f);
		transform.position = new Vector3(x, y, z);
    }
}

The random range places it sometimes to close to the player, killing him before he can react, which isn’t good.

Is there a way to clamp the spwan position of the AI enemy a certain range away from the center but a constant distance from the center?

I have tried many different things, but nothing is working.

you can use the Player;s transform.position as an offset to spawn your monsters. You can do this thing in numerous ways, you add some Random.Range to the transform.position of the player, and make sure your random range is over a certain value (distance).

But the easiest way i think it’ll be to check if the Vector3.Distance(player.transform, yourNewlyCreatedVectorWhereYouWantToSpawnEnemy) > value, if it is true, spawn, else do the random again (this is something i do not recommend doing tho).

How would I incorporate the players transform with the x, z in the above code?

I appreciate the help…

I would do something like this:

Considering your player placed at (0,0,0)

using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour {
	
	private float x, y, z;
	private float _minDistanceFromPlayer;

	void Start () 
	{
	    StartPosition();
	}
	public void SetPositionAndSpeed()
	{
                if(Random.value > 0.5){
		   x = Random.Range(_minDistanceFromPlayer, 50f);
                }
                else{
		   x = Random.Range(-_minDistanceFromPlayer, -50f);
                }
                
                if(Random.value > 0.5){
		   z = Random.Range(_minDistanceFromPlayer, 30f);
                }
                else{
		   z = Random.Range(-_minDistanceFromPlayer, -30f);
                }

		y = 0.0f;
		transform.position = new Vector3(x, y, z);
	}
}

I excluded the StartPosition() function because I’m not sure which one you used for your enemies, so consider the function above as the function to place your enemies.

That seems like its what I need.

What is the if(Random.value > 0.5) mean??

That didn’t work. The player is at 0,0,0.

I still get AI spawning 10 meters away.

I placed this on the Enemy Prefab (a red Sphere)

using UnityEngine;
using System.Collections;

public class SpawnEnemy : MonoBehaviour {
	private Vector3 playerPosition;
	public float distanceFromPlayer;
	public float randomLimit;
	
	
	
	void Awake(){
		//we set the reference of the position of the player here
		playerPosition = GameObject.Find("Player").transform.position;
		//we set the distanceFromPlayer value here (the min distance from the player the enemy must have)
		distanceFromPlayer = 15;
		if(randomLimit == 0){
			randomLimit = 50;
		}
	}
	
	void Start () {
	    StartPosition();
	}
	
	private void StartPosition(){
		//generate the random position for Enemy
		float randomPosX = Random.Range(-randomLimit, randomLimit);
		float randomPosZ = Random.Range(-randomLimit, randomLimit);
		
		//we haveto make sure the randoms are not = 0
		if(randomPosX == 0){
			randomPosX = 1;
		}
		if(randomPosZ == 0){
			randomPosZ = 1;
		}
		
		//we do it like this because the random can have positive or negative values, and we need to make sure our distanceFromPlayer is set correctly. (randomPosX/Mathf.Abs(randomPosX) = 1 or -1)
		transform.position = new Vector3(playerPosition.x + distanceFromPlayer * randomPosX/Mathf.Abs(randomPosX) + randomPosX, 1 , playerPosition.z + distanceFromPlayer * randomPosZ/Mathf.Abs(randomPosZ) + randomPosZ);
	}
}

and this one on an Empty GameObject (Spawner Object)

using UnityEngine;
using System.Collections;

public class SpawnScript : MonoBehaviour {
	public GameObject EnemyPrefab;
	public int NumberOfEnemies;
	
	// Use this for initialization
	void Awake () {
		if(!EnemyPrefab){
			print("set the prefab of the enemy!");
		}
		if(NumberOfEnemies == 0){
			NumberOfEnemies = 10;
		}	
	}
	
	// Update is called once per frame
	void Start () {
		while(NumberOfEnemies > 0){
			Instantiate(EnemyPrefab);
			NumberOfEnemies --;
		}		
	}
}

is something i made up just now, it works for me, i guess it will need some tweaking for you, but i hope you will be able to do that. Have fun!

Using beneton’s code, with few changes…

using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour {
	
	private float x, y, z;
	private float _minDistanceFromPlayer = 15;

	void Start () 
	{
	    StartPosition();
	}
	public void SetPositionAndSpeed()
	{
                if(Random.value > 0.5){
		   x = Random.Range(_minDistanceFromPlayer, 50f);
                }
                else{
		   x = Random.Range(-50f, -_minDistanceFromPlayer);
                }
                
                if(Random.value > 0.5){
		   z = Random.Range(_minDistanceFromPlayer, 30f);
                }
                else{
		   z = Random.Range(-30f, -_minDistanceFromPlayer);
                }

		y = 0.0f;
		transform.position = new Vector3(x, y, z);
	}
}

not sure if Random.Range(x, y) must have x<y, but you need to set _minDistanceFromPlayer first, i did it here, it should work now, i made it 15 unity units.

Thanks for correcting me ar0nax, I wrote the code without testing :slight_smile:

np mate.

ar0nax-

That fix I think made it work, I will have to keep restarting it to see if the enemies spawn at that distance a few hundred times to make sure.

I appreciate the help guys.

It does work. Although now the enemies only come from the 4 corners and not inbetween, so it is kind of predictable.

well then, the best thing you can do is generate some random locations, then check to see if the distance from that location to the player is greater than minimum distance, if so spawn, else… try some other random location.

PS: use a range for randoms, add them to the player.transform.position, then see if the distance is greater than…

What would I use just empty gameobjects and have them instantiate from them??

hey All_American, what are the corners in your case?

because with that code, you should get enemies spawning inside a donut.

try changing this line:

private float _minDistanceFromPlayer = 15;

for this:

private float _minDistanceFromPlayer = 15f;

because in C# you must put that f to define a float.
in fact use that for the:

if(Random.value > 0.5f){

}

And this code above means: If a random value between 0.0f and 1.0f if greater that 0.5f (about half the times)
So you can randomize positive and negative positions.

there is a problem with your Range

The four corners of the screen- they only spawn from the top and bottom corners of the screen, On an angle coming towards the center.

Yeah I inclused the f’s where they needed to be.

I think that code is taking those two numbers and plotting them out and spawning them from there every time.

That is very strange…
I don’t think that your Radom.Range is generating always the same 4 positions, so check it out. Put:

Debug.Log(x + "," + y + "," + z);

before:

transform.position = new Vector3(x, y, z);

Let’s see what results we get.

I got

32.80412,0,-30
32.77756,0,-30
-34.97808,0,-30
33.68573,0,30

Maybe I should try this

public void SetPositionAndSpeed()
	{
		x = Random.Range(_minDistanceFromPlayer,-50, 50f);
		y = 0.0f;
		z = Random.Range(_minDistanceFromPlayer, -30f, 30f);
		transform.position = new Vector3(x, y, z);
	}

What do you think. Because with this- they were spawning all over the place, so would this make them do that, but the minDistance away??

these results you posted show me that the code is working with X position, but it’s very strange with Z. a Random.Range should very rarely return the maximum or minimum values… and in your results we have it returning every time for Z. Are you sure that’s not a typo in your code?