嗨,我正在使用随机地形的游戏,我想在这个地形上产生对象。为此,我创建了我所谓的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#语言相对较新,如果有一个我错过的简单修复,我很抱歉。任何帮助,将不胜感激。谢谢。
由于qazxsw poi是一种同步方法,qazxsw poi不会返回,直到SpawnObjects
完成。
据我所知,你的问题是Start
在初始化期间没有任何东西(SpawnObjects
,Physics
,Awake
),但只能在物理块内部或之后(参见OnEnable
),例如在像Start
或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