07-10-2017 05:41 AM
07-12-2017 08:15 PM
Transform rightHandAnchor; // Assign to the proper transform
Ray pointer = new Ray (rightHandAnchor.position, rightHandAnchor.forward);
lineRenderer.SetPosition (0, pointer.origin);
lineRenderer.SetPosition (1, pointer.origin + pointer.direction * 500.0f);
using UnityEngine;
using UnityEngine.Events;
public class VRRaycaster : MonoBehaviour {
[System.Serializable]
public class Callback : UnityEvent<Ray, RaycastHit> {}
public Transform leftHandAnchor = null;
public Transform rightHandAnchor = null;
public Transform centerEyeAnchor = null;
public LineRenderer lineRenderer = null;
public float maxRayDistance = 500.0f;
public LayerMask excludeLayers;
public VRRaycaster.Callback raycastHitCallback;
void Awake() {
if (leftHandAnchor == null) {
Debug.LogWarning ("Assign LeftHandAnchor in the inspector!");
GameObject left = GameObject.Find ("LeftHandAnchor");
if (left != null) {
leftHandAnchor = left.transform;
}
}
if (rightHandAnchor == null) {
Debug.LogWarning ("Assign RightHandAnchor in the inspector!");
GameObject right = GameObject.Find ("RightHandAnchor");
if (right != null) {
rightHandAnchor = right.transform;
}
}
if (centerEyeAnchor == null) {
Debug.LogWarning ("Assign CenterEyeAnchor in the inspector!");
GameObject center = GameObject.Find ("CenterEyeAnchor");
if (center != null) {
centerEyeAnchor = center.transform;
}
}
if (lineRenderer == null) {
Debug.LogWarning ("Assign a line renderer in the inspector!");
lineRenderer = gameObject.AddComponent<LineRenderer> ();
lineRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
lineRenderer.receiveShadows = false;
lineRenderer.widthMultiplier = 0.02f;
}
}
Transform Pointer {
get {
OVRInput.Controller controller = OVRInput.GetConnectedControllers ();
if ((controller & OVRInput.Controller.LTrackedRemote) != OVRInput.Controller.None) {
return leftHandAnchor;
} else if ((controller & OVRInput.Controller.RTrackedRemote) != OVRInput.Controller.None) {
return rightHandAnchor;
}
// If no controllers are connected, we use ray from the view camera.
// This looks super ackward! Should probably fall back to a simple reticle!
return centerEyeAnchor;
}
}
void Update() {
Transform pointer = Pointer;
if (pointer == null) {
return;
}
Ray laserPointer = new Ray (pointer.position, pointer.forward);
if (lineRenderer != null) {
lineRenderer.SetPosition (0, laserPointer.origin);
lineRenderer.SetPosition (1, laserPointer.origin + laserPointer.direction * maxRayDistance);
}
RaycastHit hit;
if (Physics.Raycast (laserPointer, out hit, maxRayDistance, ~excludeLayers)) {
if (lineRenderer != null) {
lineRenderer.SetPosition (1, hit.point);
}
if (raycastHitCallback != null) {
raycastHitCallback.Invoke (laserPointer, hit);
}
}
}
}
07-13-2017 09:53 AM
07-24-2017 06:58 AM
oculus_gabor said:
There is some documentation relating to this in the works. Be on the lookout for that. In the mean time i can give you a quick and easy way to achieve this effect.First tough, Gear VR lets a user select if a controller is left handed or right handed. To support this, you need to drag a copy of GearVRController as a child of LeftHandAnchor as well. When you do this, look at the GearVRController instance. It has a OVRGearVRController script attached. This script has a dropdown for controller type. Select R Tracked Remote and L Tracked Remote for left and right controllers. The OVRGearVRController script will automatically show / hide the appropriate controller prefab.Since you have the LeftHandAnchor and RightHandAnchor transforms, you can use either one of those to create a ray. A ray needs only a position and a forward vector:
Transform rightHandAnchor; // Assign to the proper transformRay pointer = new Ray (rightHandAnchor.position, rightHandAnchor.forward);You can now use this to do ray-casts! You can render a selection ray with unity's built in LineRenderer. Make sure the line renderer has at least two points (world space) and set them in an Update method to match the pointer.lineRenderer.SetPosition (0, pointer.origin);
lineRenderer.SetPosition (1, pointer.origin + pointer.direction * 500.0f);One more thing you might want to keep in mind, a Gear VR is not guaranteed to have a controller paired. If this happens to be the case, you want to fall back on gaze controls.I wrote a simple script to demonstrate this. Attach it to OVRCameraRig and you should be good to go.using UnityEngine;
using UnityEngine.Events;
public class VRRaycaster : MonoBehaviour {
[System.Serializable]
public class Callback : UnityEvent<Ray, RaycastHit> {}
public Transform leftHandAnchor = null;
public Transform rightHandAnchor = null;
public Transform centerEyeAnchor = null;
public LineRenderer lineRenderer = null;
public float maxRayDistance = 500.0f;
public LayerMask excludeLayers;
public VRRaycaster.Callback raycastHitCallback;
void Awake() {
if (leftHandAnchor == null) {
Debug.LogWarning ("Assign LeftHandAnchor in the inspector!");
GameObject left = GameObject.Find ("LeftHandAnchor");
if (left != null) {
leftHandAnchor = left.transform;
}
}
if (rightHandAnchor == null) {
Debug.LogWarning ("Assign RightHandAnchor in the inspector!");
GameObject right = GameObject.Find ("RightHandAnchor");
if (right != null) {
rightHandAnchor = right.transform;
}
}
if (centerEyeAnchor == null) {
Debug.LogWarning ("Assign CenterEyeAnchor in the inspector!");
GameObject center = GameObject.Find ("CenterEyeAnchor");
if (center != null) {
centerEyeAnchor = center.transform;
}
}
if (lineRenderer == null) {
Debug.LogWarning ("Assign a line renderer in the inspector!");
lineRenderer = gameObject.AddComponent<LineRenderer> ();
lineRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
lineRenderer.receiveShadows = false;
lineRenderer.widthMultiplier = 0.02f;
}
}
Transform Pointer {
get {
OVRInput.Controller controller = OVRInput.GetConnectedControllers ();
if ((controller & OVRInput.Controller.LTrackedRemote) != OVRInput.Controller.None) {
return leftHandAnchor;
} else if ((controller & OVRInput.Controller.RTrackedRemote) != OVRInput.Controller.None) {
return rightHandAnchor;
}
// If no controllers are connected, we use ray from the view camera.
// This looks super ackward! Should probably fall back to a simple reticle!
return centerEyeAnchor;
}
}
void Update() {
Transform pointer = Pointer;
if (pointer == null) {
return;
}
Ray laserPointer = new Ray (pointer.position, pointer.forward);
if (lineRenderer != null) {
lineRenderer.SetPosition (0, laserPointer.origin);
lineRenderer.SetPosition (1, laserPointer.origin + laserPointer.direction * maxRayDistance);
}
RaycastHit hit;
if (Physics.Raycast (laserPointer, out hit, maxRayDistance, ~excludeLayers)) {
if (lineRenderer != null) {
lineRenderer.SetPosition (1, hit.point);
}
if (raycastHitCallback != null) {
raycastHitCallback.Invoke (laserPointer, hit);
}
}
}
}
07-28-2017 02:49 PM
leftData.worldSpaceRay = new Ray (rayTransform.position, rayTransform.forward);
You need to replace leftData.worldSpaceRay with the pick ray of the controller. Once you do that this should be a drag and drop solution. You might want to do something like:That way you have support for Gear VR Controller picking rays, and gaze rays when no controller is presentif (controllerIsPresent && VRRaycaster.Instance != null) {
VRRaycaster.Instance.PickRay;
leftData.worldSpaceRay =
}
else {
leftData.worldSpaceRay = new Ray(rayTransform.position, rayTransform.forward);
}
12-03-2017 12:39 AM
12-03-2017 12:41 AM
using UnityEngine;using UnityEngine.Events;public class VRRaycaster : MonoBehaviour{[System.Serializable]public class Callback : UnityEvent<Ray, RaycastHit> { }[SerializeField] TransformleftHandAnchor = null,rightHandAnchor = null,centerEyeAnchor = null;public float maxRayDistance = 500.0f;public LayerMask excludeLayers;public VRRaycaster.Callback raycastHitCallback;Transform pointer;OVRInput.Controller controller;LineRenderer lineRenderer = null;Ray laserPointer;RaycastHit hit;void Assign( ref Transform var, string parent ){if (null == var)var = GameObject.Find( parent )?.transform ?? null ;}void Awake(){Assign( ref leftHandAnchor, "LeftHandAnchor" );Assign( ref rightHandAnchor, "RightHandAnchor" );Assign( ref centerEyeAnchor, "CenterEyeAnchor" );lineRenderer = gameObject.AddComponent<LineRenderer>();lineRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;lineRenderer.receiveShadows = false;lineRenderer.widthMultiplier = 0.02f;}bool LeftTouch => ( controller & OVRInput.Controller.LTouch ) != OVRInput.Controller.None;bool RightTouch => ( controller & OVRInput.Controller.RTouch ) != OVRInput.Controller.None;bool LeftControl => ( controller & OVRInput.Controller.LTrackedRemote ) != OVRInput.Controller.None;bool RightControl => ( controller & OVRInput.Controller.RTrackedRemote ) != OVRInput.Controller.None;Transform Pointer{get{if ( RightControl || RightTouch ) return rightHandAnchor;if ( LeftControl || LeftTouch ) return leftHandAnchor;// If no controllers are connected, we use ray from the view camera.// This looks super ackward! Should probably fall back to a simple reticle!return centerEyeAnchor;}}private void OnGUI(){GUILayout.Label( "Controller: " + controller );GUILayout.Label( "Left: " + ( LeftTouch ? "True" : "False") );GUILayout.Label( "Right: " + ( RightTouch ? "True" : "False" ) );}void Update(){controller = OVRInput.GetConnectedControllers();pointer = Pointer;if ( pointer == null )return;laserPointer = new Ray( pointer.position, pointer.forward );lineRenderer.SetPosition( 0, laserPointer.origin );lineRenderer.SetPosition( 1, laserPointer.origin + laserPointer.direction * maxRayDistance );if ( Physics.Raycast( laserPointer, out hit, maxRayDistance, ~excludeLayers ) ){lineRenderer.SetPosition( 1, hit.point );raycastHitCallback?.Invoke( laserPointer, hit );}}}
12-04-2017 02:23 AM
12-05-2017 09:27 AM
oculus_gabor said:
Hi @myBadStudiosSorry to hear your frustration. My posts are aimed mostly at mobile, i tend not to check them against rift for functionality. From now on i'll try to make sure my posts are compatible with both. If i have time in the future, i'll even go back and update the blog posts where possible.Anyway, i've attached a unity project to this post. This project contains the minimal code needed for a controller that can interact with both UI and non UI objects.The project works on both Gear and Rift. The selection ray will come from the controller whos trigger was last pulled. Everything should be configured in the sample scene.Below is a pretty (low quality) gif of what the attached project looks like. Let me know if you have any questions!~Gabor
12-06-2017 03:34 PM