试图给我的游戏增加增益

时间:2018-07-14 14:36:07

标签: unity3d

我是编程新手。我在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)

编辑 Album With usefull images

玩家

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.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Laser : MonoBehaviour {
    [SerializeField]
    public float _speed = 10.0f;
    [SerializeField]
    public bool _laserBoost = false;
    // Use this for initialization
    void Start () {
        _laserBoost = false;

        if (_laserBoost == true)
        {
            _speed = 100f;
        }
    }

    // Update is called once per frame
    void Update () {

        //código gigante e dificil de decifrar ~irony
        transform.Translate(Vector3.up * _speed * Time.deltaTime);
        if (transform.position.y > 6f)
        {
            if(transform.parent != null)
            {
                Destroy(transform.parent.gameObject);
            }
            Destroy(gameObject);
        }

    }
    public IEnumerator LaserBoostDuration()
    {
        yield return new WaitForSeconds(10f);
        _laserBoost = false;
    }
    public void LaserBoost()
    {
        _laserBoost = true;
        StartCoroutine(LaserBoostDuration());
    }

}

开机

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

错误发生在

laser.LaserBoost();

1 个答案:

答案 0 :(得分:2)

两个之一:

1)您在“场景”层次结构中没有名为“激光”的对象;

2)该对象存在,但没有附加类型为Laser的组件。


编辑:既然看到了您的图片,我可以确认是上面的情况1)。您有一个名为“ laser”的预制件,但在场景层次结构中不存在。如果您希望它仅在需要时才存在,则必须instantiate在现场进行预制。

如果要按名称搜索Prefab,有一种方法,但是您需要在另一个名为Assets的文件夹中有一个名为Resources的文件夹...更多信息here

相反,我建议您使用另一种方法。首先,根据程序的逻辑,您将需要在某些对象中引用您的Prefab。您似乎有一个GameManager类,可能有个不错的地方。像这样在其中添加一个新字段:

    [SerializeField]
    public Laser laser
    // (...)

然后,更改生成错误的代码。 GameObject.Find尝试查找场景中已经存在的对象。对于您的情况,您想通过传递对Prefab的引用来实例化它的克隆。像这样:

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

现在,在Scene中选择将具有引用的对象(同样,我假设它是gameManager)以查看其检查器,而不是在laser字段中填充对具有Laser组件的Prefab的引用。只要确定克隆对象在不需要时会被销毁即可。

但是...老实说,我认为您无论如何也不会获得预期的结果。如果您想要的只是更快的拍摄速度,那么现在对我来说,您正在尝试的方法似乎很复杂。你为什么不像三连拍那样做呢?在播放器内部添加一个标志,当设置为true时,fireRate值就会更改。