从预制件访问变量时为空引用异常

时间:2019-05-02 13:14:29

标签: c# unity3d game-development

当尝试将布尔值更改为右(或就此而言为左)时,出现空引用异常错误。我的预制件应该在FirepointL处生成。

我的脚本能够识别prefeb,因为它不会返回用于查找预制件的Null(对此进行了测试)。

我确保将布尔值设置为Public,并将所有GameObject都放到了Inspector中指定的位置。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    public GameObject bullet;

    private Rigidbody2D myRigidbody;
    private float speed = 15;
    private bool facingRight;
    private bool ground = false;
    private float jump = 23;
    // Start is called before the first frame update
    void Start()
    {
        facingRight = true;
        myRigidbody = GetComponent<Rigidbody2D>();

    }

    // Update is called once per frame
    void FixedUpdate()
    {
        float horizontal = Input.GetAxis("Horizontal");

        bullet = GameObject.FindGameObjectWithTag("Button");


        Movement(horizontal);
        Flip(horizontal);
        if (Input.GetKey("w"))
        {
            if (ground)
            {
                GetComponent<Rigidbody2D>().velocity = new Vector2(GetComponent<Rigidbody2D>().velocity.x, jump);
            }
        }
       // this is the part that returns the error
        if (facingRight == true)
        {
            bullet.GetComponent<weapon>().right = true;
        }
        if (facingRight == false)
        {
            bullet.GetComponent<weapon>().right = false;
        }

    }

    void OnTriggerEnter2D()
    {
        ground = true;
    }

    void OnTriggerExit2D()
    {
        ground = false;
    }

    private void Movement(float horizontal)
    {

        myRigidbody.velocity = new Vector2(horizontal * speed,myRigidbody.velocity.y);
    }

    private void Flip(float horizontal)
    {
        if (horizontal > 0 && !facingRight || horizontal < 0 && facingRight)
        {
            facingRight = !facingRight;

            Vector3 theScale = transform.localScale;

            theScale.x *= -1;

            transform.localScale = theScale;
        }


    }


}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class weapon : MonoBehaviour
{
    // Start is called before the first frame update
    public bool right;
    public Transform firepointR;
    public Transform firepointL;
    public GameObject bulletPrefab;

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown("space"))
        {
            Debug.Log("It's the space key");
            Shoot();
        }

    }

    void Shoot()
    {
        if (right == true)
        {
            Instantiate(bulletPrefab, firepointR.position, firepointR.rotation);
        }
        if(right == false)
        {
            Instantiate(bulletPrefab, firepointL.position, firepointL.rotation);
        }
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class bullet : MonoBehaviour
{
    public float speed = 20;

    public Rigidbody2D rb;
    // Start is called before the first frame update
    void Start()
    {
        rb.velocity = transform.right * speed;
    }

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

    }
}

2 个答案:

答案 0 :(得分:0)

不确定是否是确切的问题,但是PlayerMovement类中存在问题。检索bullet时,您假定存在带有Button标签的对象。

我认为,您应该使用

进行检查
// this is the part that returns the error
if (bullet && facingRight == true)
{
    bullet.GetComponent<weapon>().right = true;
}
if (bullet && facingRight == false)
{
    bullet.GetComponent<weapon>().right = false;
}

答案 1 :(得分:0)

我认为命名约定存在问题。您试图找出一个名为“按钮”的项目符号,但是在实例化游戏对象时,它将其命名为类似Button(clone)的名称。

我想到的一个解决方案:

第一步:

在PlayerMovement脚本中创建一个公共静态变量。

    public static PlayerMovement Instance;


private void Awake()
{
    Instance = this;
}

在awake函数中设置其值,以便您可以从任何地方调用它。

第二步:

我修改了拍摄功能。

void Shoot()
{
    GameObject _firePosition = right == true ? firepointR : firepointL;
    PlayerMovement.Instance.bullet = Instantiate(bulletPrefab, _firePosition.position, _firePosition.rotation); // we are setting the reference on runtime whenever we spawn a new bullet.
 }

第三步:

从PlayerMovement脚本中删除此行,因为现在不需要。

        bullet = GameObject.FindGameObjectWithTag("Button");

PS:如果您不执行步骤3,则代码将不起作用。如果有帮助,请告诉我。 :)