Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Accessing VR controllers

Discussion in 'Scripting' started by Mellin, Jan 11, 2018.

  1. Mellin

    Mellin

    Joined:
    Aug 3, 2015
    Posts:
    27
    Hi.

    I'm trying to access buttons on both VR controllers in my script.
    Right now I have this:
    Code (CSharp):
    1. GameObject ControllerRight = GameObject.Find("Controller (right)");
    2. SteamVR_TrackedObject trackedObjectR = ControllerRight.GetComponent<SteamVR_TrackedObject>();
    3. deviceR = SteamVR_Controller.Input((int)trackedObjectR.index);
    4.  
    5. GameObject ControllerLeft = GameObject.Find("Controller (left)");
    6. SteamVR_TrackedObject trackedObjectL = ControllerLeft.GetComponent<SteamVR_TrackedObject>();
    7. deviceL = SteamVR_Controller.Input((int)trackedObjectL.index);
    In the MVS I don't get any errors, but when I try to start my scene in Unity, it pauses and I get an error that line (in this case #2):

    For reference here is a bigger chunk of that code, where I try to access those buttons:
    Code (CSharp):
    1.  
    2.  
    3.             GameObject ControllerRight = GameObject.Find("Controller (right)");
    4.             SteamVR_TrackedObject trackedObjectR = ControllerRight.GetComponent<SteamVR_TrackedObject>();
    5.             deviceR = SteamVR_Controller.Input((int)trackedObjectR.index);
    6.  
    7.             GameObject ControllerLeft = GameObject.Find("Controller (left)");
    8.             SteamVR_TrackedObject trackedObjectL = ControllerLeft.GetComponent<SteamVR_TrackedObject>();
    9.             deviceL = SteamVR_Controller.Input((int)trackedObjectL.index);
    10.  
    11.             GameObject HandL = GameObject.Find("ModelL");
    12.             LeftHand LeftHand = HandL.GetComponent<LeftHand>();
    13.  
    14.             GameObject HandR = GameObject.Find("ModelR");
    15.             RightHand RightHand = HandR.GetComponent<RightHand>();
    16.  
    17.             if (deviceR.GetPressDown(SteamVR_Controller.ButtonMask.ApplicationMenu) && RightHand.InHand == "No" && Vector3.Distance(transform.position, ControllerRight.transform.position) < 0.1)
    18.             {
    19.                 RightHand.InHand = "Gun";
    20.                 FNMain.Hand = "Right";
    21.                 rb.isKinematic = true;
    22.             }
    23.             if (deviceL.GetPressDown(SteamVR_Controller.ButtonMask.ApplicationMenu) && LeftHand.InHand == "No" && Vector3.Distance(transform.position, ControllerLeft.transform.position) < 0.1)
    24.             {
    25.                 LeftHand.InHand = "Gun";
    26.                 FNMain.Hand = "Left";
    27.                 rb.isKinematic = true;
    28.             }
    Anyone got an idea, of what am I doing wrong?
     
  2. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    The likely problem is the controller gameobjects aren't enabled when you are searching and therefore not found.

    What I do is put a script on each controller gameobject and have that pass the events from the controller to a static input manager and that is setup to simple return false if the controller hasn't registered with it yet.
     
  3. Mellin

    Mellin

    Joined:
    Aug 3, 2015
    Posts:
    27
    That doesn't seem to be the case.

    I have both Vive controllers connected and visible when I start it.
     
  4. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    If you're getting a null ref error on line #2, then it's likely because GameObject.Find returned null for ControllerRight, and you're trying to access a null instance when calling GetComponent. Maybe the name doesn't match (be very careful here, is the capitalization exactly correct? Number of spaces?)?

    Honestly, I'd just discourage the use of GameObject.Find, and encourage you to link to the controller instances. Just use "public GameObject ControllerRight" to expose it in the inspector and assign it there. Then whether it's active or not is a non-issue, as well as the naming issue goes away.
     
  5. Mellin

    Mellin

    Joined:
    Aug 3, 2015
    Posts:
    27
    Thanks for an idea.
    I was able to use that in other scripts and it did improve thing there, but in this instance, I still get an error, but this time from another object:
    Now my code looks like this:
    Code (CSharp):
    1. SteamVR_TrackedObject trackedObjectR = ControllerRight.GetComponent<SteamVR_TrackedObject>();
    2.             deviceR = SteamVR_Controller.Input((int)trackedObjectR.index);
    3.        
    4.             SteamVR_TrackedObject trackedObjectL = ControllerLeft.GetComponent<SteamVR_TrackedObject>();
    5.             deviceL = SteamVR_Controller.Input((int)trackedObjectL.index);
    That cs:76 is line #2 in here.
     
    Last edited: Jan 15, 2018
  6. Mellin

    Mellin

    Joined:
    Aug 3, 2015
    Posts:
    27
    Any idea what's wrong?
     
  7. StickyHoneybuns

    StickyHoneybuns

    Joined:
    Jan 16, 2018
    Posts:
    207
    I don't think you can use the TrackedObject method with the new SteamVR plugin player prefab. I had to change my code to the new Hand system at least.

    Here is how I'm accessing the controllers now.

    Code (CSharp):
    1.  
    2. Using Steam_VR_InteractionSystem;
    3.  
    4. private Hand hand;
    5.  
    6. if(hand.Controller.GetPress(SteamVR_Controller.ButtonMask.Trigger)//change trigger to whatever button you want
    7. {
    8. "Do something"
    9. }
    You can access most buttons this way but if you want to access the hairtrigger or dpad sensitivity it is slightly different. I don't remember the code for those off the top of my head but can add it to this topic later if it helps you. Basically the hair trigger returns a value between 0 and 1. The dpad I think returns a value between -1 and 1 on both xy (have to double check this though).

    If you didn't change the names of the prefab Hands, the left will be Hand1 and the right will be Hand2. You then can use this to reference which hand is interacting with whatever gameObject or event.

    The button presses have 3 states; GetPress, GetPressDown, GetPressUp.

    If I didn't explain it good enough I will be happy to post my code once I am home this evening.
     
  8. W0lfStride

    W0lfStride

    Joined:
    Feb 26, 2018
    Posts:
    1
    Could you please elaborate on using Hand script for inputs? I keep getting a Null reference exception... aka I am pretty bad at this.
    I would be very grateful for your help, my entire class project depends on getting these inputs from the hand script. Thank you! Please help me, you are my only hope.
     
    Last edited: Feb 26, 2018
  9. StickyHoneybuns

    StickyHoneybuns

    Joined:
    Jan 16, 2018
    Posts:
    207
    You are most likely getting a null reference exception due to the Hand not being pointed to in a gameObject. You should be able to change Private Hand hand to public Hand hand and drag and drop your Hand1 or Hand2 into the inspector from the player prefab.

    Also, if you post your code I can see where you went wrong as this is just a guess.

    Also, this is only one way to do it. Another way is to write your own player prefab but SteamVR plugin already has this so it's somewhat redundant.
     
  10. m2n1

    m2n1

    Joined:
    Apr 9, 2019
    Posts:
    1
    I ran into the same problem in the initial post, with the same error message. In my case, the controllers were not able to be found via "GetComponent<SteamVR_TrackedObject>()" because there were no tracked object components attached to them (I had been using the default CameraRig prefab from SteamVR).

    I simply clicked the "Add Component" button on both of the Controller game objects and added the "Steam VR_Tracked Object" script. I also set the Index setting to Device 1 for the left controller and Device 2 for the right- in the OP's original code, this looks to be a necessary step, since it references the Index. After doing this, GetComponent<SteamVR_TrackedObject>() worked for me.
     
  11. Alco6

    Alco6

    Joined:
    Oct 19, 2018
    Posts:
    13
    The problem was a matter of the Hierarchy using Camera Rig.
    GameObject.Find("/[CameraRig]/Controller (right)");

    Be sure the controllers are on when running it.
     
    mgear likes this.