2017-09-30 1 views
0

Ich versuche, ein Getriebe VR-Anwendung mit dem Getriebe VR-Controller und dem Oculus SDK zu machen. Ich habe die GazePointerRing mit dem Controller-Prefab arbeiten. Es ist ein Absehen in meiner App sichtbar, dass ich mich mit dem Gear VR Controller bewegen kann. Es erkennt die Würfel, die ich in der Szene platziert habe. Was ich jetzt tun möchte, ist das Absehen bei einem Würfel zeigen und eine Taste auf dem Controller halten, so dass der Würfel auf mein Controller-Modell bleiben wird und können sich frei bewegen, bis ich gehen die Taste loslassen. Ich habe im OVR Physics Raycaster-Skript gesucht, wie ich den Raycast-Treffer aufrufen und ihn in einem Button-Befehl in einer if-Anweisung eingeben kann. Aber ich kann keinen Weg finden, den Raycast-Hit mit einem Objekt aufzurufen. Dies ist der Oculus-Code in der OVR Physik Raycaster Skript:Verschieben eines Würfels mit dem Zahnrad-VR-Controller in Unity

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); 
    } 
} 
} 

Antwort

0

Voraussetzung: Stellen Sie sicher, OVR-Manager in der Szene zu haben, ist es ein Singleton und die für die GearVR Controller (OVRInput Klasse) zu arbeiten.

Mein üblicher Ansatz ist es, einen Strahl von der Steuerung Ankerposition Raycast geht nach vorn und überprüfen, ob es um ein gewünschtes Objekt trifft

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

ich die OVRManager in meiner Szene bekam. Danke, dass Sie Ihren Raycast-Ansatz teilen, es sieht so klar aus. Ich denke, dass ich weiter damit arbeiten kann, werde versuchen, das jetzt zu implementieren. –

+0

Hallo, noch ein paar Fragen zu deinem Ansatz zum Raycast-Skript. 1. Der Gameobject detectionline ist, dass der Controller, den Sie mit oder Ziel sind, ist, dass ein Gameobject Sie wollen interagieren? 2. Was ist der Zweck des Codes: MyComponent target = _hitInfo.collider.gameObject.GetComponent (); Und was sollte MyComponent sein? Wie zum Beispiel verschieben Sie einen Würfel an eine andere Position, indem Sie darauf zeigen, was sollte MyComponent sein? –

Verwandte Themen