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)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InputManager : MonoBehaviour {
public float panSpeed;
public float rotateSpeed;
public float rotateAmount;
private Quaternion rotation;
private float panDetect = 15f;
private float minHeight = 10f;
private float maxHeight = 100f;
public GameObject selectedObject;
public ObjectInfo selectedInfo;
// Start is called before the first frame update
void Start()
{
rotation = Camera.main.transform.rotation;
}
// Update is called once per frame
void Update()
{
MoveCamera();
RotateCamera();
if(Input.GetMouseButtonDown(0))
{
LeftClick();
}
if(Input.GetKeyDown(KeyCode.Space))
{
Camera.main.transform.rotation = rotation;
}
}
public void LeftClick()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, 100))
{
if(hit.collider.tag == "Ground")
{
selectedObject = null;
selectedInfo.isSelected = false;
selectedInfo = null;
Debug.Log("Deselected");
}
else if(hit.collider.tag == "Selectable")
{
selectedObject = hit.collider.gameObject;
selectedInfo = selectedObject.GetComponent<ObjectInfo>();
selectedInfo.isSelected = true;
Debug.Log("Selected" + selectedInfo.objectName);
}
}
}
void MoveCamera()
{
float moveX = Camera.main.transform.position.x;
float moveY = Camera.main.transform.position.y;
float moveZ = Camera.main.transform.position.z;
float xPos = Input.mousePosition.x;
float yPos = Input.mousePosition.y;
if(Input.GetKey(KeyCode.A) || xPos > 0 && xPos < panDetect)
{
moveX -= panSpeed;
}
else if(Input.GetKey(KeyCode.D) || xPos < Screen.width && xPos > Screen.width - panDetect)
{
moveX += panSpeed;
}
if(Input.GetKey(KeyCode.W) || yPos < Screen.height && yPos > Screen.height - panDetect)
{
moveZ += panSpeed;
}
else if(Input.GetKey(KeyCode.S) || yPos > 0 && yPos < panDetect)
{
moveZ -= panSpeed;
}
moveY -= Input.GetAxis("Mouse ScrollWheel") * (panSpeed * 20);
moveY = Mathf.Clamp(moveY, minHeight, maxHeight);
Vector3 newPos = new Vector3(moveX, moveY, moveZ);
Camera.main.transform.position = newPos;
}
void RotateCamera()
{
Vector3 origin = Camera.main.transform.eulerAngles;
Vector3 destination = origin;
if (Input.GetMouseButton(2))
{
destination.x -= Input.GetAxis("Mouse Y") * rotateAmount;
destination.y -= Input.GetAxis("Mouse X") * rotateAmount;
}
if (destination != origin)
{
Camera.main.transform.eulerAngles = Vector3.MoveTowards(origin, destination, Time.deltaTime * rotateSpeed);
}
}
}
This is the script in which the Error happens, and the following one has references that are used in the one above:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class ObjectInfo : MonoBehaviour
{
public TaskList task;
public ResourceManager RM;
public GameObject targetNode;
public NodeManager.ResourceTypes heldResourceType;
public bool isSelected = false;
public bool isGathering = false;
public string objectName;
private NavMeshAgent agent;
public int heldResource;
public int maxHeldResource;
public GameObject[] drops;
// Start is called before the first frame update
void Start()
{
StartCoroutine(GatherTick());
agent = GetComponent<NavMeshAgent>();
}
// Update is called once per frame
void Update()
{
if(targetNode == null)
{
if(heldResource != 0)
{
drops = GameObject.FindGameObjectsWithTag ("Drops");
agent.destination = GetClosestDropOff(drops).transform.position;
drops = null;
task = TaskList.Delivering;
}
else
{
task = TaskList.Idle;
}
}
if(heldResource >= maxHeldResource)
{
drops = GameObject.FindGameObjectsWithTag ("Drops");
agent.destination = GetClosestDropOff(drops).transform.position;
drops = null;
task = TaskList.Delivering;
}
if(Input.GetMouseButtonDown(1) && isSelected)
{
RightClick();
}
}
GameObject GetClosestDropOff(GameObject[] dropOffs)
{
GameObject closestDrop = null;
float closestDistance = Mathf.Infinity;
Vector3 position = transform.position;
foreach (GameObject targetDrop in dropOffs)
{
Vector3 direction = targetDrop.transform.position - position;
float distance = direction.sqrMagnitude;
if(distance < closestDistance)
{
closestDistance = distance;
closestDrop = targetDrop;
}
}
return closestDrop;
}
public void RightClick()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, 100))
{
if(hit.collider.tag == "Ground")
{
agent.destination = hit.point;
Debug.Log("Moving");
task = TaskList.Moving;
}
else if(hit.collider.tag == "Resource")
{
agent.destination = hit.collider.gameObject.transform.position;
Debug.Log("Harvesting");
task = TaskList.Gathering;
targetNode = hit.collider.gameObject;
}
}
}
public void OnTriggerEnter(Collider other)
{
GameObject hitObject = other.gameObject;
if(hitObject.tag == "Resource" && task == TaskList.Gathering)
{
isGathering = true;
hitObject.GetComponent<NodeManager>().gatherers++;
heldResourceType = hitObject.GetComponent<NodeManager>().resourceType;
}
else if(hitObject.tag == "Drops" && task == TaskList.Delivering)
{
if(RM.metal >= RM.maxMetal)
{
task = TaskList.Idle;
}
else
{
RM.metal += heldResource;
heldResource = 0;
if (targetNode != null)
{
task = TaskList.Gathering;
agent.destination = targetNode.transform.position;
}
else task = TaskList.Idle;
}
}
}
public void OnTriggerExit(Collider other)
{
GameObject hitObject = other.gameObject;
if(hitObject.tag == "Resource")
{
hitObject.GetComponent<NodeManager>().gatherers--;
isGathering = false;
}
}
IEnumerator GatherTick()
{
while (true)
{
yield return new WaitForSeconds(1);
if(isGathering)
{
heldResource++;
}
}
}
}
I apologize afront for the long and painful post, I am trying to do my best learning to code.