Подождите, пока функция завершит выполнение, прежде чем метод start остановится - PullRequest
1 голос
/ 18 марта 2019

Привет, я работаю над игрой, которая использует случайную местность, и я хочу создавать объекты на этой местности. Для этого я создал то, что я назвал Скрипт Surface Populator Script.

Это скрипт:

public SurfaceSpawnerData spawnerData;

private float randomX;
private float randomZ;
private Renderer r;

void Start()
{
    r = GetComponent<Renderer>();
    for (int i = 0; i < spawnerData.spawnableObjects.Length; i++)
    {
        spawnerData.spawnableObjects[i].currentObjects = 0;
    }
    spawnerData.SpawnedObjects.Clear();

    SpawnObjects();
}

void Update()
{

}

void SpawnObjects()
{
    RaycastHit hit;

    for (int i = 0; i < spawnerData.spawnableObjects.Length; i++)
    {
        int currentObjects = spawnerData.spawnableObjects[i].currentObjects;
        int numOfObjects = spawnerData.spawnableObjects[i].numberOfObjects;

        if (currentObjects != numOfObjects)
        {
            if (Physics.Raycast(new Vector3(randomX, r.bounds.max.y + 5f, randomZ), -Vector3.up, out hit))
            {
                randomX = Random.Range(r.bounds.min.x, r.bounds.max.x);
                randomZ = Random.Range(r.bounds.min.z, r.bounds.max.z);

                if (hit.point.y >= spawnerData.spawnableObjects[i].spawnerStartHeight && hit.point.y <= spawnerData.spawnableObjects[i].spawnerEndHeight)
                {
                    spawnerData.SpawnedObjects.Add(Instantiate(spawnerData.spawnableObjects[i].spawnablePrefab, hit.point, Quaternion.identity));
                    spawnerData.spawnableObjects[i].currentObjects += 1;
                }
            }
        }
    }
}

Сценарий также получает свои данные из объекта сценария:

[CreateAssetMenu]
public class SurfaceSpawnerData : ScriptableObject
{
    public SpawnableObjects[] spawnableObjects;
    public List<GameObject> SpawnedObjects; 

    [System.Serializable]
    public class SpawnableObjects
    {
        public GameObject spawnablePrefab;
        public float spawnerStartHeight = 2f;
        public float spawnerEndHeight;
        public int currentObjects;
        public int numberOfObjects;
    }
}

Этот сценарий в настоящее время прекрасно работает, когда помещается в метод обновления, однако я не хочу этого делать из-за его влияния на производительность. Поэтому мне интересно, есть ли способ остановить выход из метода запуска Unity до тех пор, пока моя функция SpawnObjects () не перестанет работать. Если это невозможно, если у вас есть другие идеи о том, как я запускаю это только один раз без использования функции обновления, дайте мне знать.

Я относительно новичок в c # как языке, и мне жаль, если есть простое исправление, которое я пропустил. Любая помощь будет оценена. Спасибо.

1 Ответ

2 голосов
/ 18 марта 2019

Поскольку SpawnObjects является методом синхронизации Start не вернется, пока SpawnObjects не закончится.

Насколько я понимаю, ваша проблема скорее в том, что что-либо из Physics недоступно во время инициализации (Awake, OnEnable, Start), но только внутри или после блока Physics. (см. ExecutionOrder ), например, в методе типа FixedUpdate или Update.


Итак, чтобы ответить на ваш вопрос: вы можете использовать Coroutine и WaitForFixedUpdate для того, чтобы сделать ваш экземпляр:

void Start()
{
    r = GetComponent<Renderer>();
    for (int i = 0; i < spawnerData.spawnableObjects.Length; i++)
    {
        spawnerData.spawnableObjects[i].currentObjects = 0;
    }
    spawnerData.SpawnedObjects.Clear();

    StartCoroutine(DoInstantiate());
}

private IEnumerator DoInstantiate()
{
    // wait until Physics are initialized
    yield return new WaitForFixedUpdate();

    SpawnObjects();
}

или, как вы можете видеть в ScriptReference / Coroutine , вы можете сделать это короче, непосредственно сделав Start подпрограммой, например, как

IEnumerator Start()
{
    r = GetComponent<Renderer>();
    for (int i = 0; i < spawnerData.spawnableObjects.Length; i++)
    {
        spawnerData.spawnableObjects[i].currentObjects = 0;
    }
    spawnerData.SpawnedObjects.Clear();

    // wait until Physics are initialized
    yield return new WaitForFixedUpdate();

    SpawnObjects();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...