如何使克隆的游戏对象全局化,以便在Unity的函数之外使用它们



我最近刚进入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):error CS0103:名称'enemyClone'在当前上下文中不存在"。

我确实明白为什么我会收到消息,但不知道如何使enemyClone在全球可用。

提前感谢大家,

苯磺酰基

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

如果要在spawnEnemy函数之外使用enemyClone,则需要在函数之外声明enemyClone变量。(如果你不想让enemyClone被其他GameObjects访问,下面的例子会起作用)

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。如果您不希望它显示在检查器中,请在enemyClone的声明上方添加[HideInInspector],如下所示:

[HideInInspector]
public GameObject enemyClone;

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

变量的作用域决定了它对程序其余部分的可见性。

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

按需生成游戏对象的成本很高。与其每次都产卵,不如将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);
}
}
}

最新更新