在 start 方法停止之前等待函数完成执行

Wait for a function to finish executing before the start method stops

您好,我正在开发使用随机地形的游戏,我想在该地形上生成对象。为此,我创建了所谓的 Surface Populator 脚本。

这是脚本:

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() 函数停止 运行ning。如果这是不可能的,如果您对我如何 运行 这一次不使用更新功能有任何其他想法,请告诉我。

我对 c# 这门语言还比较陌生,如果我错过了一个简单的修复程序,我深表歉意。任何帮助,将不胜感激。谢谢

因为 SpawnObjects 是一个同步方法 Start 无论如何都不会 return 直到 SpawnObjects 完成。

据我了解你的问题是来自 Physics is not available during initialization (Awake, OnEnable, Start) but only within or after the Physics block (see ExecutionOrder) 的任何问题,例如在像 FixedUpdateUpdate.

这样的方法中

所以回答你的问题:你可以使用 Coroutine and 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();
}