【问题标题】:Wait for a function to finish executing before the start method stops在 start 方法停止之前等待函数完成执行
【发布时间】:2019-03-18 19:45:25
【问题描述】:

您好,我正在开发使用随机地形的游戏,我想在该地形上生成对象。为此,我创建了所谓的 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() 函数停止运行。如果这不可能,如果您对我如何在不使用更新功能的情况下仅运行一次有任何其他想法,请告诉我。

我对 c# 作为一种语言比较陌生,如果我错过了一个简单的修复方法,我很抱歉。任何帮助,将不胜感激。谢谢。

【问题讨论】:

  • 我不明白你的问题。因为SpawnObjects 是一个同步方法StartSpawnObjects 完成之前不会返回......另外你在Update 中究竟调用了什么?
  • 您认为Start 会在SpawnObjects 完成之前立即退出吗?我认为情况并非如此。
  • @BenRubin 我不确定我在解释这个问题方面做得是否最好。该脚本当前设置为产生 10 个发束,然后如果将其放置在 update 方法中,则停止它可以正常工作,但是,当放置在 start 方法中时,每次只会产生 1-2 个发束。我也刚刚意识到 spawnObjects 方法的工作方式可能存在问题。
  • 附带说明,在第一次设置之前使用 randomX 和 randomZ 似乎是错误的。您可能希望将它们移到 Physics.Raycast 语句上方。您也可以通过编写 spawnerData.spawnableObjects[i].currentObjects++ 来增加 1,但这只是风格问题。

标签: c# unity3d game-engine game-development


【解决方案1】:

由于SpawnObjects 是一种同步方法,Start 将在SpawnObjects 完成之前不会返回。

据我了解,您的问题是 Physics 中的任何内容在初始化期间均不可用(AwakeOnEnableStart),但仅在物理块之内或之后(请参阅ExecutionOrder)所以例如在FixedUpdateUpdate 之类的方法中。


所以回答您的问题:您可以使用CoroutineWaitForFixedUpdate 来进行实例化:

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();
}

【讨论】:

  • 谢谢你一些总体上好的建议,但是在尝试之后,没有任何结果我开始认为问题实际上出在我的 SpawnObjects 方法上。
  • 我现在找到了解决方案,因为事实证明我缺少一个 for 循环,该循环需要循环遍历创建的对象数量,我只是循环遍历数组中的不同区域。
猜你喜欢
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 2013-08-09
  • 1970-01-01
  • 2020-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多