First of all, I am somewhat of a beginner with Unity and programming in general, but I am pretty sure I have found some sort of bug/unintended interaction within the Unity SDK. I am using Unity 2018.2.11f1 and the Oculus VR SDK for Unity 3.4.1.
Essentially an error appears if an object is made inactive while holding it. At first this makes sense, so I worked around it by using the function ForceRelease() from the OVRGrabber Script BEFORE setting anything inactive. Therefore the hands release what they are holding and then set the object inactive. This avoids the nullreferencexception error.
HOWEVER, there is another error which appears. This can be recreated using just a simple cube with OVR grabbable. I used the following script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CubeScript : MonoBehaviour {
public GameObject Cube;
// GOmanager is a controller script, righthandanchor and lefthandanchor are gameobjects from the 'Tracking Space' OVR PlayerController prefab
// TEST: Turning off/on a cube with A button. Turning it off while holding it, then trying to grab the now inactive object with the other hand causes OVRGrabber to Stop Working at line 321
// FULL ERROR MESSAGE
/* NullReferenceException: Object reference not set to an instance of an object
// This is where it fails. grabbedRigidbody.MovePosition(grabbablePosition);
// I believe somehow even though the object when debugging in the console says it is released (m_grabbedObj = null), it is bypassing in MoveGrabbedObject(), going to the else condition and failing since the object is now inactive.
void Update () {
if(OVRInput.GetDown(OVRInput.Button.One))
{
// Check What Each Hand is Holding
Debug.Log("Left Hand is Holding : " + GOmanager.Instance.LeftHandAnchor.GetComponent<OVRGrabber>().grabbedObject);
Debug.Log("Right Hand is Holding : " + GOmanager.Instance.RightHandAnchor.GetComponent<OVRGrabber>().grabbedObject);
// Check What Each Hand is Holding Now After Release
Debug.Log("Left Hand is Holding : " + GOmanager.Instance.LeftHandAnchor.GetComponent<OVRGrabber>().grabbedObject);
Debug.Log("Right Hand is Holding : " + GOmanager.Instance.RightHandAnchor.GetComponent<OVRGrabber>().grabbedObject);
// Turn Cube On/Off
Cube.SetActive(!Cube.activeSelf);
// Check What Each Hand is Holding Now After cube is On/off
Debug.Log("Left Hand is Holding : " + GOmanager.Instance.LeftHandAnchor.GetComponent<OVRGrabber>().grabbedObject);
Debug.Log("Right Hand is Holding : " + GOmanager.Instance.RightHandAnchor.GetComponent<OVRGrabber>().grabbedObject);
}
}
}
So I'll explain what is happening. When I am holding the cube in my left hand, and set it inactive by pressing 'A', continue holding the left hand trigger down (STILL holding even though cube is now inactive), then try to grab the inactive cube with my right hand (where it would be), I get the full error message shown above in the script. Now when debugging to see what is being held at different stages when I press A I get:
Left Hand is Holding: Cube (OVRGrabbable) Right Hand is Holding: Left Hand is Holding: Right Hand is Holding: Left Hand is Holding: Right Hand is Holding:
This shows that ForceRelease successfully releases the held gameobject. Now let's look at the OVRGrabber Script:
It is proven that m_grabbedObj is null after releasing, so why does it go to the else condition, where it obviously fails as the grabbedRigidbody is inactive? It should just see that the grabbedObj is null and return null at the first step.
I hope I have made my issue clear, any advice would be really recommended.
@imperativity Sorry, I don't remember downloading the Oculus integration package, just the Unity SDK, Platform SDK and Avatar SDKs separately from the Oculus site. I can easily recreate the bug above with the SDK versions I have listed. Still haven't been able to solve it.
@imperativity I just checked the individual SDKs in the newest Oculus Integration package 1.30.1 and they are identical. So this bug should be easy to recreate with the new integration package.