【问题标题】:How to destroy GameObject & Instantiate new one after a while一段时间后如何销毁游戏对象并实例化新对象
【发布时间】:2018-10-28 22:13:34
【问题描述】:

我正在创建一个游戏,在游戏中有 7 个 GameObject Prefab,每个都在关卡上实例化它,我现在正在创建将实例化每个 GameObject Prefab 的主脚本,现在我想做的就是创建每 80f“秒”实例化一个新的 GameObject Prefab,并销毁最后一个,例如,自关卡启动后的 0f 秒内,实例化(随机)GameObject Prefab,并在 80f 秒内销毁我在 0f 秒内创建的一个,并实例化一个新的,等等。

这是我现在拥有的脚本,它不起作用,它会实例化新的游戏对象,但不要破坏我创建的最后一个。 我希望你能帮助我/给我一个如何解决这个问题的想法 注意我尝试使用 Stack,但是当我从堆栈中销毁 Prefab 时,它会自行销毁 Prefab,并且无法恢复。我的脚本:

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

【问题讨论】:

  • 使用协程。
  • 如果您的问题只是在延迟后销毁对象:Destroy 的过载会延迟几秒钟,例如 Destroy(obj, 80.0f);

标签: c# unity3d gameobject


【解决方案1】:

重复事件最好使用协程来完成。此外,Unity 告诉我们避免在游戏运行时实例化和销毁游戏对象(因为它“慢”)——尤其是当它们可能被重用时。

因此,您想要的行为的快速而肮脏的实现应该如下。如果你想确保一个对象不会连续两次被激活,你不能采取直接的随机方法,但你需要打乱数组并以新的顺序生成它。有很多洗牌可用数组的示例。下面的内容应该很容易适应,只需稍加修改即可;)

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

【讨论】:

  • 非常感谢您的帮助,您是真正的救星! tho,我遇到了 1 个问题,当游戏对象实例化时,当它重新出现时消失,它不会从屏幕顶部重新出现,它保持在完全相同的位置,这可能会导致玩家输掉而没有做错任何事情,如何我可以解决吗? :)
  • @JhonySitbon 我不知道你的游戏对象做什么,但我猜想什么可以解决你的问题。 GameObjects 有两个函数OnEnable 和OnDisable 你可以重载。当它们被禁用(或启用,这真的不重要)时,您可能必须使用它们来重置位置。如果您需要比以下两个链接更多的帮助,请随时打开一个新问题(不要忘记给出一个很好的描述和您尝试过的代码示例)docs.unity3d.com/ScriptReference/MonoBehaviour.OnEnable.html 和 docs.unity3d.com/ScriptReference/MonoBehaviour.OnDisable.html
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多