I checked several threads on direction’s and magnitude’s but couldn’t figure out the following:
If I have a gameobject that solely carries a circlecollider2D, how can I get the position of a random point of the colliders boundary? I know that I can set random directions with random.range and set the vectors magnitude to the colliders radius, but I don’t know how to do that properly in c#.
CircleCollider2D CC2D;
Vector3 randomPointInRadius
{
get
{
float radius = CC2D.radius;
Vector2 center = CC2D.bounds.center;
Vector2 randomDirection = new Vector2(Random.Range(-1f,1f),Random.Range(-1f,1f)).normalized;
float randomLength = Random.Range(0,radius);
return center + randomDirection * randomLength;
}
}
void Start ()
{
CC2D = GetComponent<CircleCollider2D>();
}
Here, this is a pretty straight to the point calculation: using a random direction and a random length.
Maybe you’re not familiar with getter/setter’s, “randomPointInRadius” is a Vector3 randomized every time you “get” it.
So to move an object to a random spot within the CircleCollider just do this =
( gameObject.transform.position = randomPointInRadius )
But remember that "randomPointInRadius " changes every time you use it.
I have a circular “playfield” which is surrounded by another circle (a gameobject with a circlecollider2D) which represent the outer points of the players vision. The idea is, that I use the boundary of the circlecollider2D as random positions for enemy spawning.
Thanks for the code! This was basically what I needed except, that I wanted the position to always be on the colliders boundary. I adjusted your code to get a random position on the boundary everytime the “spawn-object” is enabled:
using UnityEngine;
using System.Collections;
public class SpawnEnemies : MonoBehaviour {
public GameObject enemyPrefab;
public int amount;
public GameObject spawnLocation;
private float spawnRadius;
public float spawnWait; // time between each enemy
public bool randomSpawnLocation;
public bool symmetricSpawnLocation;
private Vector3 randomSpawnPoint;
void OnEnable()
{
spawnLocation = GameObject.Find("SpawnLocation");
SetRandomLocation();
StartCoroutine(Spawn());
}
public void SetRandomLocation()
{
Random.seed = System.Environment.TickCount;
float spawnRadius = spawnLocation.GetComponent<CircleCollider2D>().radius;
Vector2 center = spawnLocation.GetComponent<CircleCollider2D>().bounds.center;
Vector2 randomDirection = new Vector2(Random.Range(-1f, 1f), Random.Range(-1f, 1f)).normalized;
randomSpawnPoint = center + randomDirection * spawnRadius;
}
IEnumerator Spawn()
{
if (randomSpawnLocation == true)
{
for (int i = 0; i < amount; i++)
{
GameObject enemy = (GameObject)Instantiate(enemyPrefab, randomSpawnPoint, Quaternion.identity);
yield return new WaitForSeconds(spawnWait);
if (i == amount - 1)
{
Destroy(gameObject); // destroys the spawn when it finished spawning
}
}
}
if (symmetricSpawnLocation == true)
{
// logic for symmetric spawns
}
}
}
There is another related problem: While the above code allows the spawning of all enemies at the same location, I want to implement symmetric spawning in the following sense:
If the amount of enemies to spawn is for example four:
Enemy 1 spawns at a random location on the boundary of the collider e.g. at center + Vector2(0f,1f)*spawnRadius, which is the right border;
Enemy 2 spawns at the opposite direction, relative to enemy 1. Enemy 3 spawns at the top (or bottom) border, while enemy 4 spawns at the bottom (top) border. While this is easy for 4 enemies, Iam looking for a general way to allow for e.g. odd spawning numbers where e.g. 3 enemies spawn at different locations but remain the same distance to it’s nearest partner.