简体   繁体   中英

GameObject being set to null after being made

I put together a simple script that creates a sprite-based pointer I can use in UI. It's not complete yet (still needs support for when the player pushes a button), but already running into problems.

I get a NullReferenceException: Object reference not set to an instance of an object

At line 52...

_ptrSpriteRenderer.sprite = newSprite;

...and 72

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

I am creating _ptr and _ptrSpriteRenderer in the Start, but for some reason at all my other functions these two GameObjects are null, and yet they aren't null during Start.

I'm sure it's something simple that I goofed up on, but I've spent hours comparing this class to other classes where I've created sprites and I can't see the issue.

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

And the place where my Pointer class is being called is done like this:

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

These lines look wrong:

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

You are creating a SpriteRenderer and then two lines later overwriting the value with what's in _ptr which is, in all probability, null.

Do you really need this line?

Also if you're adding a component shouldn't you be actually passing the component into the Add method?

So turns out everything works fine if I switch Start() with Awake(). That's all that was needed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM