2017-09-30 8 views
0

J'essaie de créer une application Gear VR avec le contrôleur Gear VR et le SDK Oculus. J'ai eu le GazePointerRing pour travailler avec le contrôleur préfabriqué. Il y a un réticule dans mon application visible que je peux me déplacer avec le contrôleur Gear VR. Il détecte les cubes que j'ai placés dans la scène. Ce que je veux faire maintenant, c'est pointer le réticule sur un cube et maintenir un bouton sur le contrôleur, afin que le cube colle à mon modèle de contrôleur et puisse bouger jusqu'à ce que je lâche le bouton. J'ai cherché dans le script OVR Physics Raycaster comment je peux appeler le hit raycast et l'entrer dans une commande de bouton dans une instruction if. Mais je ne peux pas trouver un moyen d'invoquer le hit raycast avec un objet. Ce est le code Oculus dans le script Physique OVR raycaster:Déplacement d'un cube avec le contrôleur Gear VR dans 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); 
    } 
} 
} 

Répondre

0

Pré-requis: Assurez-vous d'avoir OVR Manager dans votre scène, il est un singleton et nécessaire pour le contrôleur GearVR (classe OVRInput) au travail.

Mon approche habituelle est de raycast un rayon de la position d'ancrage du contrôleur aller de l'avant et vérifier si elle frappe un objet désiré

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

Je suis le OVRManager dans ma scène. Merci de partager votre approche de raycast, ça a l'air si clair. Je pense que je peux travailler plus loin avec ça, je vais essayer de l'implémenter maintenant. –

+0

Salut, juste quelques questions à propos de votre approche du script raycast. 1. La ligne de détection gameobject est celle avec laquelle vous visez ou est-ce un objet avec lequel vous voulez interagir? 2. Quel est le but du code: MyComponent target = _hitInfo.collider.gameObject.GetComponent (); Et que devrait être MyComponent? Comme par exemple déplacer un cube vers une position différente en le pointant dessus, que devrait être MyComponent? –