Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[Solved] Setting Unity Steamvr 2.2 Locktopoint Only Oncollisionenter

Discussion in 'AR/VR (XR) Discussion' started by Giantbean, Apr 13, 2019.

  1. Giantbean

    Giantbean

    Joined:
    Dec 13, 2012
    Posts:
    144
    I am learning Steam VR with the 2.2 release and the hands are a great. I can pick up objects and toss them around with the throwable script built into the SteamVR plugin. The issue is that all the objects have physics so its hard to place something back in a specific spot. Valve provided a LockToPoint script in the plug in which when used will snap an object back to a point when the object is released however I don't want to snap all the time. I only want to snap when I collide with a preset location and let go of the object.
    here is a snip from something I was trying

    Code (CSharp):
    1.      using Valve.VR;
    2.     using Valve.VR.InteractionSystem;
    3.     using Valve.VR.InteractionSystem.Sample;
    4.    
    5.      public GameObject AttachableObject;
    6.    
    7.     private void OnTriggerExit(Collider other)
    8.         {
    9.             if (other.gameObject.tag == TagName)
    10.             {
    11.                  AttachableObject.GetComponent<LockToPoint>().enabled = false;
    12.              }
    13.     }
    The simple idea is that this would turn off the snap to point when the object leaves its base station and another script with n OnTriggerEnter would turn the LockToPoint.cs back on.
    The idea works but with a major flaw that I have not been able to fix. The Flaw is that when you exit the home base with the LockToPoint and deactivate the scrip the ridged body of the object losses its Kinematics and pulls down on the hand holding it. If dropped it floats in place and when grabbed again it becomes kinematic as it should in the hand but each time you drop the object from then on it once again losses kinematics and floats in space.

    setting up a GetComponent(); and then telling it to turn off and on i.e

    Code (CSharp):
    1.      private Rigidbody body;
    2.      private void start()
    3.         {
    4.             body = GetComponent<Rigidbody>();
    5.         }
    6.    
    7.     private void OnTriggerExit(Collider other)
    8.         {
    9.             if (other.gameObject.tag == TagName)
    10.             {
    11.                 //...other lines redacted for clarity of the point being made
    12.                 body.isKinematic = false; // or true
    13.             }
    14.         }

    has not helped as the SteamVR scripts for the hand, throwable, and LockToPoint all seem to be competing with one another.

    Anyone know how I can make the script snap the object to a set transform and rotation only when it is colliding with the base station and the user/player has dropped the object?
     
  2. Giantbean

    Giantbean

    Joined:
    Dec 13, 2012
    Posts:
    144
    FYI I can now pick up the object without it causing drag on the hand however when I let go it still floats in mid air.

    Code (CSharp):
    1.  public GameObject AttachableObject;
    2.  
    3. private void OnTriggerExit(Collider other)
    4.     {
    5.         if (other.gameObject.tag == TagName)
    6.         {
    7.           AttachableObject.GetComponent<Rigidbody>().isKinematic = true;
    8.          }
    9.      }
    Does anyone knows where the Steam VR hand gets set to use kinematics while being held and release kinematics when dropped.. I am thinking its in the throwable script but I am unsure how to access the function.
     
  3. Giantbean

    Giantbean

    Joined:
    Dec 13, 2012
    Posts:
    144
    I was able to fix the issue with the following script on the object being attached and dethatched from the base station.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Valve.VR.InteractionSystem;
    5.  
    6. public class RemoveKenimaticOnRelease : MonoBehaviour
    7. {
    8.     private void OnDetachedFromHand(Hand hand)
    9.     {
    10.         GetComponent<Rigidbody>().isKinematic = false;
    11.     }
    12. }
     
  4. hassancortex

    hassancortex

    Joined:
    Oct 27, 2019
    Posts:
    7
    This works great. Thank you very much. However, what I am looking for, is to snap it back to it's original position before it was grabbed.
     
  5. Giantbean

    Giantbean

    Joined:
    Dec 13, 2012
    Posts:
    144
    Are you wanting it to snap back no mater where it is in the scene or could it be placed into a collider and then move back to its primary location as if you are holstering it?
     
  6. Giantbean

    Giantbean

    Joined:
    Dec 13, 2012
    Posts:
    144
    Maybe try a two part solution such as removing it and then replacing it?


    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using Valve.VR;
    4. using Valve.VR.InteractionSystem;;
    5. using UnityEngine.Events;
    6.  
    7. public class RemoveHome : MonoBehaviour //AKA Attatch to hand
    8. {
    9.     public GameObject[] SwitchObjectsOnPickUp;
    10.     public Collider[] SwitchCollidersOnPickUp;
    11.     public Animator[] ItemActiveAnimations;
    12.     public string[] ActiveAnimationStates;
    13.     //public GameObject AttachableObject;
    14.     public string ObjectName;
    15.     public UnityEvent onRemoval;
    16.  
    17.     private Interactable interactable;
    18.     private SteamVR_Input_Sources hand;
    19.  
    20.     private void start()
    21.     {
    22.         interactable = GetComponent<Interactable>();
    23.     }
    24.  
    25.     //Switch states and Animate if the item is removed from the base station
    26.     private void OnTriggerExit(Collider other)
    27.     {
    28.         if (other.gameObject.name.IndexOf(ObjectName) > -1)
    29.         {
    30.             if (SwitchObjectsOnPickUp.Length > 0)
    31.             {
    32.                 foreach (GameObject go in SwitchObjectsOnPickUp)
    33.                 {
    34.                     go.SetActive(!go.activeSelf);
    35.                 }
    36.             }
    37.             if (SwitchCollidersOnPickUp.Length > 0)
    38.             {
    39.                 foreach (Collider c in SwitchCollidersOnPickUp)
    40.                 {
    41.                     c.enabled = !c.enabled;
    42.                 }
    43.             }
    44.             if (ItemActiveAnimations.Length > 0 && ActiveAnimationStates.Length > 0 && ActiveAnimationStates.Length == ItemActiveAnimations.Length)
    45.             {
    46.                 for (int i = 0; i < ItemActiveAnimations.Length; i++)
    47.                 {
    48.                     ItemActiveAnimations[i].Play(ActiveAnimationStates[i]);
    49.                 }
    50.             }
    51.  
    52.             onRemoval.Invoke();
    53.  
    54.             //Turn off lock point and return kinamatic control to the hand.
    55.             Destroy(other.gameObject.GetComponent<LockToPoint>());
    56.             other.gameObject.GetComponent<Rigidbody>().isKinematic = true; // object should have "RemoveKenimaticonRelease" script to keep it from floating when dropped.
    57.  
    58.         }
    59.     }
    60. }
    and then

    Code (CSharp):
    1. using UnityEngine;
    2. using Valve.VR.InteractionSystem;
    3. using UnityEngine.Events;
    4.  
    5. public class ReturnHome : MonoBehaviour // AKA Remove from hand and store in set location
    6. {
    7.  
    8.     public GameObject[] SwitchObjectsOnPlacement;
    9.     public Collider[] SwitchCollidersOnPlacement;
    10.     public Animator[] ItemReturnedAnimations;
    11.     public string[] ReturnedAnimationStates;
    12.     public UnityEvent onPlacement;
    13.     //public GameObject AttachableObject;
    14.     public string ObjectName;
    15.     public Transform snapTo;
    16.     public float speed = 2;
    17.  
    18.     //Switch states and Animate if the user puts the Item in a set location.
    19.     private void OnTriggerEnter(Collider other)
    20.     {
    21.         if (other.gameObject.name.IndexOf(ObjectName) > -1)
    22.         {
    23.             if (SwitchObjectsOnPlacement.Length > 0)
    24.             {
    25.                 foreach (GameObject go in SwitchObjectsOnPlacement)
    26.                 {
    27.                     go.SetActive(!go.activeSelf);
    28.                 }
    29.  
    30.             }
    31.             if (SwitchCollidersOnPlacement.Length > 0)
    32.             {
    33.                 foreach (Collider c in SwitchCollidersOnPlacement)
    34.                 {
    35.                     c.enabled = !c.enabled;
    36.                 }
    37.             }
    38.             if (ItemReturnedAnimations.Length > 0 && ReturnedAnimationStates.Length > 0 && ReturnedAnimationStates.Length == ItemReturnedAnimations.Length)
    39.             {
    40.                 for (int i = 0; i < ItemReturnedAnimations.Length; i++)
    41.                 {
    42.                     ItemReturnedAnimations[i].Play(ReturnedAnimationStates[i]);
    43.                 }
    44.             }
    45.  
    46.             onPlacement.Invoke();
    47.  
    48.             // attach with LockToPoint Script on tagged object
    49.             other.gameObject.AddComponent<LockToPoint>();
    50.             other.gameObject.GetComponent<LockToPoint>().snapTo = snapTo;
    51.             other.gameObject.GetComponent<LockToPoint>().snapTime = speed;
    52.         }
    53.     }
    54. }
    The object would have a collider trigger that turns off when it is removed and activates a different collider trigger then the triggers would swap again when you replace the item. With snap speed you could make it smoothly return home or instantly snap into place.

    If that's not what you need try digging into the SteamVR samples and look at how the long bow is handled.
     
  7. enhox090

    enhox090

    Joined:
    Mar 24, 2021
    Posts:
    3
    Hi, I'm a newbie in VR and I'm looking forward to a method to pick up an object in one position and snap it in another place. I understand your code, but I don't know how to set it up in unity, so can you show me some pictures or something for example?
     
  8. Giantbean

    Giantbean

    Joined:
    Dec 13, 2012
    Posts:
    144
    This may not be relevant to new VR depending on what your using as this is old steam VR and not set up for OpenXR.
     
  9. enhox090

    enhox090

    Joined:
    Mar 24, 2021
    Posts:
    3
    I got it, thank you for your reply :))