如何使克隆的游戏对象成为全局对象,以便可以在Unity功能之外使用它们?

时间:2018-12-27 23:58:01

标签: c# unity3d

我最近刚进入Unity 3D,目前从事我自己的第一个项目。对于即时游戏,我需要一个生成器功能,当敌​​人从平台上掉下来时,它会重新生成敌人的克隆。这是我现在拥有的代码:

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):错误CS0103:名称'enemyClone'在当前上下文中不存在”。

我确实知道为什么收到消息,但是不知道如何使敌人克隆在全球范围内可用。

谢谢大家

bezunyl

2 个答案:

答案 0 :(得分:0)

spawnEnemy()函数中,您说var enemyClone = Instantiate(...);。 evilClone是只能在spawnEnemy函数中使用的局部变量,或者至少是您编写它的方式。

如果要在spawnEnemy函数外部使用敌人敌人,则需要在函数外部声明敌人敌人变量。 (如果您不希望其他游戏对象可以访问敌人克隆,以下示例将可用)

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

现在,如果您希望其他游戏对象可以访问敌人克隆,那么您将需要使enemyClone变量public而不是private。如果您不希望它显示在检查器中,请在敌人克隆的声明上方添加[HideInInspector],如下所示:

[HideInInspector]
public GameObject enemyClone;

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

  

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

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

答案 1 :(得分:0)

按需生成GameObject非常昂贵。而不是每次都生成它,您应该将GameObject池化。

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