如何销毁 GameObject 并在一段时间后实例化一个新的
How to destroy GameObject & Instantiate new one after a while
我正在创建一个游戏,游戏中有 7 个 GameObject Prefab,每个实例化它都在水平上,我现在正在创建将实例化每个 GameObject Prefab 的主脚本,现在我想做的是所以创建每个 80f "seconds" 以实例化一个新的 GameObject Prefab,并销毁最后一个,例如,在 Level Started 后的 0f 秒内,实例化(随机)GameObject Prefab,并在 80f 秒内销毁我在 0f 中创建的那个秒,并实例化一个新的,依此类推。
这是我现在拥有的脚本,它不起作用,它会实例化新的游戏对象,但不要破坏我创建的最后一个。
我希望你能帮助我/给我一个解决这个问题的想法
注意我尝试使用堆栈,但是当我从堆栈中销毁预制件时,它会自行销毁预制件,而不是 recoverable.my 脚本:
TimeSinceLevelStarted = Time.timeSinceLevelLoad;
if (Mathf.Clamp(TimeSinceLevelStarted - TimeToLoadNext, -2f, 2f) == TimeSinceLevelStarted - TimeToLoadNext
&& LoadedFirstLevel == false)
{
GameObject go = LevelsPrefabs[Random.Range(0, LevelsPrefabs.Length)];
FirstLevel(go);
LoadedFirstLevel = false;
Debug.Log("Instantiated Prefab2");
}
}
private void FirstLevel(GameObject go)
{
if (LoadedFirstLevel == false)
{
Instantiate(go, new Vector3(0, 0, 0), Quaternion.identity);
goStack.Push(go);
Debug.Log("Instantiated Prefab1");
TimeToLoadNext += 50f;
LoadedFirstLevel = false;
if (TimeToLoadNext >= 30f) {
Destroy(go);
}
}
}
重复事件最好用协程来完成。 Unity 还告诉我们要避免在游戏运行时实例化和销毁游戏对象(因为它 "slow")——尤其是当它们可能被重用时。
因此,您想要的行为的快速而肮脏的实现应该如下所示。如果你想确保一个对象不会连续激活两次,你不能采取直接的随机方法,但你需要打乱数组并以新顺序生成它。有很多洗牌可用数组的示例。下面的内容应该很容易适应,只要你稍加修改即可;)
public class RandomSpawner : MonoBehaviour {
//i learned there should always be an option to break out of a loop
public bool exitCoroutine = false;
public GameObject[] prefabs;
public float waitTime = 80.0f;
WaitForSeconds waitObject;
GameObject[] gameObjects;
int currentlyActive = 0;
void Start() {
waitObject = new WaitForSeconds(waitTime);
gameObjects = new GameObject[prefabs.Length];
for (int i = 0; i < prefabs.Length; i++) {
gameObjects[i] = Instantiate(prefabs[i]);
gameObjects[i].SetActive(false);
}
StartCoroutine(SpawnRandomObject());
}
void ActivateRandom() {
int nextActive = Random.Range(0, gameObjects.Length);
gameObjects[currentlyActive].SetActive(false);
gameObjects[nextActive].SetActive(true);
currentlyActive = nextActive;
}
IEnumerator SpawnRandomObject() {
while (!exitCoroutine) {
ActivateRandom();
yield return waitObject;
}
}
}
https://docs.unity3d.com/ScriptReference/MonoBehaviour.StartCoroutine.html
https://docs.unity3d.com/ScriptReference/WaitForSeconds.html
我正在创建一个游戏,游戏中有 7 个 GameObject Prefab,每个实例化它都在水平上,我现在正在创建将实例化每个 GameObject Prefab 的主脚本,现在我想做的是所以创建每个 80f "seconds" 以实例化一个新的 GameObject Prefab,并销毁最后一个,例如,在 Level Started 后的 0f 秒内,实例化(随机)GameObject Prefab,并在 80f 秒内销毁我在 0f 中创建的那个秒,并实例化一个新的,依此类推。
这是我现在拥有的脚本,它不起作用,它会实例化新的游戏对象,但不要破坏我创建的最后一个。 我希望你能帮助我/给我一个解决这个问题的想法 注意我尝试使用堆栈,但是当我从堆栈中销毁预制件时,它会自行销毁预制件,而不是 recoverable.my 脚本:
TimeSinceLevelStarted = Time.timeSinceLevelLoad;
if (Mathf.Clamp(TimeSinceLevelStarted - TimeToLoadNext, -2f, 2f) == TimeSinceLevelStarted - TimeToLoadNext
&& LoadedFirstLevel == false)
{
GameObject go = LevelsPrefabs[Random.Range(0, LevelsPrefabs.Length)];
FirstLevel(go);
LoadedFirstLevel = false;
Debug.Log("Instantiated Prefab2");
}
}
private void FirstLevel(GameObject go)
{
if (LoadedFirstLevel == false)
{
Instantiate(go, new Vector3(0, 0, 0), Quaternion.identity);
goStack.Push(go);
Debug.Log("Instantiated Prefab1");
TimeToLoadNext += 50f;
LoadedFirstLevel = false;
if (TimeToLoadNext >= 30f) {
Destroy(go);
}
}
}
重复事件最好用协程来完成。 Unity 还告诉我们要避免在游戏运行时实例化和销毁游戏对象(因为它 "slow")——尤其是当它们可能被重用时。
因此,您想要的行为的快速而肮脏的实现应该如下所示。如果你想确保一个对象不会连续激活两次,你不能采取直接的随机方法,但你需要打乱数组并以新顺序生成它。有很多洗牌可用数组的示例。下面的内容应该很容易适应,只要你稍加修改即可;)
public class RandomSpawner : MonoBehaviour {
//i learned there should always be an option to break out of a loop
public bool exitCoroutine = false;
public GameObject[] prefabs;
public float waitTime = 80.0f;
WaitForSeconds waitObject;
GameObject[] gameObjects;
int currentlyActive = 0;
void Start() {
waitObject = new WaitForSeconds(waitTime);
gameObjects = new GameObject[prefabs.Length];
for (int i = 0; i < prefabs.Length; i++) {
gameObjects[i] = Instantiate(prefabs[i]);
gameObjects[i].SetActive(false);
}
StartCoroutine(SpawnRandomObject());
}
void ActivateRandom() {
int nextActive = Random.Range(0, gameObjects.Length);
gameObjects[currentlyActive].SetActive(false);
gameObjects[nextActive].SetActive(true);
currentlyActive = nextActive;
}
IEnumerator SpawnRandomObject() {
while (!exitCoroutine) {
ActivateRandom();
yield return waitObject;
}
}
}
https://docs.unity3d.com/ScriptReference/MonoBehaviour.StartCoroutine.html https://docs.unity3d.com/ScriptReference/WaitForSeconds.html