GameObject在制作后设置为null

时间:2016-10-27 02:52:32

标签: c# unity3d

我整理了一个简单的脚本,创建了一个可以在UI中使用的基于精灵的指针。它尚未完成(仍然需要支持播放器按下按钮的时间),但已经遇到问题。

我得到一个NullReferenceException:对象引用未设置为对象的实例

第52行......

_ptrSpriteRenderer.sprite = newSprite;

......和72

_ptr.transform.position = new Vector2(((float)_ptrPosX * _ptrPositionXDistance) + _ptrPositionTopLeft.x, ((float)_ptrPosY * _ptrPositionYDistance) + _ptrPositionTopLeft.x);

我在Start中创建_ptr和_ptrSpriteRenderer,但由于某种原因,在我的所有其他函数中,这两个GameObject都为null,但它们在Start期间不为null。

我确信这是一件简单易事的事情,但是我花了好几个小时将这个班级与其他我创造精灵的班级进行比较,而且我可以'看到问题。

using UnityEngine;
using System.Collections;

public class Pointer : MonoBehaviour {

    private GameObject _ptr;
    private Sprite _ptrSprite;
    private SpriteRenderer _ptrSpriteRenderer;

    private bool _ptrEnabled;           // Is the pointer receiving input?
    private int _ptrMovePerSecond;      // Number of positions to move per second if input held down
    private int _ptrXInput;
    private int _ptrYInput;
    private float _ptrTimeSinceLastInput = 0f;
    private float _ptrTimePerInput = 0.25f;
    private bool _ptrInputDelay = false;

    private Vector2 _ptrPositionTopLeft;  //The top left position the pointer can reach in the grid
    private Vector2 _ptrPositionBottomRight;  //The bottom right position the pointer can reach in the grid
    private int _ptrPositionsX;   //The number of grid positions the pointer can traverse in X
    private int _ptrPositionsY;   //The number of grid positions the pointer can traverse in Y
    private float _ptrPositionXDistance;    //The distance of each X position in the grid
    private float _ptrPositionYDistance;    //The distance of each Y position in the grid

    private int _ptrPosX;   //Current X position of pointer in the grid
    private int _ptrPosY;   //Current Y position of pointer in the grid



    // Use this for initialization
    void Start () {
        _ptr = new GameObject();

        _ptrSpriteRenderer = new SpriteRenderer();
        _ptr.AddComponent<SpriteRenderer>();
        _ptrSpriteRenderer = _ptr.GetComponent<SpriteRenderer>();

        _ptrEnabled = true;


    }

    public void setSprite ( Sprite newSprite )
    {

        if (newSprite == null)
        {
            Debug.LogError("No sprite passed to setSprite in Pointer");
        }
        else
        {
            _ptrSpriteRenderer.sprite = newSprite;
        }
    }

    public void setPositions (Vector2 positionTopLeft, Vector2 positionBottomRight, int numPositionsX, int numPositionsY)
    {
        _ptrPositionsX = numPositionsX;
        _ptrPositionsY = numPositionsY;
        _ptrPositionTopLeft = positionTopLeft;
        _ptrPositionBottomRight = positionBottomRight;

        _ptrPositionXDistance = Mathf.Abs((positionBottomRight.x - positionTopLeft.x) / numPositionsX);
        _ptrPositionYDistance = Mathf.Abs((positionBottomRight.y - positionTopLeft.y) / numPositionsY);
    }

    public void setPosition (int x, int y)
    {
        _ptrPosX = x;
        _ptrPosY = y;

        _ptr.transform.position = new Vector2(((float)_ptrPosX * _ptrPositionXDistance) + _ptrPositionTopLeft.x, ((float)_ptrPosY * _ptrPositionYDistance) + _ptrPositionTopLeft.x);
    }



    // Update is called once per frame
    void Update () {
        //Is the pointer enabled?

        if (_ptrEnabled)
        {
            if (_ptrInputDelay)
            {
                _ptrTimeSinceLastInput += Time.deltaTime;
                if (_ptrTimeSinceLastInput >= _ptrTimePerInput)
                {
                    _ptrInputDelay = false;
                }
            }

            if (_ptrInputDelay == false)
            {
                _ptrXInput = (int)Input.GetAxis("Horizontal");
                _ptrYInput = (int)Input.GetAxis("Vertical");

                if (_ptrXInput != 0 || _ptrYInput != 0)
                {
                    _ptrPosX += _ptrXInput;
                    _ptrPosY += _ptrYInput;

                    Debug.Log("WHEE");

                    if (_ptrPosX < 0) _ptrPosX = 0;
                    if (_ptrPosX > _ptrPositionsX) _ptrPosX = _ptrPositionsX;
                    if (_ptrPosY < 0) _ptrPosY = 0;
                    if (_ptrPosY > _ptrPositionsY) _ptrPosY = _ptrPositionsY;

                    _ptr.transform.position = new Vector2(((float)_ptrPosX * _ptrPositionXDistance) + _ptrPositionTopLeft.x, ((float)_ptrPosY * _ptrPositionYDistance) + _ptrPositionTopLeft.x );

                    _ptrInputDelay = true;
                    _ptrTimeSinceLastInput = 0f;
                }
            }
        }
    }
}

我的Pointer类被调用的地方是这样的:

GameObject newPointer = new GameObject();
    newPointer.AddComponent<Pointer>();
    Pointer newPointerScript = newPointer.GetComponent<Pointer>();
    newPointerScript.setPositions(new Vector2(-1f, -1f), new Vector2(1f, 1f), 3, 3);
    newPointerScript.setSprite(newWeapon);
    newPointerScript.setPosition(1, 1);

2 个答案:

答案 0 :(得分:1)

这些行看起来不对:

    _ptrSpriteRenderer = new SpriteRenderer();
    _ptr.AddComponent<SpriteRenderer>();
    _ptrSpriteRenderer = _ptr.GetComponent<SpriteRenderer>();

你正在创建一个SpriteRenderer然后两行,用_ptr中的内容覆盖该值,这很可能是空的。

你真的需要这条线吗?

另外,如果您要添加组件,那么您是否应该将组件实际传递到Add方法?

答案 1 :(得分:0)

如果我用Awake()切换Start(),那么事实证明一切正常。这就是所需要的一切。