Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Confusing null reference exception

Discussion in 'Scripting' started by MaltedWheaties, Aug 19, 2020.

  1. MaltedWheaties

    MaltedWheaties

    Joined:
    Apr 15, 2020
    Posts:
    44
    Hi there, I am making a drag and drop script for 2D sprites.

    I am getting an "object reference not set to an instance of an object" error on line 39. I can't see where I am going wrong.

    Thanks in advance for any help

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class NEWdragdrop : MonoBehaviour {
    7.  
    8.     public LayerMask IncludeLayers;//include the block layer
    9.     public LayerMask dropDataIncludeLayers;//include the valid position layer
    10.     public bool isDragging = false;
    11.     public GameObject currentBlock;
    12.     public Vector2 currentBlockPreviousPosition;
    13.     public GameObject previousBlock;
    14.     public float units = 1f;
    15.  
    16.     void Update() {
    17.         Vector3 pointerScreenPoint = Input.mousePosition;
    18.  
    19.         Vector2 pointerWorldPoint = Camera.main.ScreenToWorldPoint(pointerScreenPoint);
    20.  
    21.         RaycastHit2D hitData = Physics2D.Raycast(pointerWorldPoint, Vector2.zero, Mathf.Infinity, IncludeLayers);
    22.  
    23.         if (Input.GetMouseButtonDown(0)){
    24.             if (hitData) {
    25.                 isDragging = true;
    26.                 currentBlock = hitData.transform.gameObject;
    27.                 currentBlockPreviousPosition = currentBlock.transform.position;
    28.                 if (previousBlock != null) {
    29.                     previousBlock.GetComponent<SpriteRenderer>().sortingOrder = 4;
    30.                 }
    31.                 currentBlock.GetComponent<SpriteRenderer>().sortingOrder = 5;
    32.             }
    33.         }
    34.  
    35.         if (Input.GetMouseButton(0)) {
    36.             if (isDragging) {
    37.                 float pointerWorldPointX = Mathf.Round(pointerWorldPoint.x / units);
    38.                 float pointerWorldPointY = Mathf.Round(pointerWorldPoint.y / units);
    39.                 if (hitData.transform.gameObject.name == "Block_S") {
    40.                     currentBlock.transform.position = new Vector3(pointerWorldPointX + .5f, pointerWorldPointY, currentBlock.transform.position.z);
    41.                 }
    42.                 else if (hitData.transform.name == "Block_A" || hitData.transform.name == "Block_D") {
    43.                     currentBlock.transform.position = new Vector3(pointerWorldPointX, pointerWorldPointY, currentBlock.transform.position.z);
    44.                 }
    45.                 else {
    46.                     Debug.Log("There is a collider in the \'block\' layer");
    47.                 }
    48.                 currentBlock.GetComponent<BoxCollider2D>().enabled = false;
    49.             }
    50.         }
    51.  
    52.         if (Input.GetMouseButtonUp(0)) {
    53.          
    54.             RaycastHit2D dropData = Physics2D.Raycast(pointerWorldPoint, Vector2.zero, Mathf.Infinity, dropDataIncludeLayers);
    55.             if (!dropData) {
    56.                 currentBlock.transform.position = currentBlockPreviousPosition;
    57.             }
    58.  
    59.             isDragging = false;
    60.             currentBlock.GetComponent<BoxCollider2D>().enabled = true;
    61.  
    62.             previousBlock = currentBlock;
    63.         }
    64.     }
    65. }
    66.  
    67.  
     
  2. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    Look in the console, the error should tell which line the null reference is came from.
     
  3. MaltedWheaties

    MaltedWheaties

    Joined:
    Apr 15, 2020
    Posts:
    44
    Hi, apologies, I forgot to include this. It's in the question now. :)
     
  4. adehm

    adehm

    Joined:
    May 3, 2017
    Posts:
    369
    I don't believe hitData is a gameobject.
     
  5. MaltedWheaties

    MaltedWheaties

    Joined:
    Apr 15, 2020
    Posts:
    44
    It's not - It's storing the raycast information. What I'm using line 39 for is to get the hitData object's transform, then get the gameobject the transform component is attatched to, then get the name of the gameobject.
     
  6. adehm

    adehm

    Joined:
    May 3, 2017
    Posts:
    369
    Perhaps then line 42 is the real issue.

    39. hitData.transform.gameObject.name
    42. hitData.transform.name
     
  7. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    hitData is probably null, you are populating it each frame and when you start dragging, it likely doesn't hit the object you think it should. Check if hitData is null before you do anything with it.
     
  8. MaltedWheaties

    MaltedWheaties

    Joined:
    Apr 15, 2020
    Posts:
    44
    That was it. Because I had made the sprites snap to the nearest x units, sometimes I could drag outside of the sprite, while it is still snapped to the previous position, meaning I would be over empty space, causing the raycast hitData to return null. Thanks a lot!

    I'll attach the final script below;

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class NEWdragdrop : MonoBehaviour {
    6.  
    7.     public LayerMask IncludeLayers;//include the block layer
    8.     public LayerMask dropDataIncludeLayers;//include the valid position layer
    9.     public bool isDragging = false;
    10.     public GameObject currentBlock;
    11.     public Vector2 currentBlockPreviousPosition;
    12.     public GameObject previousBlock;
    13.     public float units = 1f;
    14.     public RaycastHit2D hitData;
    15.  
    16.     void Update() {
    17.         Vector3 pointerScreenPoint = Input.mousePosition;
    18.  
    19.         //screenPoint.z = Vector3.Distance(transform.position, Camera.main.transform.position);//poncey maths, just set the raycast to go forever like a boss
    20.         Vector2 pointerWorldPoint = Camera.main.ScreenToWorldPoint(pointerScreenPoint);
    21.  
    22.  
    23.         if (Input.GetMouseButtonDown(0)){
    24.             hitData = Physics2D.Raycast(pointerWorldPoint, Vector2.zero, Mathf.Infinity, IncludeLayers);
    25.             if (hitData) {
    26.                 isDragging = true;
    27.                 currentBlock = hitData.transform.gameObject;
    28.                 currentBlockPreviousPosition = currentBlock.transform.position;
    29.                 if (previousBlock != null) {
    30.                     previousBlock.GetComponent<SpriteRenderer>().sortingOrder = 4;
    31.                 }
    32.                 currentBlock.GetComponent<SpriteRenderer>().sortingOrder = 5;
    33.             }
    34.         }
    35.  
    36.         if (Input.GetMouseButton(0)) {
    37.             if (isDragging) {
    38.                 float pointerWorldPointX = Mathf.Round(pointerWorldPoint.x / units);
    39.                 float pointerWorldPointY = Mathf.Round(pointerWorldPoint.y / units);
    40.                 if (hitData.transform.gameObject.name == "Block_S") {
    41.                     currentBlock.transform.position = new Vector3(pointerWorldPointX + .5f, pointerWorldPointY, currentBlock.transform.position.z);
    42.                 }
    43.                 else if (hitData.transform.gameObject.name == "Block_A" || hitData.transform.gameObject.name == "Block_D") {
    44.                     currentBlock.transform.position = new Vector3(pointerWorldPointX, pointerWorldPointY, currentBlock.transform.position.z);
    45.                 }
    46.                 else {
    47.                     Debug.Log("There is a collider in the \'block\' layer");
    48.                 }
    49.                 currentBlock.GetComponent<BoxCollider2D>().enabled = false;
    50.             }
    51.         }
    52.  
    53.         if (Input.GetMouseButtonUp(0)) {
    54.          
    55.             RaycastHit2D dropData = Physics2D.Raycast(pointerWorldPoint, Vector2.zero, Mathf.Infinity, dropDataIncludeLayers);
    56.             if (!dropData) {
    57.                 currentBlock.transform.position = currentBlockPreviousPosition;
    58.             }
    59.  
    60.             isDragging = false;
    61.             currentBlock.GetComponent<BoxCollider2D>().enabled = true;
    62.  
    63.             previousBlock = currentBlock;
    64.         }
    65.     }
    66. }
    67.