Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • 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, 2021 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, 2021 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, 2021 at 10:27 PM 0
Share

Thanks a lot for help!

avatar image
2

Answer by ddooms · Jan 04, 2021 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, 2021 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).sqr$$anonymous$$agnitude > (some squared value))



avatar image ddooms DanielJankovskij · Jan 05, 2021 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 $$anonymous$$imumDistance = 5;
 
 dist = (enemy.position - newSpawnPosition).sqr$$anonymous$$agnitude;
 
 if(dist > ($$anonymous$$imumDistance * $$anonymous$$imumDistance)){
  // 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.

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

Pickup & Drop Objects + Spawn items HELP 0 Answers

Different way to spawn prefabs 0 Answers

Spawning help 1 Answer

Navmesh problem with SpawnSystem 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges