Unity3d 试图为我的游戏添加buff
我是编程新手。我在udemy开始了Unity3D课程,我已经完成了课程,但我正在尝试为我的游戏添加一个buff。我想要的是,当我的球员得到这个增益,他的投篮速度提高,我试图这样做,但我得到这个错误,当我与它碰撞Unity3d 试图为我的游戏添加buff,unity3d,Unity3d,我是编程新手。我在udemy开始了Unity3D课程,我已经完成了课程,但我正在尝试为我的游戏添加一个buff。我想要的是,当我的球员得到这个增益,他的投篮速度提高,我试图这样做,但我得到这个错误,当我与它碰撞 NullReferenceException: Object reference not set to an instance of an object Powerup.OnTriggerEnter2D (UnityEngine.Collider2D other) (at Assets/
NullReferenceException: Object reference not set to an instance of an object
Powerup.OnTriggerEnter2D (UnityEngine.Collider2D other) (at Assets/Galaxy Shooter/Scripts/Powerup.cs:54)
编辑
玩家
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour {
public bool canTripleShoot = false;
public bool movSpeedBoost = false;
public bool shield = false;
[SerializeField]
private GameObject _laserPrefabs;
[SerializeField]
private GameObject _tripleShootPrefab;
[SerializeField]
private GameObject _shieldGameObject;
[SerializeField]
private GameObject _explosionPrefab;
[SerializeField]
private float _speed = 5.0f;
[SerializeField]
private GameObject[] _engines;
[SerializeField]
private float _fireRate = 0.25f;
private float _canFire = 0.0f;
public int playerHp = 3;
public int _hitcount = 0;
private UIManager _uiManager;
private GameManager _gameManager;
private SpawnManager _spawnManager;
private AudioSource _audioSource;
// Use this for initialization
void Start () {
_audioSource = GetComponent<AudioSource>();
_spawnManager = GameObject.Find("Spawn_Manager").GetComponent<SpawnManager>();
_uiManager = GameObject.Find("Canvas").GetComponent<UIManager>();
_gameManager = GameObject.Find("GameManager").GetComponent<GameManager>();
transform.position = new Vector3(0, 0, 0);
if(_uiManager != null)
{
_uiManager.UpdateLives(playerHp);
}
if(_spawnManager != null)
{
_spawnManager.StartSpawn();
}
}
// Update is called once per frame
void Update ()
{
Movement();
//ativar ao pressionar espaço ou botão esquerdo do mouse
if (Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButton(0))
{
Shoot();
}
}
//renderização e cooldown dos tiros
private void Shoot()
{
if (Time.time > _canFire)
{
_audioSource.Play();
if (canTripleShoot== true)
{
Instantiate(_tripleShootPrefab, transform.position, Quaternion.identity);
}
else
{
Instantiate(_laserPrefabs, transform.position + new Vector3(0, 0.95f, 0), Quaternion.identity);
}
_canFire = Time.time + _fireRate;
}
}
//calculo de dano
public void Damage()
{
if(shield == true)
{
shield = false;
_shieldGameObject.SetActive(false);
return;
}
_hitcount++;
if(_hitcount == 1)
{
_engines[0].SetActive(true);
}
if(_hitcount == 2)
{
_engines[1].SetActive(true);
}
playerHp--;
_uiManager.UpdateLives(playerHp);
if(playerHp < 1)
{
Instantiate(_explosionPrefab, transform.position, Quaternion.identity);
_gameManager.gameOver = true;
_uiManager.ShowTitleScreen();
Destroy(this.gameObject);
}
}
public void ShieldUp()
{
shield = true;
_shieldGameObject.SetActive(true);
}
//controle da velocidade de movimento e teleporte
private void Movement()
{
float controleHorizontal = Input.GetAxis("Horizontal");
float controleVertical = Input.GetAxis("Vertical");
//velocidade de movimento
if(movSpeedBoost == true)
{
transform.Translate(Vector3.up * _speed * controleVertical * Time.deltaTime * 2.0f);
transform.Translate(Vector3.right * _speed * controleHorizontal * Time.deltaTime * 2.0f);
}else
{
transform.Translate(Vector3.up * _speed * controleVertical * Time.deltaTime);
transform.Translate(Vector3.right * _speed * controleHorizontal * Time.deltaTime);
}
//limita jogar até o centro da tela
if (transform.position.y > 0)
{
transform.position = new Vector3(transform.position.x, 0, 0);
}
//limita jogar até a borda inferior
else if (transform.position.y < -4.2f)
{
transform.position = new Vector3(transform.position.x, -4.2f, 0);
}
//teleporta jogar se sair da tela na horizontal
else if (transform.position.x < -9.45f)
{
transform.position = new Vector3(9.45f, transform.position.y, 0);
}
else if (transform.position.x > 9.45f)
{
transform.position = new Vector3(-9.45f, transform.position.y, 0);
}
}
//duração triple shot
public IEnumerator TripleShotPowerDownRoutine()
{
yield return new WaitForSeconds(5.0f);
canTripleShoot = false;
}
public void TripleShotPowerUpOn()
{
canTripleShoot = true;
StartCoroutine(TripleShotPowerDownRoutine());
}
//duração boost de movimento
public IEnumerator MovSpeedBoostDownRoutine()
{
yield return new WaitForSeconds(5.0f);
movSpeedBoost = false;
}
//ativa boost de movimento e inicia contagem de duração
public void MovSpeedBoost()
{
movSpeedBoost = true;
StartCoroutine(MovSpeedBoostDownRoutine());
}
}
通电
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Powerup : MonoBehaviour
{
[SerializeField]
private float _speed = 3.0f;
[SerializeField]
private int powerupID;
[SerializeField]
private AudioClip _clip;
// Update is called once per frame
void Update ()
{
//movimenta o powerup para baixo
transform.Translate(Vector3.down * _speed * Time.deltaTime);
//destroy o power ao sair da tela
if (transform.position.y <-7)
{
Destroy(this.gameObject);
}
}
private void OnTriggerEnter2D(Collider2D other)
{
if(other.tag == "Player")
{
//acessa o player
Player player = other.GetComponent<Player>();
if(player != null)
{
if(powerupID == 0)
{
//ativa tripleshoot
player.TripleShotPowerUpOn();
}
else if(powerupID == 1)
{
//ativa speedboost
player.MovSpeedBoost();
}
else if(powerupID == 2)
{
//ativar shield
player.ShieldUp();
}
else if (powerupID == 3)
{
Laser laser = GameObject.Find("laser").GetComponent<Laser>();
laser.LaserBoost();
}
}
//detroy powerup
AudioSource.PlayClipAtPoint(_clip, transform.position);
Destroy(this.gameObject);
}
}
}
其中一个:
1) 场景层次中没有名为“激光”的对象
2) 此对象存在,但未连接激光类型的组件
编辑:现在我看到了你的照片,我可以确认这是上面的情况。您有一个名为“激光”的预设,但它不存在于场景层次中。如果您希望它只在需要时才存在,则必须在场景中使用预制件 如果您想按预设的名称搜索它,有一种方法,但您需要在另一个命名资产中有一个名为Resources的文件夹。。。更多信息 相反,我建议你另一种方法。首先,您需要在某个对象中引用预置,具体取决于程序的逻辑。你似乎有一个游戏管理类,可能有一个好地方。在其中添加一个新字段(如果是这样的话),如下所示:
[SerializeField]
public Laser laser
// (...)
else if (powerupID == 3)
{
// I don't know for sure how can you access your GameManager in your program. I will suppose your player have a reference to it.
// You shall change the position depending on your game logic
Laser laserClone = (Laser) Instantiate(player.gameManager.laser, player.transform.position, player.transform.rotation);
laserClone.LaserBoost();
}
然后,更改生成错误的代码。GameObject.Find尝试查找场景中已存在的对象。在您的例子中,您希望通过传递对预置的引用来实例化它的克隆。大概是这样的:
[SerializeField]
public Laser laser
// (...)
else if (powerupID == 3)
{
// I don't know for sure how can you access your GameManager in your program. I will suppose your player have a reference to it.
// You shall change the position depending on your game logic
Laser laserClone = (Laser) Instantiate(player.gameManager.laser, player.transform.position, player.transform.rotation);
laserClone.LaserBoost();
}
现在,选择场景中具有引用的对象(同样,我假设它是gameManager)以查看其检查器,然后在laser
字段中填充对具有激光组件的预制件的引用。只要确保克隆对象在不需要时被销毁即可
但是。。。说实话,我不认为你会得到你所期望的结果。如果你想要的只是更快的射速,你现在尝试的方式对我来说似乎很复杂。你为什么不像你的三连拍那样拍呢?在您的播放器中添加一个标志,当该标志为真时,fireRate值会发生变化。以下两种标志之一:
1) 场景层次中没有名为“激光”的对象
2) 此对象存在,但未连接激光类型的组件
编辑:现在我看到了你的照片,我可以确认这是上面的情况。您有一个名为“激光”的预设,但它不存在于场景层次中。如果您希望它只在需要时才存在,则必须在场景中使用预制件 如果您想按预设的名称搜索它,有一种方法,但您需要在另一个命名资产中有一个名为Resources的文件夹。。。更多信息 相反,我建议你另一种方法。首先,您需要在某个对象中引用预置,具体取决于程序的逻辑。你似乎有一个游戏管理类,可能有一个好地方。在其中添加一个新字段(如果是这样的话),如下所示:
[SerializeField]
public Laser laser
// (...)
else if (powerupID == 3)
{
// I don't know for sure how can you access your GameManager in your program. I will suppose your player have a reference to it.
// You shall change the position depending on your game logic
Laser laserClone = (Laser) Instantiate(player.gameManager.laser, player.transform.position, player.transform.rotation);
laserClone.LaserBoost();
}
然后,更改生成错误的代码。GameObject.Find尝试查找场景中已存在的对象。在您的例子中,您希望通过传递对预置的引用来实例化它的克隆。大概是这样的:
[SerializeField]
public Laser laser
// (...)
else if (powerupID == 3)
{
// I don't know for sure how can you access your GameManager in your program. I will suppose your player have a reference to it.
// You shall change the position depending on your game logic
Laser laserClone = (Laser) Instantiate(player.gameManager.laser, player.transform.position, player.transform.rotation);
laserClone.LaserBoost();
}
现在,选择场景中具有引用的对象(同样,我假设它是gameManager)以查看其检查器,然后在laser
字段中填充对具有激光组件的预制件的引用。只要确保克隆对象在不需要时被销毁即可
但是。。。说实话,我不认为你会得到你所期望的结果。如果你想要的只是更快的射速,你现在尝试的方式对我来说似乎很复杂。你为什么不像你的三连拍那样拍呢?在您的播放器中添加一个标志,当该标志为真时,fireRate值会发生变化。基本上可能与您的GameObject.Find(“激光”).GetComponent()重复失败,您不应该将这些函数串联起来,因为如果GameObject.Find失败,您也会出现此错误。调用getcomponent后,应始终检查Laser是否为空。因此,首先要确保你正在执行此操作的场景确实有一个名为laser的游戏对象,并确保它确实有laser组件。(GameObject.Find可能是一个非常昂贵的调用,顺便说一句。)
void Start(){{u laserBoost=false;if({u laserBoost==true){{u speed=100f;}}
你知道这个if语句永远不会是真的,对吗?激光游戏对象是否处于活动状态??“查找”仅在对象处于活动状态时有效。如果没有,请在适当的层次结构中为组件提供资金。GameObject.Find(“laser”).GetComponent()可能与您的GameObject.Find有重复。失败后,您不应该将这些函数进行菊花链连接,因为如果GameObject.Find失败,也会出现此错误。调用getcomponent后,应始终检查Laser是否为空。因此,首先要确保你正在执行此操作的场景确实有一个名为laser的游戏对象,并确保它确实有laser组件。(GameObject.Find可能是一个非常昂贵的调用,顺便说一句。)void Start(){{u laserBoost=false;if({u laserBoost==true){{u speed=100f;}}
你知道这个if语句永远不会是真的,对吗?激光游戏对象是否处于活动状态??“查找”仅在对象处于活动状态时有效。如果没有,请在适当的层次结构中为组件提供资金。我的激光游戏对象名为“激光”,并附加了“激光”脚本。您是否也可以在该对象的场景中显示层次结构?我的激光游戏对象名为“激光”,并附加了“激光”脚本。您是否也可以在该对象的场景中显示层次结构?