How to instantiate an Oculus grabbable object at runtime in Unity?
Asked Answered
S

2

1

Right now I have an obj file in Unity. I have a script that adds a Collider component, a Rigidbody component, and finally an OVRGrabbable component to the object. I need to add these components at runtime because eventually I will be producing procedural meshes in a script at runtime, and I need these procedural meshes to be grabbable.

My problem is that the OVRGrabbable script does not recognize the added collider as a grab point when the collider is added at runtime. I thought that it would be enough to add the collider before the OVRGrabbable in my script, but no dice. I tried attaching the collider in an Awake function and then the OVRGrabbable in the Start function, but that didn't work either. Additionally, I cannot add it in script because the grabPoints array is read-only. Here is my code:

     public class AddVRComponents : MonoBehaviour {
     void Start () {
         public bool freeMoving = false;
         public bool useGravity = false;

         collide = gameObject.AddComponent<BoxCollider>();

         Rigidbody rB = gameObject.AddComponent<Rigidbody>();
         if (!freeMoving)
         {
             rB.drag = Mathf.Infinity;
             rB.angularDrag = Mathf.Infinity;
         }
         if (!useGravity)
         {
             rB.useGravity = false;
         }

         OVRGrabbable grab = gameObject.AddComponent<OVRGrabbable>();
         Collider[] newGrabPoints = new Collider[1];
         newGrabPoints[0] = collide;
         grab.enabled = true;
         grab.grabPoints = newGrabPoints;
     }
 }

This obviously does not work because the final line produces the error that grab.grabPoints is read-only.

I know that it can be done because if I run my program and then in the editor manually drag my collider into the grab points field of the OVRGrabbable component, the object can be grabbed.

How can I get the OVRGrabbable script to recognize my collider?

Sonstrom answered 24/7, 2018 at 15:58 Comment(1)
can you make a prefab with all of those components set and then instantiate the prefab?Trinitrotoluene
F
2

Read-only properties are properties that can be assigned only through the script that contains them. This means that you can only change the value of grabPoints from inside the OVRGrabbable.cs script.

The best way to do this is by adding a custom function inside the OVRGrabbable.cs file so that you can access and set the read only variables.

I use this one so I can also set the snapPosition and snapOrientation fields as well as the grabPoints.

public void Initialize(bool snapPosition, bool snapOrientation, Collider[] grabPoints)
{
    m_snapPosition = snapPosition;
    m_snapOrientation = snapOrientation;
    m_grabPoints = grabPoints;
}

You'll be good enough only adding and calling the following one:

public void Initialize(Collider[] grabPoints)
{
    m_grabPoints = grabPoints;
}
Fablan answered 16/10, 2018 at 21:25 Comment(0)
D
0

I made this modification to OVRGrabbale.cs:

void Awake()
    {
        if (ReferenceEquals(m_grabPoints, null) || m_grabPoints.Length == 0)
        {
            // Get the collider from the grabbable
            Collider collider = this.GetComponent<Collider>();
            if (collider == null)
            {
                throw new ArgumentException("Grabbables cannot have zero grab points and no collider -- please add a grab point or collider.");
            }

            // Create a default grab point
            m_grabPoints = new Collider[1] { collider };
        }
    }

I checked to see if m_grabPoints is null and it worked.

Dunc answered 28/12, 2022 at 0:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.