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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Question Best Method to create a Holster

Discussion in 'XR Interaction Toolkit and Input' started by nrvllrgrs, Jun 20, 2022.

  1. nrvllrgrs

    nrvllrgrs

    Joined:
    Jan 12, 2010
    Posts:
    59
    I'm trying to create a holster. It seems to be something between an XRInteractableObject and XRSocketInteractor.
    • Normally, the item is equipped and visible in the holster (socket)
    • The player can grab the item from the holster (socket)
    • If the player grabs the empty holster, then the item will snap to that interactor (interactable)
    What is the best practice for creating a holster using the framework.
     
  2. acasta

    acasta

    Joined:
    Feb 10, 2018
    Posts:
    8
    Hello, I had a similar question yesterday, and I've created a fairly clean solution so far. However I'm not sure it covers your last point.
    Can you explain that function a bit further?

    Here is what I've created so far. Right now it's just tracking/moving the waist (which the holsters are children of) based on the XR camera position & rotation, but I'm planning to add more positions to be tracked (i.e. over shoulder, chest etc).

    upload_2022-6-22_9-31-56.png
    upload_2022-6-22_9-32-26.png

    Code (CSharp):
    1. public class HolsterPositioning : MonoBehaviour
    2. {
    3.     [SerializeField] Transform XRCameraTransform;
    4.  
    5.     [SerializeField] GameObject waist;
    6.     [SerializeField] float waistOffsetHeight;
    7.  
    8.     [SerializeField] float[] lookDownPauseRotationRange = new float[2] { 45, 90 };
    9.  
    10.     // Update is called once per frame
    11.     void Update()
    12.     {
    13.         if (!CanSeeWaist()) UpdateWaistLocation();
    14.     }
    15.  
    16.     bool CanSeeWaist()
    17.     {
    18.         if (XRCameraTransform.eulerAngles.x > lookDownPauseRotationRange[0] && XRCameraTransform.eulerAngles.x < lookDownPauseRotationRange[1])
    19.         {
    20.             return true;
    21.         }
    22.         else return false;
    23.     }
    24.  
    25.     void UpdateWaistLocation ()
    26.     {
    27.         // Translate position to match camera X, Y - offset, Z
    28.         float newYPosition = Mathf.Clamp(XRCameraTransform.position.y - waistOffsetHeight, 0.1f, XRCameraTransform.position.y);
    29.         waist.transform.position = new Vector3(XRCameraTransform.position.x, newYPosition, XRCameraTransform.position.z);
    30.         // Rotate to match camera
    31.         waist.transform.eulerAngles = new Vector3(waist.transform.eulerAngles.x, XRCameraTransform.eulerAngles.y, waist.transform.eulerAngles.z);
    32.     }
    33. }
     

    Attached Files:

    Last edited: Jun 22, 2022
  3. nrvllrgrs

    nrvllrgrs

    Joined:
    Jan 12, 2010
    Posts:
    59
    I created XRHips to approximate the hip position.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class XRHips : MonoBehaviour
    4. {
    5.     #region Fields
    6.  
    7.     [SerializeField]
    8.     private float m_headOffset = -0.35f;
    9.  
    10.     [SerializeField]
    11.     private Transform m_head;
    12.  
    13.     #endregion
    14.  
    15.     #region Methods
    16.  
    17.     private void LateUpdate()
    18.     {
    19.         var forward = m_head.forward;
    20.  
    21.         var modForward = forward;
    22.         modForward.y = 0f;
    23.         modForward.Normalize();
    24.  
    25.         var modUp = m_head.up;
    26.         if (forward.y > 0f)
    27.         {
    28.             modUp = -modUp;
    29.         }
    30.         modUp.y = 0f;
    31.         modUp.Normalize();
    32.  
    33.         var dot = Mathf.Clamp01(Vector3.Dot(modForward, forward));
    34.         transform.SetPositionAndRotation(
    35.             m_head.position + m_headOffset * Vector3.up,
    36.             Quaternion.LookRotation(Vector3.Lerp(modUp, modForward, dot * dot), Vector3.up));
    37.     }
    38.  
    39.     #endregion
    40. }
    41.