Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

NRE encountered when clicking on ground - debugging for an RTS game

Discussion in 'Scripting' started by icosminc92, Jul 22, 2019.

  1. icosminc92

    icosminc92

    Joined:
    Jul 22, 2019
    Posts:
    2
    Hello, I just started working with Unity and scripting in general, I am new to this realm so please bear with me.

    I am trying to make an RTS game, following some tutorial on Youtube and landed on an issue that is quite frustrating. When I click on the ground in the Active game window without having a unit selected I get:


    NullReferenceException: Object reference not set to an instance of an object
    InputManager.LeftClick () (at Assets/Scripts/InputManager.cs:53)
    InputManager.Update () (at Assets/Scripts/InputManager.cs:34)


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class InputManager : MonoBehaviour {
    6.    
    7.     public float panSpeed;
    8.     public float rotateSpeed;
    9.     public float rotateAmount;
    10.  
    11.     private Quaternion rotation;
    12.  
    13.     private float panDetect = 15f;
    14.     private float minHeight = 10f;
    15.     private float maxHeight = 100f;
    16.  
    17.     public GameObject selectedObject;
    18.     public ObjectInfo selectedInfo;
    19.  
    20.     // Start is called before the first frame update
    21.     void Start()
    22.     {
    23.         rotation = Camera.main.transform.rotation;
    24.     }
    25.  
    26.     // Update is called once per frame
    27.     void Update()
    28.     {
    29.         MoveCamera();
    30.         RotateCamera();
    31.  
    32.         if(Input.GetMouseButtonDown(0))
    33.         {  
    34.             LeftClick();
    35.         }
    36.  
    37.         if(Input.GetKeyDown(KeyCode.Space))
    38.         {
    39.             Camera.main.transform.rotation = rotation;
    40.         }
    41.     }
    42.  
    43.     public void LeftClick()
    44.     {
    45.         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    46.         RaycastHit hit;
    47.  
    48.         if(Physics.Raycast(ray, out hit, 100))
    49.         {
    50.             if(hit.collider.tag == "Ground")
    51.             {
    52.                 selectedObject = null;
    53.                 selectedInfo.isSelected = false;
    54.                 selectedInfo = null;
    55.                 Debug.Log("Deselected");
    56.             }
    57.            
    58.             else if(hit.collider.tag == "Selectable")
    59.             {
    60.                 selectedObject = hit.collider.gameObject;
    61.                 selectedInfo = selectedObject.GetComponent<ObjectInfo>();
    62.  
    63.                 selectedInfo.isSelected = true;
    64.  
    65.                 Debug.Log("Selected" + selectedInfo.objectName);
    66.             }
    67.         }
    68.     }
    69.  
    70.     void MoveCamera()
    71.     {
    72.         float moveX = Camera.main.transform.position.x;
    73.         float moveY = Camera.main.transform.position.y;
    74.         float moveZ = Camera.main.transform.position.z;
    75.  
    76.         float xPos = Input.mousePosition.x;
    77.         float yPos = Input.mousePosition.y;
    78.  
    79.         if(Input.GetKey(KeyCode.A) || xPos > 0 && xPos < panDetect)
    80.         {
    81.             moveX -= panSpeed;
    82.         }
    83.         else if(Input.GetKey(KeyCode.D) || xPos < Screen.width && xPos > Screen.width - panDetect)
    84.         {
    85.             moveX += panSpeed;
    86.         }
    87.  
    88.         if(Input.GetKey(KeyCode.W) || yPos < Screen.height && yPos > Screen.height - panDetect)
    89.         {
    90.             moveZ += panSpeed;
    91.         }
    92.         else if(Input.GetKey(KeyCode.S) || yPos > 0 && yPos < panDetect)  
    93.         {  
    94.             moveZ -= panSpeed;
    95.         }
    96.  
    97.  
    98.         moveY -= Input.GetAxis("Mouse ScrollWheel") * (panSpeed * 20);
    99.         moveY = Mathf.Clamp(moveY, minHeight, maxHeight);  
    100.         Vector3 newPos = new Vector3(moveX, moveY, moveZ);
    101.         Camera.main.transform.position = newPos;
    102.  
    103.     }
    104.  
    105.     void RotateCamera()
    106.     {
    107.         Vector3 origin = Camera.main.transform.eulerAngles;
    108.         Vector3 destination = origin;
    109.  
    110.         if (Input.GetMouseButton(2))
    111.         {
    112.             destination.x -= Input.GetAxis("Mouse Y") * rotateAmount;
    113.             destination.y -= Input.GetAxis("Mouse X") * rotateAmount;
    114.         }
    115.  
    116.         if (destination != origin)
    117.         {
    118.             Camera.main.transform.eulerAngles = Vector3.MoveTowards(origin, destination, Time.deltaTime * rotateSpeed);
    119.  
    120.         }
    121.     }
    122.  
    123. }
    124.  
    This is the script in which the Error happens, and the following one has references that are used in the one above:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.AI;
    5.  
    6. public class ObjectInfo : MonoBehaviour
    7. {
    8.     public TaskList task;
    9.     public ResourceManager RM;
    10.  
    11.     public GameObject targetNode;
    12.  
    13.     public NodeManager.ResourceTypes heldResourceType;
    14.  
    15.     public bool isSelected = false;
    16.     public bool isGathering = false;
    17.  
    18.     public string objectName;
    19.  
    20.     private NavMeshAgent agent;
    21.  
    22.     public int heldResource;
    23.     public int maxHeldResource;
    24.  
    25.     public GameObject[] drops;
    26.  
    27.  
    28.  
    29.     // Start is called before the first frame update
    30.     void Start()
    31.     {
    32.         StartCoroutine(GatherTick());
    33.         agent = GetComponent<NavMeshAgent>();
    34.     }
    35.  
    36.     // Update is called once per frame
    37.     void Update()
    38.     {
    39.         if(targetNode == null)
    40.         {
    41.             if(heldResource != 0)
    42.             {
    43.                 drops = GameObject.FindGameObjectsWithTag ("Drops");
    44.                 agent.destination = GetClosestDropOff(drops).transform.position;
    45.                 drops = null;
    46.                 task = TaskList.Delivering;
    47.             }
    48.             else
    49.             {
    50.                 task = TaskList.Idle;
    51.             }
    52.         }
    53.         if(heldResource >= maxHeldResource)
    54.         {
    55.             drops = GameObject.FindGameObjectsWithTag ("Drops");
    56.             agent.destination = GetClosestDropOff(drops).transform.position;
    57.             drops = null;
    58.             task = TaskList.Delivering;
    59.         }
    60.  
    61.  
    62.         if(Input.GetMouseButtonDown(1) && isSelected)
    63.         {
    64.             RightClick();
    65.         }
    66.     }
    67.  
    68.     GameObject GetClosestDropOff(GameObject[] dropOffs)
    69.     {
    70.         GameObject closestDrop = null;
    71.         float closestDistance = Mathf.Infinity;
    72.         Vector3 position = transform.position;
    73.  
    74.         foreach (GameObject targetDrop in dropOffs)
    75.         {
    76.             Vector3 direction = targetDrop.transform.position - position;
    77.             float distance = direction.sqrMagnitude;
    78.             if(distance < closestDistance)
    79.             {
    80.                 closestDistance = distance;
    81.                 closestDrop = targetDrop;
    82.             }
    83.         }
    84.  
    85.         return closestDrop;
    86.     }
    87.  
    88.  
    89.     public void RightClick()
    90.     {
    91.         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    92.         RaycastHit hit;
    93.  
    94.         if(Physics.Raycast(ray, out hit, 100))
    95.         {
    96.             if(hit.collider.tag == "Ground")
    97.             {
    98.                 agent.destination = hit.point;
    99.                 Debug.Log("Moving");
    100.                 task = TaskList.Moving;
    101.             }
    102.             else if(hit.collider.tag == "Resource")
    103.             {  
    104.                 agent.destination = hit.collider.gameObject.transform.position;
    105.                 Debug.Log("Harvesting");
    106.                 task = TaskList.Gathering;
    107.                 targetNode = hit.collider.gameObject;
    108.             }
    109.         }
    110.     }
    111.  
    112.     public void OnTriggerEnter(Collider other)
    113.     {
    114.         GameObject hitObject = other.gameObject;
    115.  
    116.         if(hitObject.tag == "Resource" && task == TaskList.Gathering)
    117.         {
    118.             isGathering = true;
    119.             hitObject.GetComponent<NodeManager>().gatherers++;
    120.             heldResourceType = hitObject.GetComponent<NodeManager>().resourceType;
    121.            
    122.         }
    123.         else if(hitObject.tag == "Drops" && task == TaskList.Delivering)
    124.         {
    125.             if(RM.metal >= RM.maxMetal)
    126.             {
    127.                 task = TaskList.Idle;
    128.             }
    129.             else
    130.             {
    131.                 RM.metal += heldResource;
    132.                 heldResource = 0;
    133.                 if (targetNode != null)
    134.                 {
    135.                     task = TaskList.Gathering;
    136.                     agent.destination = targetNode.transform.position;
    137.                 }
    138.                 else task = TaskList.Idle;
    139.  
    140.             }
    141.         }
    142.     }
    143.  
    144.     public void OnTriggerExit(Collider other)
    145.     {
    146.         GameObject hitObject = other.gameObject;
    147.        
    148.         if(hitObject.tag == "Resource")
    149.         {
    150.             hitObject.GetComponent<NodeManager>().gatherers--;
    151.             isGathering = false;
    152.         }
    153.     }
    154.  
    155.     IEnumerator GatherTick()
    156.     {
    157.         while (true)
    158.         {
    159.             yield return new WaitForSeconds(1);
    160.             if(isGathering)
    161.             {
    162.                 heldResource++;
    163.             }
    164.         }
    165.     }
    166.  
    167.  
    168. }
    169.  
    I apologize afront for the long and painful post, I am trying to do my best learning to code.:D
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    If you don't have anything selected, then selectInfo.isSelected refers to the property "isSelected" of an object that doesn't exist, hence the error. All you need to do in this case is check for null before doing that:
    Code (csharp):
    1.  
    2.             if(hit.collider.tag == "Ground")
    3.             {
    4.                 selectedObject = null;
    5. if (selectedInfo != null) {
    6.                 selectedInfo.isSelected = false;
    7.                 selectedInfo = null;
    8.                 Debug.Log("Deselected");
    9. }
    10.             }
     
    icosminc92 likes this.
  3. icosminc92

    icosminc92

    Joined:
    Jul 22, 2019
    Posts:
    2
    Thank you so much!
    The error no longer happens, but I got something funnier... I can't reselect the unit. I mean, no errors, no nothing in the console. Got any ideas ?