How to prevent my Gravity gun from picking up nothing

My gravity gun code currently has a bug in which if the player right clicks on nothing then it will try to pick it up and allow you to drop it as well, but as soon as you try to pick up something else straight afterward then you’re left with an null pointer exception error. The reason this is happening is that within my code for picking up objects which is applied to the player.

I have 2 bools canpick & picking. canpick tells the player that when its set to true it can pick up an object and when its false that it is unable to pick up an item (Either there is no item to pick up or you’re already picking something up).

The picking bool on the otherhand refers to whether or not the player has right clicked to pick up / drop off an object. This starts off as false so that when you right click the mouse to pick up an object it will go true & upon releasing the right mouse button go false.

Currently at the moment if the player decides to right click on something that doesn’t have the tag pickup then it will set the canpick bool to false & upon pressing the right mouse button to essentially drop the item. The canpick bool will remain false, thus preventing the gravity gun from being able to pick up an object due to canpick bool not being true.

I created a small workaround for the right mouse button in which if the right mouse button is up and they’re not picking an object then it will set the canpick bool to true. Which means that in order to set the canpick bool to true, the player will have to click the right mouse button for an second time. Which will then state the null reference exception error before then allowing the player to pick up objects once again.

What should I do to be able to fix this problem as this work-around is only half the answer and I have no idea how I could go about getting a full answer to this.

PickUp Code

 public Quaternion   objectRot;
 public Vector3      objectPos;

 public GameObject   pickObj;
 public GameObject   pickref;

 public bool         canpick = true;
 public bool         picking = false;

 // Use this for initialization
 void Start ()
 {
 pickref = GameObject.FindWithTag("pickupref");
 pickObj = pickref;
 }

 // Update is called once per frame
 void Update ()
 {
 objectPos = transform.position;

 objectRot = transform.rotation;

 //Method here picks up the object with the right mouse button
 if (Input.GetMouseButtonDown (1) && canpick)
 {
     Debug.Log ("Object Picked Up");
     picking = true;

     Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);

     RaycastHit hit;

     if (Physics.Raycast (ray, out hit, 10) && hit.collider.gameObject.tag == "pickup")
     {
         pickObj = hit.collider.gameObject;
         hit.rigidbody.useGravity = false;
         hit.rigidbody.isKinematic = true;
         hit.collider.isTrigger = false;
         hit.transform.parent = gameObject.transform;
         hit.transform.position = objectPos;
         hit.transform.rotation = objectRot;
     }
     //else if (Physics.Raycast (ray, out hit, 10) && hit.collider.gameObject.tag != "pickup")
     //{
     //    canpick = true;
     //    Debug.Log ("Why are you trying to pick up nothing");
     //}

 }
 //canpick = true;



 if (Input.GetMouseButtonUp (1) && picking)
 {
     picking = false;
     canpick = false;
     //Debug.Log ("Fix this");


 }

 //This acts as a small work-around by reclicking and detecting that you haven't picked anything it will
 else if (Input.GetMouseButtonUp(1) && !picking)
 {
     canpick = true;
 }

 
 //Method here drops the object if it has been picked up by clicking the right mouse button
 if (Input.GetMouseButtonDown (1) && !canpick && pickObj.GetComponent<PickedUpObject> ().refuseThrow != true)
 {
     canpick = true;
     pickObj.rigidbody.useGravity = true;
     pickObj.rigidbody.isKinematic = false;
     pickObj.transform.parent = null;
     pickObj.collider.isTrigger = false;
     pickObj = pickref;
 }

}

PickedUpObject Code

 public bool refuseThrow = false;

 void OnTriggerEnter(Collider other)
 {
 if (other.gameObject.tag != "Player" && other.gameObject.tag != "pickto")
 {
     refuseThrow = true;
 }
 }

 void OneTriggerExit(Collider other)
 {
 if (other.gameObject.tag != "Player" && other.gameObject.tag != "pickto")
 {
     refuseThrow = false;
 }
 }

Move line 28 picking = true; to line 36, inside of the if(Physics.Raycast) block.

Right now you are setting picking to true even if there is nothing to pick up and you do not set pickObj. If you move the line then picking well only be set to true if the raycast detects a object with the correct tag.

I would also watch out for two other things. First, you do not set canpick to false when pickObj is set in the if(Physics.Raycast) block when the code seems like you should set it to false whenever something is picked up. Second, your picking boolean seems redundant with pickObj, it might be easier to just get rid of picking and use pickObj=obj/pickObj=null then test if you are picking an object using pickObj==null.

It looks like the error is caused because you are setting your booleans before checking if you are picking up an object.

Can you try changing your code around line 25 to:
//Method here picks up the object with the right mouse button
if (Input.GetMouseButtonDown (1) && canpick)
{
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);

      RaycastHit hit;
 
      if (Physics.Raycast (ray, out hit, 10) && hit.collider.gameObject.tag == "pickup")
      {
	      Debug.Log ("Object Picked Up");
          picking = true;
          
		  pickObj = hit.collider.gameObject;
          hit.rigidbody.useGravity = false;
          hit.rigidbody.isKinematic = true;
          hit.collider.isTrigger = false;
          hit.transform.parent = gameObject.transform;
          hit.transform.position = objectPos;
          hit.transform.rotation = objectRot;
      }
      else 
	  {
	      Debug.Log ("Why are you trying to pick up nothing");
      } 
  }