2017-09-30 37 views
0

Gear VR 컨트롤러와 Oculus SDK로 Gear VR 어플리케이션을 만들려고합니다. GazePointerRing을 컨트롤러 프리 패브와 함께 사용할 수 있습니다. 내 앱에는 레티클이있어 Gear VR 컨트롤러로 이동할 수 있습니다. 그것은 내가 장면에 넣은 큐브를 감지합니다. 지금 내가하고 싶은 것은 큐브의 레티클을 가리키고 컨트롤러의 버튼을 누르고 있기 때문에 큐브가 컨트롤러 모델을 고수하고 버튼을 놓을 때까지 이동할 수 있습니다. 나는 OVR Physics Raycaster 스크립트에서 raycast 히트를 호출하고 if 명령문에서 버튼 명령으로 입력 할 수있는 방법을 찾고있었습니다. 하지만 개체를 ​​사용하여 레이 캐스트를 요청하는 방법을 찾을 수 없습니다. 이것은 OVR 물리학 Raycaster 스크립트의 마력 코드는 다음과 같습니다Unity의 Gear VR 컨트롤러로 큐브 이동하기

using System.Collections.Generic; 

namespace UnityEngine.EventSystems 
{ 
    /// <summary> 
    /// Simple event system using physics raycasts. 
    /// </summary> 
    [RequireComponent(typeof(OVRCameraRig))] 
    public class OVRPhysicsRaycaster : BaseRaycaster 
    { 
     /// <summary> 
     /// Const to use for clarity when no event mask is set 
     /// </summary> 
     protected const int kNoEventMaskSet = -1; 


    /// <summary> 
    /// Layer mask used to filter events. Always combined with the camera's culling mask if a camera is used. 
    /// </summary> 
    [SerializeField] 
    public LayerMask m_EventMask = kNoEventMaskSet; 

    protected OVRPhysicsRaycaster() 
    { } 

    public override Camera eventCamera 
    { 
     get 
     { 
      return GetComponent<OVRCameraRig>().leftEyeCamera; 
     } 
    } 

    /// <summary> 
    /// Depth used to determine the order of event processing. 
    /// </summary> 
    public virtual int depth 
    { 
     get { return (eventCamera != null) ? (int)eventCamera.depth : 0xFFFFFF; } 
    } 

    /// <summary> 
    /// Event mask used to determine which objects will receive events. 
    /// </summary> 
    public int finalEventMask 
    { 
     get { return (eventCamera != null) ? eventCamera.cullingMask & m_EventMask : kNoEventMaskSet; } 
    } 

    /// <summary> 
    /// Layer mask used to filter events. Always combined with the camera's culling mask if a camera is used. 
    /// </summary> 
    public LayerMask eventMask 
    { 
     get { return m_EventMask; } 
     set { m_EventMask = value; } 
    } 


    /// <summary> 
    /// Perform a raycast using the worldSpaceRay in eventData. 
    /// </summary> 
    /// <param name="eventData"></param> 
    /// <param name="resultAppendList"></param> 
    public override void Raycast(PointerEventData eventData, List<RaycastResult> resultAppendList) 
    { 
     // This function is closely based on PhysicsRaycaster.Raycast 

     if (eventCamera == null) 
      return; 

     OVRRayPointerEventData rayPointerEventData = eventData as OVRRayPointerEventData; 
     if (rayPointerEventData == null) 
      return; 

     var ray = rayPointerEventData.worldSpaceRay; 

     float dist = eventCamera.farClipPlane - eventCamera.nearClipPlane; 

     var hits = Physics.RaycastAll(ray, dist, finalEventMask); 

     if (hits.Length > 1) 
      System.Array.Sort(hits, (r1, r2) => r1.distance.CompareTo(r2.distance)); 

     if (hits.Length != 0) 
     { 
      for (int b = 0, bmax = hits.Length; b < bmax; ++b) 
      { 
       var result = new RaycastResult 
       { 
        gameObject = hits[b].collider.gameObject, 
        module = this, 
        distance = hits[b].distance, 
        index = resultAppendList.Count, 
        worldPosition = hits[0].point, 
        worldNormal = hits[0].normal, 
       }; 
       resultAppendList.Add(result); 
      } 
     } 
    } 

