Войти
UnityФорумОбщее

Помогите со спавном объектов

#0
11:02, 5 апр 2017

У меня есть скрипт. Там новый объект спавнится каждую 0,5 секунду. Но часто происходит так, что один объект появляется на другом. Как сделать, чтобы они не спавнились друг на друге?


public float timer = 0.5f;
public int lives = 3;
public int record;

public GameObject ObjectG;
public GameObject ObjectR;
public GameObject ObjectB;

void Update()
{
int RandNum = Random.Range (1, 100);

float addXPosG = Random.Range(-2.16f, 2.16f);
float addYPosG = Random.Range(-4.25f, 4.25f);

float addXPosR = Random.Range(-2.16f, 2.16f);
float addYPosR = Random.Range(-4.25f, 4.25f);

float addXPosB = Random.Range(-2.16f, 2.16f);
float addYPosB = Random.Range(-4.25f, 4.25f);

Vector3 spawnPosG = transform.position + new Vector3 (addXPosG, addYPosG, 1);
Vector3 spawnPosR = transform.position + new Vector3 (addXPosR, addYPosR, 1);
Vector3 spawnPosB = transform.position + new Vector3 (addXPosB, addYPosB, 1);

timer -= Time.deltaTime;

if (timer <= 0) {


if (RandNum <= 70) {
GameObject ObG = Instantiate (ObjectG, spawnPosG, Quaternion.identity);
Destroy (ObG, 1.5f);

}

if (RandNum > 70 && RandNum < 99) {
GameObject ObR = Instantiate (ObjectR, spawnPosR, Quaternion.identity);
if (ObjectR != null) {
Destroy (ObR, 1.5f);

}
}

if (RandNum >= 99) {
GameObject ObB = Instantiate (ObjectB, spawnPosB, Quaternion.identity);
if (ObjectB != null) {
Destroy (ObB, 1.5f);

}
}

timer = 0.5f;
}
}

#1
11:13, 5 апр 2017

https://docs.unity3d.com/ScriptReference/Physics.OverlapSphere.html

#2
1:27, 8 мая 2017

Ну, во первых, тебе необязательно каждый тик инициализировать все эти переменные:

int RandNum = Random.Range (1, 100);

float addXPosG = Random.Range(-2.16f, 2.16f); 
float addYPosG = Random.Range(-4.25f, 4.25f);

float addXPosR = Random.Range(-2.16f, 2.16f); 
float addYPosR = Random.Range(-4.25f, 4.25f);

float addXPosB = Random.Range(-2.16f, 2.16f); 
float addYPosB = Random.Range(-4.25f, 4.25f);

Vector3 spawnPosG = transform.position + new Vector3 (addXPosG, addYPosG, 1); 
Vector3 spawnPosR = transform.position + new Vector3 (addXPosR, addYPosR, 1); 
Vector3 spawnPosB = transform.position + new Vector3 (addXPosB, addYPosB, 1);

Все их лучше перенести под строку:

if (timer <= 0) {


Более того, уж очень однотипно все это выглядит, и надо загнать все это в отдельный метод, например так:

Vector3 GetRandomOffset (float minX, float maxX, float minY, float maxY)
{
  return new Vector3 (Random.Range(minX, maxX), Random.Range(minY, maxY), 1f);
}

Да и использовать -= time.deltaTime не самый лучший способ, но не буду пока пудрить мозги, касательно InvokeRepeating () и Карутинов, если захочешь - погугли, очень полезная штука.
Если перевести на человеческий, то:

public float timer = 0.5f; 
public int lives = 3; 
public int record;

public float radius;

public GameObject ObjectG; 
public GameObject ObjectR; 
public GameObject ObjectB;

void Update() 
{
  timer -= Time.deltaTime;

  if (timer <= 0) {
    GameObject targetPrefab;

    if (RandNum <= 70) { 
      targetPrefab = ObjectG;
    }else if (RandNum > 70 && RandNum < 99) {
      targetPrefab = ObjectR;
    }else { 
      targetPrefab = ObjectB;
    }
    Vector3 targetPosition = transform.position+GetRandomOffset (-2.16f, 2.16f, -4.25f, 4.25f);
    //Проверка на пересечения!!!!!!!
    while (Physics.OverlapSphere(targetPosition, radius).Length > 0)
      targetPosition = transform.position+GetRandomOffset (-2.16f, 2.16f, -4.25f, 4.25f);

    //Поясняю, мы перебираем случайные значения до того момента, пока не найдем свободного места, как только нашли - идем дальше
    //То есть, мы получаем количество коллайдеров внутри сферы с заданным радиусом и спавним, только если количество коллайдеров становится равным 0!
    //не самое гениальное решение, но оно будет работать

    GameObject gO = Instantiate (targetPrefab, targetPosition, Quaternion.identity);
    Destroy (gO, 1.5f);
    timer = 0.5f;
  } 
}

Vector3 GetRandomOffset (float minX, float maxX, float minY, float maxY)
{
  return new Vector3 (Random.Range(minX, maxX), Random.Range(minY, maxY), 1f);
}
UnityФорумОбщее

Тема в архиве.