我最近刚进入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
答案 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);
}
}
}