【问题标题】:How do I make my cloned game objects global, so I can use them outside of the function in Unity?如何使克隆的游戏对象成为全局对象,以便在 Unity 中的函数之外使用它们?
【发布时间】:2018-12-28 17:08:11
【问题描述】:

我最近刚接触 Unity 3D,目前正在处理我自己的第一个项目。对于我正在制作的游戏,我需要一个 spawner 功能,一旦敌人从平台上掉下来,它就会重新生成敌人的克隆。这是我现在的代码:

using UnityEngine;

public class spawner : MonoBehaviour
{
    public GameObject enemyPrefab;
    public float spawnHeight = 0.75f;

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

    // Update is called once per frame
    void Update()
    {
        if (enemyClone.transform.position.y < -10)
        {
            Destroy(enemyClone);
            spawnEnemy();
        }
    }

    public void spawnEnemy()
    {
        var enemyPosition = new Vector3(Random.Range(-5, 5), spawnHeight, Random.Range(-5, 5));
        var enemyClone = Instantiate(enemyPrefab, enemyPosition, Quaternion.identity);
    }
}

函数 spawnEnemy 本身工作正常,因为它在游戏开始时创建一个敌人,但不会产生更多的敌人。我收到消息:“Assets\spawner.cs(21,21): error CS0103: The name 'enemyClone' does not exist in the current context”。

我明白为什么我会收到这条消息,但是不知道如何让enemyClone 全球可用。

提前感谢大家,

苯乙腈

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    spawnEnemy() 函数中,你说var enemyClone = Instantiate(...);。 enemyClone 是一个局部变量,只能在 spawnEnemy 函数中使用,或者至少你是这样写的。

    如果要在spawnEnemy 函数之外使用enemyClone,则需要在函数之外声明enemyClone 变量。 (如果您不希望其他游戏对象可以访问enemyClone,则下面的示例将起作用)

    using UnityEngine;
    
    public class spawner : MonoBehaviour
    {
        public GameObject enemyPrefab;
        public float spawnHeight = 0.75f;
    
        private GameObject enemyClone //Added to allow enemyClone to be used anywhere in the class
    
        // Start is called before the first frame update
        void Start()
        {
            spawnEnemy();
        }
    
        // Update is called once per frame
        void Update()
        {
            if (enemyClone.transform.position.y < -10)
            {
                Destroy(enemyClone);
                spawnEnemy();
            }
        }
    
        public void spawnEnemy()
        {
            var enemyPosition = new Vector3(Random.Range(-5, 5), spawnHeight, Random.Range(-5, 5));
            enemyClone = Instantiate(enemyPrefab, enemyPosition, Quaternion.identity);
        }
    }
    

    现在,如果您希望其他 GameObjects 可以访问enemyClone,那么您需要将enemyClone 变量设置为public 而不是private。如果不希望它出现在inspector中,在enemyClone的声明上方添加[HideInInspector],如下图:

    [HideInInspector]
    public GameObject enemyClone;
    

    您的问题基于scope。你可能想研究它,知道这一点很重要。

    变量的范围决定了它对程序其余部分的可见性。

    http://www.blackwasp.co.uk/CSharpVariableScopes.aspx http://www.informit.com/articles/article.aspx?p=1609145&seqNum=4

    【讨论】:

    • 非常感谢您的帮助。我得到了它的工作。
    【解决方案2】:

    按需生成游戏对象是昂贵的。您应该池化游戏对象,而不是每次都生成它。

    public class Spawner : MonoBehaviour {
        public Enemy enemyPrefab;
        public List<Enemy> enemyPool;
        public const SPAWN_HEIGHT = 0.75f;
    
        // Start is called before the first frame update
        void Start()
        {
            enemyPool = new List<Enemy>();
            spawnEnemy();
        }
    
        // Update is called once per frame
        public void Despawn(Enemy deadEnemy)
        {
            deadEnemy.gameObject.SetActive(false);
            enemyPool.Add(deadEnemy);
        }
    
        public void spawnEnemy() {
            Enemy newEnemy;
            if (enemyPool.Count > 0) {
                newEnemy = enemyPool[0];
                enemyPool.Remove(0);
            } else {
                newEnemy = Instantiate(enemyPrefab);
            }
            newEnemy.Init(this);
    
            newEnemy.position =  new Vector3(Random.Range(-5, 5), SPAWN_HEIGHT, Random.Range(-5, 5));
            newEnemy.gameObject.SetActive(true);
        }
    }
    
    public class Enemy : MonoBehaviour {
        private Spawner spawner;
        private const float DEATH_POSITION_Y = -10;
    
        public void Init(Spawner spawner) {
            this.spawner = spawner;
        }
    
        void Update() {
            if (transform.position.y < DEATH_POSITION_Y) {
                spawner.Despawn(this);
            }
        }
    }
    

    【讨论】:

    • 感谢您的帮助。我会再研究一下,因为它看起来很复杂。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    • 1970-01-01
    • 2011-02-09
    • 1970-01-01
    • 2017-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多