-
Notifications
You must be signed in to change notification settings - Fork 125
Make controllers for both Unity XR and WebVR #295
Conversation
private FixedJoint attachJoint = null; | ||
private Rigidbody currentRigidBody = null; | ||
private List<Rigidbody> contactRigidBodies = new List<Rigidbody> (); | ||
|
||
void Awake() | ||
{ | ||
controllerManager = WebVRControllerManager.Instance; | ||
//controllerManager = WebVRControllerManager.Instance; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops, will remove this.
{ | ||
#if UNITY_EDITOR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually, this might be better as !UNITY_WEBGL
since XR can be used outside of UNITY_EDITOR
as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, good call 👍 can you change this? as well as in GetButton
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add a comment explaining the #if
/#else
/#endif
block?
|
||
void Update() | ||
{ | ||
#if UNITY_EDITOR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix casing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above, can you fix? and also can you add a comment explaining the conditional logic? thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great work - refactor looking good!
on both master
and on this branch, I tested the following:
- Oculus Rift with Touch controllers in Unity's XR preview mode
- Oculus Rift with Touch controllers in WebVR in Firefox for Windows
- HTC Vive with controllers in Unity's XR preview mode
- HTC Vive with controllers in WebVR in Firefox for Windows
in the Vive, my right-hand controller could not pick up objects. both hands appeared correctly, and I was able to pick up the interactable objects with my left hand. but my right hand did not work in Unity's XR preview mode. surprisingly or not, my right hand (and left hand) did work in WebVR in Firefox for Windows. (I'm not sure if this is an Oculus vs. OpenVR bug, or whether it's reproducible with Oculus as well. I encountered some problematic tracking issues with my Oculus Rift that seemed unrelated to your patch/this project, so I was unable to grab objects to test if Oculus is also affected.)
👍 fantastic progress here. this makes development easy breezy. I can't believe how simple it is now to develop whilst testing in VR and rapidly making adjustments.
{ | ||
[Tooltip("Map GameObject to controller hand name.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you change this to Hand of controller to map to.
(or something succincter, of course)?
{ | ||
[Tooltip("Map GameObject to controller hand name.")] | ||
public WebVRControllerHand hand = WebVRControllerHand.NONE; | ||
[Tooltip("Controller Input settings")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Controller input settings.
(including the trailing period)
public int index; | ||
public Enum hand; | ||
[HideInInspector] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 good call
|
||
private Dictionary<WebVRInputAction, bool[]> buttonStates = new Dictionary<WebVRInputAction, bool[]>(); | ||
private Dictionary<string, bool[]> buttonStates = new Dictionary<string, bool[]>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 this is probably better to use native string
s than the WebVRInputAction
interface
if (i == (int)action) { | ||
if (buttonStates.ContainsKey(action)) | ||
buttonStates[action][0] = button.pressed; | ||
if (input.gamepadId == i) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if a gamepad is removed and/or added, gamepadId
can be guaranteed to reflect the same Gamepad
object as the one that was initially detected? (I'm pretty sure Gecko and Chromium handle this properly, but I haven't checked all the implementations.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I messed this one up. This should be gamepadButtonId
, not gamepadId
.
|
||
[CreateAssetMenu(menuName = "WebVRControllerInputSettings")] | ||
public class WebVRControllerInputSettings : ScriptableObject { | ||
[Header("WebVR Controller Input Settings")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: do we need to say WebVR
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just want to be clear since there are two different input systems in use here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following my former comments, we should change this to: WebVR Input Map
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, WebVR Input Map
is clearer.
|
||
[System.Serializable] | ||
public class WebVRControllerInput { | ||
public string actionName; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add [Tooltip(…)]
s or helpful descriptions?
} | ||
|
||
private void onControllerUpdate( | ||
int index, string h, Vector3 position, Quaternion rotation, Matrix4x4 sitStand, WebVRControllerButton[] b) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where is index
used here?
private void onControllerUpdate( | ||
int index, string h, Vector3 position, Quaternion rotation, Matrix4x4 sitStand, WebVRControllerButton[] b) | ||
{ | ||
// convert string to enum |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would it be possible to just pass in the enum instead of passing and parsing the string on every call?
int index, string h, Vector3 position, Quaternion rotation, Matrix4x4 sitStand, WebVRControllerButton[] b) | ||
{ | ||
// convert string to enum | ||
WebVRControllerHand updateHand; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wherever you decide to keep this string-to-enum parsing, could you do something like this to catch any possible enum-parsing errors?
WebVRControllerHand updateHand = WebVRControllerHand.NONE;
if (!String.IsNullOrEmpty(h)) {
try {
updateHand = (WebVRControllerHand) Enum.Parse(typeof(WebVRControllerHand), h.ToUpper(), true);
}
catch {
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
update: it looks like you can use Enum.TryParse
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TryParse doesn't work with Unity apparently: https://answers.unity.com/questions/830527/enumtryparse-method-not-support.html
2a70a6c
to
20703e3
Compare
@cvan ready for another review, fixed review issues + nits. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
grabbing objects with the right controller now works now. 👍
great work! I tested with both Rift and Vive in both Unity's XR player and WebVR-exported builds in Firefox. ship it! 🚢
P.S. see my comment about the changed default camera position in non-VR mode. also, we should address the varying camera positions in Oculus and in Windows Mixed Reality.
@@ -515,6 +515,7 @@ GameObject: | |||
- component: {fileID: 54027100335586508} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
something in here caused the default camera position to be different (compare it to the position in master
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cvan hm. not sure I understand. Only when entering VR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
regarding the default camera position. It's the transform that the browser supplies. Not sure if there is anything that we need to do specifically to accommodate different devices, but I suspect this may be an issue with WebVR with Edge. Will need to do some testing.
I will give it a check with the Samsung HMD.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay, I just filed issue #303 to track this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super nice job @caseyyee ! This is great, we should provide full mappings for not only the trigger and grip but including all the buttons but is a great enhancement.
Please, make the changes I've requested you and feel free to discuss. Although the ease of use is mainly provided by the default mappings, we should make super clear that the user understand what is she doing.
Another thing, there is a Input
folder inside the script. Do you mind to move the controller-related scripts inside that folder?
@@ -81,13 +113,56 @@ public bool GetButtonUp(WebVRInputAction action) | |||
return isUp; | |||
} | |||
|
|||
public WebVRController(int index, Enum hand, Vector3 position, Quaternion rotation, Matrix4x4 sitStand) | |||
private void onControllerUpdate( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Public names should be in UpperCamelCase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's internal. The public function is on the WebVRManager.
@@ -81,13 +113,56 @@ public bool GetButtonUp(WebVRInputAction action) | |||
return isUp; | |||
} | |||
|
|||
public WebVRController(int index, Enum hand, Vector3 position, Quaternion rotation, Matrix4x4 sitStand) | |||
private void onControllerUpdate( | |||
int index, string h, Vector3 position, Quaternion rotation, Matrix4x4 sitStand, WebVRControllerButton[] b) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is h
? Can you provide a more meaningful name here?
private void onControllerUpdate( | ||
int index, string h, Vector3 position, Quaternion rotation, Matrix4x4 sitStand, WebVRControllerButton[] b) | ||
{ | ||
// convert string to enum |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extract this into a meaningful function handFromString()
and remove the comment.
handValue = (WebVRControllerHand) Enum.Parse(typeof(WebVRControllerHand), h.ToUpper(), true); | ||
} | ||
catch | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At least, we should show a warning explaining what happened, hinting ourselves about how to solve the problem.
@@ -81,13 +113,56 @@ public bool GetButtonUp(WebVRInputAction action) | |||
return isUp; | |||
} | |||
|
|||
public WebVRController(int index, Enum hand, Vector3 position, Quaternion rotation, Matrix4x4 sitStand) | |||
private void onControllerUpdate( | |||
int index, string h, Vector3 position, Quaternion rotation, Matrix4x4 sitStand, WebVRControllerButton[] b) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, provide a meaningful name for the b
parameter.
using UnityEngine; | ||
|
||
[CreateAssetMenu(menuName = "WebVRControllerInputSettings")] | ||
public class WebVRControllerInputSettings : ScriptableObject { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
|
||
[CreateAssetMenu(menuName = "WebVRControllerInputSettings")] | ||
public class WebVRControllerInputSettings : ScriptableObject { | ||
[Header("WebVR Controller Input Settings")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following my former comments, we should change this to: WebVR Input Map
.
} | ||
|
||
[System.Serializable] | ||
public class WebVRControllerInput { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following the naming from before, the former is the map containing individual mappings so this should be WebVRInputMapping
. I'm not enforcing these names but try to make clear that these structures are mapping to different sources (the one from the Unity Input System and the one coming from the Web platform) to a common name. Clever idea and very nice from your side to provide some defaults but let make it super-clear.
|
||
[System.Serializable] | ||
public class WebVRControllerInput { | ||
[Tooltip("Name of input action to be performed.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since these are tooltips, I would say for this: A meaningful name describing the gesture performed on the controller
.
public class WebVRControllerInput { | ||
[Tooltip("Name of input action to be performed.")] | ||
public string actionName; | ||
[Tooltip("WebVR Gamepad button ID.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather say: Button ID coming from Web Gamepad API
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@caseyyee let me know when you've addressed @delapuente's review feedback (excellent comments, btw 👍). and I can take another look, test it, and we can merge this. let me know if you're stuck on anything or need a hand. otherwise, this looks very close to ready. great work, @caseyyee! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
almost there!
two issues:
- I cannot pick up objects anymore (seems to be a regression, but it seems fixed somewhat in your follow-up PR Cross platform controller support for Unity XR and WebVR. #306)
- the starting camera position in the Rift (regardless of the order of OpenVR vs. Oculus in Unity's XR Settings) starts below the desk
looking good 👍 let me know what else you'd like me to test
@@ -515,6 +515,7 @@ GameObject: | |||
- component: {fileID: 54027100335586508} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Closing in favor of #306. |
This PR adds the ability to map controller button and axis inputs to the appropriate Unity XR input and WebVR controller, depending on which context the project is running. Basically, it enables VR controllers to work between Unity and WebVR and fixes issue #233.
This involves change with how controllers work:
WebVRManager
and makesWebVRController
a component of controller GameObject. (This binding was done auto-magically previously, this is way more straightforward and easier to understand and work with).ControllerInteraction.cs
example):The
Trigger
action needs to be mapped to the appropriate Unity XR and WebVR controller inputs. To do this, we have aWebVRControllerInputSettings
scriptable object that is used to create a configuration.We bundle a basic configuration for Left and Right hand controllers:
LeftControllerMap
andRightControllerMap
respectively. You can make your own usingAssets > Create > WebVRControllerInputSettings
:For each action, we define a WebVR Controller button or axis ID and Unity Input definition. This is defined using Unity's Input Manager:
See Unity's XR Input docs https://docs.unity3d.com/Manual/OpenVRControllers.html to find the appropriate axis and button ID's to use. In this case, we want to use
Axis1D.PrimaryIndexTrigger
, which corresponds withjoystick button 14
.