【问题标题】:How to i get the location a vive motion cotroller is pointing to (in unity)如何获取 vive 运动控制器指向的位置(统一)
【发布时间】:2017-08-31 21:10:06
【问题描述】:

我想制作一个统一的 VR 游戏。我有这些基础知识,例如门、抽屉、枪和对象选择器上脚本。我想做一个基础构建器/编辑器,但我完全不知道如何获取控制器指向的位置(如激光笔) 该项目在c#中

【问题讨论】:

    标签: c# virtual-reality htc-vive


    【解决方案1】:

    您必须从控制器向对象进行光线投射。

    https://docs.unity3d.com/ScriptReference/Physics.Raycast.html

    为了简化您的工作,我建议您使用 VRTK 工具包,您可以简单地将其作为断言添加到您的统一项目中:https://vrtoolkit.readme.io/

    该工具包有很多功能,如激光点、抓取等。

    希望对你有帮助!

    编辑:

    这是来自 VRTK 工具包的激光指示器的一个很好的例子:

    using UnityEngine;
    using System.Collections;
    
    public class ViveCursor : MonoBehaviour
    {
        public enum AxisType
        {
            XAxis,
            ZAxis
        }
    
        public Color color;
        public float thickness = 0.002f;
        public AxisType facingAxis = AxisType.XAxis;
        public float length = 100f;
        public bool showCursor = true;
    
        GameObject holder;
        GameObject pointer;
        GameObject cursor;
    
        Vector3 cursorScale = new Vector3(0.05f, 0.05f, 0.05f);
        float contactDistance = 0f;
        Transform contactTarget = null;
    
        void SetPointerTransform(float setLength, float setThicknes)
        {
            //if the additional decimal isn't added then the beam position glitches
            float beamPosition = setLength / (2 + 0.00001f);
    
            if (facingAxis == AxisType.XAxis)
            {
                pointer.transform.localScale = new Vector3(setLength, setThicknes, setThicknes);
                pointer.transform.localPosition = new Vector3(beamPosition, 0f, 0f);
                if (showCursor)
                {
                    cursor.transform.localPosition = new Vector3(setLength - cursor.transform.localScale.x, 0f, 0f);
                }
            }
            else
            {
                pointer.transform.localScale = new Vector3(setThicknes, setThicknes, setLength);
                pointer.transform.localPosition = new Vector3(0f, 0f, beamPosition);
    
                if (showCursor)
                {
                    cursor.transform.localPosition = new Vector3(0f, 0f, setLength - cursor.transform.localScale.z);
                }
            }
        }
    
        // Use this for initialization
        void Start()
        {
            Material newMaterial = new Material(Shader.Find("Unlit/Color"));
            newMaterial.SetColor("_Color", color);
    
            holder = new GameObject();
            holder.transform.parent = this.transform;
            holder.transform.localPosition = Vector3.zero;
    
            pointer = GameObject.CreatePrimitive(PrimitiveType.Cube);
            pointer.transform.parent = holder.transform;
            pointer.GetComponent<MeshRenderer>().material = newMaterial;
    
            pointer.GetComponent<BoxCollider>().isTrigger = true;
            pointer.AddComponent<Rigidbody>().isKinematic = true;
            pointer.layer = 2;
    
            if (showCursor)
            {
                cursor = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                cursor.transform.parent = holder.transform;
                cursor.GetComponent<MeshRenderer>().material = newMaterial;
                cursor.transform.localScale = cursorScale;
    
                cursor.GetComponent<SphereCollider>().isTrigger = true;
                cursor.AddComponent<Rigidbody>().isKinematic = true;
                cursor.layer = 2;
            }
    
            SetPointerTransform(length, thickness);
        }
    
        float GetBeamLength(bool bHit, RaycastHit hit)
        {
            float actualLength = length;
    
            //reset if beam not hitting or hitting new target
            if (!bHit || (contactTarget && contactTarget != hit.transform))
            {
                contactDistance = 0f;
                contactTarget = null;
            }
    
            //check if beam has hit a new target
            if (bHit)
            {
                if (hit.distance <= 0)
                {
    
                }
                contactDistance = hit.distance;
                contactTarget = hit.transform;
            }
    
            //adjust beam length if something is blocking it
            if (bHit && contactDistance < length)
            {
                actualLength = contactDistance;
            }
    
            if (actualLength <= 0)
            {
                actualLength = length;
            }
    
            return actualLength; ;
        }
    
        void Update()
        {
            Ray raycast = new Ray(transform.position, transform.forward);
    
            RaycastHit hitObject;
            bool rayHit = Physics.Raycast(raycast, out hitObject);
    
            float beamLength = GetBeamLength(rayHit, hitObject);
            SetPointerTransform(beamLength, thickness);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-08
      相关资源
      最近更新 更多