• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by DanielJankovskij · Jan 03 at 10:57 PM · 3dspawnprefabsspawningspawning problems

How do I make enemies not spawn in the same position?

So I am making a 3D game which has a perspective of a 2D game and I made an enemy spawner game object and gave it this script. And here's the problem, sometimes enemies randomly spawn in the same position. How do I prevent this from happening? Thanks for your support!

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class SpawnEnemy : MonoBehaviour
 {
     public GameObject[] enemyPrefabs;
     public Vector3 spawnPos;
 
     private int enemyCount = 0;
 
     private float startDelay = 3;
     public float minValuex = -8;
     public float spaceBetweenSquares = 1f;
     private BoxCollider boxCollider;
     private int maxEnemies = 4;
 
     Vector3[] spawnedEnemiesPosition;
 
     private PlayerController playerControllerScript;
 
     // Start is called before the first frame update
     void Start()
     {
         InvokeRepeating("SpawnEnemies", startDelay, Random.Range(4f, 5f));
         playerControllerScript = GameObject.Find("Player").GetComponent<PlayerController>();
 
         for (int i = 0; i < maxEnemies; i++)
         {
             spawnedEnemiesPosition[i] = new Vector3(0, 0, 0);
         }
     }
 
     // Update is called once per frame
     void Update()
     {
 
     }
 
     Vector3 RandomSpawnPosition()
     {
         
         float spawnPosX = minValuex + (RandomSquareIndex() * spaceBetweenSquares);
         float spawnPosY = 0;
 
         Vector3 spawnPosition = new Vector3(spawnPosX, spawnPosY, -2);
 
         return spawnPosition;
     }
 
     // Generates random square index from 0 to 3, which determines which square the target will appear in
     int RandomSquareIndex()
     {
         return Random.Range(-2, 0);
     }
 
     void SpawnEnemies()
     {
         if (playerControllerScript.gameOver == false && enemyCount <= 4)
         {
             int enemyIndex = Random.Range(0, enemyPrefabs.Length);
             spawnPos = RandomSpawnPosition();
 
             //bool CheckBox(Vector3 center = new  Vector3(0.009f, 1.26f, -0.033f), Vector3 halfExtents, Quaternion orientation = Quaternion.identity, int layermask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);
 
             Instantiate(enemyPrefabs[enemyIndex], spawnPos, enemyPrefabs[enemyIndex].transform.rotation);
 
             enemyCount++;
         }
     }
 }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by Zaeran · Jan 04 at 12:29 AM

Easiest way would be to add the position of each enemy to a list when they spawn.

Before an enemy spawns, check each position in the list, and if the proposed spawn position is too close to a position in the list, change the proposed spawn position.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image DanielJankovskij · Jan 04 at 10:27 PM 0
Share

Thanks a lot for help!

avatar image
2

Answer by ddooms · Jan 04 at 01:17 AM

I second Zaeran's answer, but I'd like to add to it.

Add a List and then add to that anytime you have a new enemy (remove from it when you remove that enemy). Then, when you're checking for their distances, just use a sample position to test if there is an enemy at the chosen place for the enemy's next spawn - Loop through all current enemies and test their distances :

 if((enemy.position - newSpawnPosition).sqrMagnitude > (some squared value)) continue; else { GenerateNewPosition() }

GenerateNewPosition is just a dummy function here, but it would just call the spawn function again to get a new position to test. You should have some fail safe so you don't have an endless loop. Perhaps if it fails after 100 times it just stops, because maybe there are too many enemies or something.

I wouldn't use InvokeRepeating because it's difficult to control. Try to use controllable loops that you can break anytime. While loops, or maybe forloops. You could also use the Update function to spawn enemies every few seconds.

 float nextSpawn, spawnRate = 1;
 
 void Update {
 if(Time.time > nextSpawn){
 nextSpawn = Time.time + spawnRate;
 SpawnEnemy();
 }
 }

This would spawn an enemy every 1 second. You can utilize Time.time to control the rate of things easily -- just have a value that keeps the time, and add the amount of time you want to wait to it.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image DanielJankovskij · Jan 04 at 10:26 PM 0
Share

Thanks a lot! But i have a question, what do you mean by saying "some squared value" in the code?

 if((enemy.position - newSpawnPosition).sqrMagnitude > (some squared value))



avatar image ddooms DanielJankovskij · Jan 05 at 04:57 AM 0
Share

I'm using a distance formula instead of the standard "Vector3.Distance(a,b)" It works with squares, rather than division. In order to get an accurate reading without negatives, you square it (multiply it by itself). It's the same as (enemy.position - newSpawnPosition) * (enemy.position - newSpawnPosition).

So the "some squared value" is a value that represents the distance between your enemy and the spawn point you're checking. We have to square it, since we are also squaring the distance formula.

So if we have a distance of 4, it was squared. That means if we want to CHECK for a distance of 3, we have to take 3 to the power of 2 (3 * 3) in order to keep it consistent between the two values.

 float dist = 0;
 float minimumDistance = 5;
 
 dist = (enemy.position - newSpawnPosition).sqrMagnitude;
 
 if(dist > (minimumDistance * minimumDistance)){
  // spawn
 }

The reason I do this is because Vector3.Distance is ever so slightly less efficient than doing the formula yourself. Sorry to complicate things lol.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

146 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

[Help] How Do I Randomly Spawn Game Objects On Specific Coordinates? 3 Answers

How to spawn all humans at once and activate then with time? 1 Answer

Navmesh problem with SpawnSystem 0 Answers

Scripts are being disabled during game play 0 Answers

How to spawn random buildings 5 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges