Skip to content

Commit 0823d40

Browse files
authored
Merge pull request #61 from De-Panther/gamepad_haptic_support
Added Gamepad Haptic support
2 parents f1c293f + 17bb73a commit 0823d40

File tree

10 files changed

+90
-3
lines changed

10 files changed

+90
-3
lines changed

Assets/WebGLTemplates/WebXR/webxr.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
this.touchpadY = 0;
4141
this.buttonA = 0;
4242
this.buttonB = 0;
43+
this.gamepad = null;
4344
}
4445

4546
function XRHandData() {
@@ -170,6 +171,7 @@
170171
var onToggleVr = this.toggleVr.bind(this);
171172
var onUnityLoaded = this.unityLoaded.bind(this);
172173
var onToggleHitTest = this.toggleHitTest.bind(this);
174+
var onCallHapticPulse = this.hapticPulse.bind(this);
173175

174176
// dispatched by index.html
175177
document.addEventListener('UnityLoaded', onUnityLoaded, false);
@@ -178,6 +180,7 @@
178180
document.addEventListener('toggleVR', onToggleVr, false);
179181

180182
document.addEventListener('toggleHitTest', onToggleHitTest, false);
183+
document.addEventListener('callHapticPulse', onCallHapticPulse, false);
181184
}
182185

183186
XRManager.prototype.onRequestARSession = function () {
@@ -376,6 +379,24 @@
376379
}
377380
}
378381
}
382+
383+
XRManager.prototype.hapticPulse = function (hapticPulseAction) {
384+
let controller = null;
385+
switch(hapticPulseAction.detail.controller)
386+
{
387+
case 0:
388+
case 2:
389+
controller = this.xrData.controllerA;
390+
break;
391+
case 1:
392+
controller = this.xrData.controllerB;
393+
break;
394+
}
395+
if (controller && controller.enabled == 1 && controller.gamepad && controller.gamepad.hapticActuators && controller.gamepad.hapticActuators.length > 0)
396+
{
397+
controller.gamepad.hapticActuators[0].pulse(hapticPulseAction.detail.intensity, hapticPulseAction.detail.duration);
398+
}
399+
}
379400

380401
XRManager.prototype.setGameInstance = function (gameInstance) {
381402
if (!this.gameInstance) {
@@ -571,6 +592,7 @@
571592
}
572593
}
573594
}
595+
controller.gamepad = inputSource.gamepad;
574596

575597
if (hand == 0 || hand == 2) {
576598
xrData.controllerA = controller;

Assets/WebGLTemplates/WebXRFullView/webxr.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
this.touchpadY = 0;
4141
this.buttonA = 0;
4242
this.buttonB = 0;
43+
this.gamepad = null;
4344
}
4445

4546
function XRHandData() {
@@ -170,6 +171,7 @@
170171
var onToggleVr = this.toggleVr.bind(this);
171172
var onUnityLoaded = this.unityLoaded.bind(this);
172173
var onToggleHitTest = this.toggleHitTest.bind(this);
174+
var onCallHapticPulse = this.hapticPulse.bind(this);
173175

174176
// dispatched by index.html
175177
document.addEventListener('UnityLoaded', onUnityLoaded, false);
@@ -178,6 +180,7 @@
178180
document.addEventListener('toggleVR', onToggleVr, false);
179181

180182
document.addEventListener('toggleHitTest', onToggleHitTest, false);
183+
document.addEventListener('callHapticPulse', onCallHapticPulse, false);
181184
}
182185

183186
XRManager.prototype.onRequestARSession = function () {
@@ -376,6 +379,24 @@
376379
}
377380
}
378381
}
382+
383+
XRManager.prototype.hapticPulse = function (hapticPulseAction) {
384+
let controller = null;
385+
switch(hapticPulseAction.detail.controller)
386+
{
387+
case 0:
388+
case 2:
389+
controller = this.xrData.controllerA;
390+
break;
391+
case 1:
392+
controller = this.xrData.controllerB;
393+
break;
394+
}
395+
if (controller && controller.enabled == 1 && controller.gamepad && controller.gamepad.hapticActuators && controller.gamepad.hapticActuators.length > 0)
396+
{
397+
controller.gamepad.hapticActuators[0].pulse(hapticPulseAction.detail.intensity, hapticPulseAction.detail.duration);
398+
}
399+
}
379400

380401
XRManager.prototype.setGameInstance = function (gameInstance) {
381402
if (!this.gameInstance) {
@@ -571,6 +592,7 @@
571592
}
572593
}
573594
}
595+
controller.gamepad = inputSource.gamepad;
574596

575597
if (hand == 0 || hand == 2) {
576598
xrData.controllerA = controller;

Assets/WebXR/Plugins/WebGL/webxr.jslib

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ mergeInto(LibraryManager.library, {
2121
document.dispatchEvent(new CustomEvent('toggleHitTest', {}));
2222
},
2323

24+
ControllerPulse: function(controller, intensity, duration) {
25+
document.dispatchEvent(new CustomEvent('callHapticPulse', {detail: {'controller' : controller, 'intensity' : intensity, 'duration': duration}}));
26+
},
27+
2428
ListenWebXRData: function() {
2529
// Listen for headset updates from webxr.jspre and load data into shared Array which we pick up in Unity.
2630
document.addEventListener('XRData', function(evt) {

Assets/WebXR/Scripts/ControllerInteraction.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public class ControllerInteraction : MonoBehaviour
1010
private List<Rigidbody> contactRigidBodies = new List<Rigidbody>();
1111

1212
private Animator anim;
13+
private WebXRController controller;
1314

1415
void Awake()
1516
{
@@ -19,12 +20,11 @@ void Awake()
1920
void Start()
2021
{
2122
anim = gameObject.GetComponent<Animator>();
23+
controller = gameObject.GetComponent<WebXRController>();
2224
}
2325

2426
void Update()
2527
{
26-
WebXRController controller = gameObject.GetComponent<WebXRController>();
27-
2828
float normalizedTime = controller.GetButton("Trigger") ? 1 : controller.GetAxis("Grip");
2929

3030
if (controller.GetButtonDown("Trigger") || controller.GetButtonDown("Grip"))
@@ -43,6 +43,7 @@ void OnTriggerEnter(Collider other)
4343
return;
4444

4545
contactRigidBodies.Add(other.gameObject.GetComponent<Rigidbody>());
46+
controller.Pulse(0.5f, 250);
4647
}
4748

4849
void OnTriggerExit(Collider other)

Assets/WebXR/Scripts/WebXRController.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,12 @@ private void SetHandJointsVisible(bool visible)
265265
}
266266
}
267267

268+
// intensity 0 to 1, duration milliseconds
269+
public void Pulse(float intensity, float duration)
270+
{
271+
WebXRManager.Instance.HapticPulse(hand, intensity, duration);
272+
}
273+
268274
void OnEnable()
269275
{
270276
if (inputMap == null)

Assets/WebXR/Scripts/WebXRManager.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ public delegate void HeadsetUpdate(
6060
[DllImport("__Internal")]
6161
private static extern void ToggleViewerHitTest();
6262

63+
[DllImport("__Internal")]
64+
private static extern void ControllerPulse(int controller, float intensity, float duration);
65+
6366
[DllImport("__Internal")]
6467
private static extern void ListenWebXRData();
6568

@@ -213,6 +216,13 @@ public void StopViewerHitTest()
213216
}
214217
}
215218

219+
public void HapticPulse(WebXRControllerHand hand, float intensity, float duration)
220+
{
221+
#if UNITY_WEBGL && !UNITY_EDITOR
222+
ControllerPulse((int)hand, intensity, duration);
223+
#endif
224+
}
225+
216226
float[] GetMatrixFromSharedArray(int index)
217227
{
218228
float[] newArray = new float[16];

Build/Build/Build.data.unityweb

232 Bytes
Binary file not shown.

Build/Build/Build.wasm

298 Bytes
Binary file not shown.

Build/Build/Build.wasm.framework.unityweb

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

Build/webxr.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
this.touchpadY = 0;
4141
this.buttonA = 0;
4242
this.buttonB = 0;
43+
this.gamepad = null;
4344
}
4445

4546
function XRHandData() {
@@ -170,6 +171,7 @@
170171
var onToggleVr = this.toggleVr.bind(this);
171172
var onUnityLoaded = this.unityLoaded.bind(this);
172173
var onToggleHitTest = this.toggleHitTest.bind(this);
174+
var onCallHapticPulse = this.hapticPulse.bind(this);
173175

174176
// dispatched by index.html
175177
document.addEventListener('UnityLoaded', onUnityLoaded, false);
@@ -178,6 +180,7 @@
178180
document.addEventListener('toggleVR', onToggleVr, false);
179181

180182
document.addEventListener('toggleHitTest', onToggleHitTest, false);
183+
document.addEventListener('callHapticPulse', onCallHapticPulse, false);
181184
}
182185

183186
XRManager.prototype.onRequestARSession = function () {
@@ -376,6 +379,24 @@
376379
}
377380
}
378381
}
382+
383+
XRManager.prototype.hapticPulse = function (hapticPulseAction) {
384+
let controller = null;
385+
switch(hapticPulseAction.detail.controller)
386+
{
387+
case 0:
388+
case 2:
389+
controller = this.xrData.controllerA;
390+
break;
391+
case 1:
392+
controller = this.xrData.controllerB;
393+
break;
394+
}
395+
if (controller && controller.enabled == 1 && controller.gamepad && controller.gamepad.hapticActuators && controller.gamepad.hapticActuators.length > 0)
396+
{
397+
controller.gamepad.hapticActuators[0].pulse(hapticPulseAction.detail.intensity, hapticPulseAction.detail.duration);
398+
}
399+
}
379400

380401
XRManager.prototype.setGameInstance = function (gameInstance) {
381402
if (!this.gameInstance) {
@@ -571,6 +592,7 @@
571592
}
572593
}
573594
}
595+
controller.gamepad = inputSource.gamepad;
574596

575597
if (hand == 0 || hand == 2) {
576598
xrData.controllerA = controller;

0 commit comments

Comments
 (0)