Unity实例化如何管理克隆对象

发布于 2025-02-02 10:59:28 字数 1545 浏览 4 评论 0原文

按照一个2D游戏教程创建怪物的怪物脚产脚本看起来像

public class MonsterSpawner : MonoBehaviour
{

    [SerializeField]
    private GameObject[] monsterReference;

    private GameObject spawnedMonster;

    [SerializeField]
    private Transform leftPos, rightPos;

    private int randomIndex;
    private int randomSide;

    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(SpawnMonsters());
    }

    IEnumerator SpawnMonsters() {

        while (true) {

            yield return new WaitForSeconds(Random.Range(1, 5));

            randomIndex = Random.Range(0, monsterReference.Length);
            randomSide = Random.Range(0, 2);

            spawnedMonster = Instantiate(monsterReference[randomIndex]);

            // left side
            if (randomSide == 0)
            {

                spawnedMonster.transform.position = leftPos.position;
                spawnedMonster.GetComponent<Monster>().speed = Random.Range(4, 10);

            }
            else
            {
                // right side
                spawnedMonster.transform.position = rightPos.position;
                spawnedMonster.GetComponent<Monster>().speed = -Random.Range(4, 10);
                spawnedMonster.transform.localScale = new Vector3(-1f, 1f, 1f);

            }
}}}

我的问题:每1-5秒钟,一个新的怪物被克隆到何处,对象内存管理发生在哪里,以及我如何处理/管理/如何处理/管理/更改特定对象(在C#中,我将有一个列表,可以通过mymonsters [i])

编辑注:我希望知道是否有一种获取和管理其内存的方法(让我们说销毁它们)而无需从教程更改代码(假设我想创建一个新的游戏经理类)

Following a 2D game tutorial for creating monsters the spawner script looks like this

public class MonsterSpawner : MonoBehaviour
{

    [SerializeField]
    private GameObject[] monsterReference;

    private GameObject spawnedMonster;

    [SerializeField]
    private Transform leftPos, rightPos;

    private int randomIndex;
    private int randomSide;

    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(SpawnMonsters());
    }

    IEnumerator SpawnMonsters() {

        while (true) {

            yield return new WaitForSeconds(Random.Range(1, 5));

            randomIndex = Random.Range(0, monsterReference.Length);
            randomSide = Random.Range(0, 2);

            spawnedMonster = Instantiate(monsterReference[randomIndex]);

            // left side
            if (randomSide == 0)
            {

                spawnedMonster.transform.position = leftPos.position;
                spawnedMonster.GetComponent<Monster>().speed = Random.Range(4, 10);

            }
            else
            {
                // right side
                spawnedMonster.transform.position = rightPos.position;
                spawnedMonster.GetComponent<Monster>().speed = -Random.Range(4, 10);
                spawnedMonster.transform.localScale = new Vector3(-1f, 1f, 1f);

            }
}}}

my question: every 1-5 seconds a new monster is being cloned where does the object memory management happens and how can I handle/manage/change a specific object (in C# I would have a list and can reach each object through myMonsters[i])

Editing Note: I wish to know if there is a way to get and manage their memory (lets say destroy them) without changing the code from the tutorial (lets say if I want to create a new game manager class)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夜灵血窟げ 2025-02-09 10:59:28

实例化将对象作为场景中的gameObject创建。内存是在场景层次结构中管理的。只要它是场景中的游戏对象,数据就存储在其中。

为了保留对GameObject的引用,您必须添加GameObject的列表,然后将实例化的GameObject添加到该列表中。要销毁GameObject,您必须调用destrot destrot(Monster)

我添加了您的代码,并在所有产卵的怪物中添加了列表。我还添加了一部分,当场景中有3个怪物时,会破坏怪物。

快速注意:我将所有内容都公开了,因为它通常更容易调试,因为您可以实时看到所有值。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MonsterSpawner : MonoBehaviour
{
    public GameObject[] monsterReference;

    public GameObject spawnedMonster;
    public List<GameObject> previouslySpawnedMonsters = new List<GameObject>();

    public Transform leftPos, rightPos;

    public int randomIndex;
    public int randomSide;

    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(SpawnMonsters());
    }

    IEnumerator SpawnMonsters()
    {
        int count = 0;
        while (true)
        {
            yield return new WaitForSeconds(Random.Range(1, 5));
            if (previouslySpawnedMonsters.Count > 3)
            {
                //get the monster to destroy
                GameObject monsterToDestroy = previouslySpawnedMonsters[0];

                //destroy the monster if it was spawned last round
                Destroy(monsterToDestroy);

                //remove the reference to the monster from our list of monsters
                previouslySpawnedMonsters.RemoveAt(0);
            }

            randomIndex = Random.Range(0, monsterReference.Length);
            randomSide = Random.Range(0, 2);

            spawnedMonster = Instantiate(monsterReference[randomIndex]);
            spawnedMonster.name = "monster " + count;
            count++;
            previouslySpawnedMonsters.Add(spawnedMonster);

            // left side
            if (randomSide == 0)
            {
                spawnedMonster.transform.position = leftPos.position;
                spawnedMonster.GetComponent<Monster>().speed = Random.Range(4, 10);
            }
            else
            {
                // right side
                spawnedMonster.transform.position = rightPos.position;
                spawnedMonster.GetComponent<Monster>().speed = -Random.Range(4, 10);
                spawnedMonster.transform.localScale = new Vector3(-1f, 1f, 1f);
            }
        }
    }
}

Instantiate creates the object as a gameobject in the scene. The memory is managed in the scene hierarchy. As long as it's a gameobject in the scene the data is stored in it.

To keep the references to the gameobject you'll have to add an list of Gameobjects and then add the instantiated gameobjects to that list. To destroy the gameobject however you'll have to call a Destroy(monster).

I've added to your code and added a list to all the spawned monsters. I've also added a part that destroys the monsters when there are more then 3 monsters in the scene.

Quick note: I've made everything public as it is often easier to debug, as you can see all the values in real time.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MonsterSpawner : MonoBehaviour
{
    public GameObject[] monsterReference;

    public GameObject spawnedMonster;
    public List<GameObject> previouslySpawnedMonsters = new List<GameObject>();

    public Transform leftPos, rightPos;

    public int randomIndex;
    public int randomSide;

    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(SpawnMonsters());
    }

    IEnumerator SpawnMonsters()
    {
        int count = 0;
        while (true)
        {
            yield return new WaitForSeconds(Random.Range(1, 5));
            if (previouslySpawnedMonsters.Count > 3)
            {
                //get the monster to destroy
                GameObject monsterToDestroy = previouslySpawnedMonsters[0];

                //destroy the monster if it was spawned last round
                Destroy(monsterToDestroy);

                //remove the reference to the monster from our list of monsters
                previouslySpawnedMonsters.RemoveAt(0);
            }

            randomIndex = Random.Range(0, monsterReference.Length);
            randomSide = Random.Range(0, 2);

            spawnedMonster = Instantiate(monsterReference[randomIndex]);
            spawnedMonster.name = "monster " + count;
            count++;
            previouslySpawnedMonsters.Add(spawnedMonster);

            // left side
            if (randomSide == 0)
            {
                spawnedMonster.transform.position = leftPos.position;
                spawnedMonster.GetComponent<Monster>().speed = Random.Range(4, 10);
            }
            else
            {
                // right side
                spawnedMonster.transform.position = rightPos.position;
                spawnedMonster.GetComponent<Monster>().speed = -Random.Range(4, 10);
                spawnedMonster.transform.localScale = new Vector3(-1f, 1f, 1f);
            }
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文