    /// <summary> 
    /// Perform a Spherecast using the worldSpaceRay in eventData. 
    /// </summary> 
    /// <param name="eventData"></param> 
    /// <param name="resultAppendList"></param> 
    /// <param name="radius">Radius of the sphere</param> 
    public void Spherecast(PointerEventData eventData, List<RaycastResult> resultAppendList, float radius) 
    { 
     if (eventCamera == null) 
      return; 

     OVRRayPointerEventData rayPointerEventData = eventData as OVRRayPointerEventData; 
     if (rayPointerEventData == null) 
      return; 

     var ray = rayPointerEventData.worldSpaceRay; 

     float dist = eventCamera.farClipPlane - eventCamera.nearClipPlane; 

     var hits = Physics.SphereCastAll(ray, radius, dist, finalEventMask); 

     if (hits.Length > 1) 
      System.Array.Sort(hits, (r1, r2) => r1.distance.CompareTo(r2.distance)); 

     if (hits.Length != 0) 
     { 
      for (int b = 0, bmax = hits.Length; b < bmax; ++b) 
      { 
       var result = new RaycastResult 
       { 
        gameObject = hits[b].collider.gameObject, 
        module = this, 
        distance = hits[b].distance, 
        index = resultAppendList.Count, 
        worldPosition = hits[0].point, 
        worldNormal = hits[0].normal, 
       }; 
       resultAppendList.Add(result); 
      } 
     } 
    } 
    /// <summary> 
    /// Get screen position of this world position as seen by the event camera of this OVRPhysicsRaycaster 
    /// </summary> 
    /// <param name="worldPosition"></param> 
    /// <returns></returns> 
    public Vector2 GetScreenPos(Vector3 worldPosition) 
    { 
     // In future versions of Uinty RaycastResult will contain screenPosition so this will not be necessary 
     return eventCamera.WorldToScreenPoint(worldPosition); 
    } 
} 
} 

답변

0

전제 조건 : 장면에 OVR 관리자를 가지고 있는지 확인, 작동하는 싱글과 GearVR 컨트롤러에 필요한 (OVRInput 클래스)입니다. 그것이 내가 내 장면에 OVRManager있어 원하는 객체

public class SampleScript : MonoBehaviour 
{ 
    public Transform anchorPos; 
    public GameObject detectionLineObject; // a gameObject with a line renderer 

    private RaycastHit _hitInfo; 
    private LineRenderer _detectionLine; 

    void Start() 
    { 
     GameObject line = Instantiate(detectionLineObject); 
     _detectionLine = line.GetComponent<LineRenderer>(); 
    } 

    void Update() 
    { 
     DetectionManager(); 
    } 

    void DetectionManager() 
    { 
     // check if controller is actually connected 
     if (!OVRInput.IsControllerConnected(OVRInput.Controller.RTrackedRemote) || !OVRInput.IsControllerConnected(OVRInput.Controller.LTrackedRemote)) 
     { 
      return; 
     } 
     // launch a ray from the OVRCameraRig's Anchor Right 
     if (Physics.Raycast(anchorPos.position, anchorPos.forward, out _hitInfo)) 
     { 
      // set our line points 
      _detectionLine.SetPosition(0, anchorPos.position); 
      _detectionLine.SetPosition(1, _hitInfo.point); 

      MyComponent target = _hitInfo.collider.gameObject.GetComponent<MyComponent>(); 

      if (target != null) 
      { 
       // Do you stuff here 
       target.StartInteraction(); 
      } 
     } 
     else 
     { 

      // point our line to infinity 
      _detectionLine.SetPosition(0, anchorPos.position); 
      _detectionLine.SetPosition(1, anchorPos.forward * 500.0f); 
     } 
    } 
} 
+0

에게 안타

내 일반적인 접근 방식은 향후 컨트롤러 앵커 위치에서 선을 레이 캐스트하고 확인하는 것입니다. raycast 접근법을 공유해 주셔서 감사합니다. 나는 그걸로 더 일할 수 있다고 생각합니다. 지금 구현하려고합니다. –

+0

안녕하세요. 레이 캐스트 스크립트에 대한 접근 방식에 대해 다시 한 번 질문드립니다. 1. 게임 개체 감지 라인은 목표로 삼고있는 컨트롤러이거나 게임 개체와 상호 작용할 대상입니까? 2. 코드 목적 : MyComponent target = _hitInfo.collider.gameObject.GetComponent (); 그리고 MyComponent는 무엇이되어야합니까? 예를 들어 큐브를 다른 위치로 이동시키는 것과 마찬가지로 MyComponent는 무엇이되어야합니까? –