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/

我是编程新手。我在udemy开始了Unity3D课程,我已经完成了课程,但我正在尝试为我的游戏添加一个buff。我想要的是,当我的球员得到这个增益,他的投篮速度提高,我试图这样做,但我得到这个错误,当我与它碰撞

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语句永远不会是真的,对吗?激光游戏对象是否处于活动状态??“查找”仅在对象处于活动状态时有效。如果没有,请在适当的层次结构中为组件提供资金。我的激光游戏对象名为“激光”,并附加了“激光”脚本。您是否也可以在该对象的场景中显示层次结构?我的激光游戏对象名为“激光”,并附加了“激光”脚本。您是否也可以在该对象的场景中显示层次结构?