Main idea to use browser GamePad API (Still not supported by Safary and not W3C standard) came from that I couldn't find way how to solve the problem recognizing wheel turning direction as Unity
static float GetAxisRaw(string axisName) return from full left to full right turn -1 to 1 to -1. So I couldn't find what is left and write. I'm dumb and hate Unity Ultimate InputManager tree control so I decided to call GamePad API thru Mono behaviour and SendMessage
I succeed on both Chrome and FF despite their GamePad API aren't the same.
public void HaveGamepadEvents() { Application.ExternalEval( "if('GamepadEvent' in window) UnityObject2.instances[0].getUnity().SendMessage('WebHIDBehaviourGO','onHaveGamepadEvents','1');" + "else UnityObject2.instances[0].getUnity().SendMessage('WebHIDBehaviourGO','onHaveGamepadEvents','0');" ); }
First have events and second need pool loop in order to track connecting/disconnecting of devices
if (hasGamepadEvents) { _hasEvents=true; Application.ExternalEval( // "window.addEventListener('gamepadconnected',function(e){ var buttons = []; for (var i = 0; i < e.gamepad.buttons.length; i++) buttons[i] = e.gamepad.buttons[i].value; UnityObject2.instances[0].getUnity().SendMessage('WebHIDBehaviourGO','onDeviceConnectedEvent',JSON.stringify({ id: e.gamepad.id, axes: e.gamepad.axes, buttons: buttons, index: e.gamepad.index }))});" + // "window.addEventListener('gamepaddisconnected',function(e){ UnityObject2.instances[0].getUnity().SendMessage('WebHIDBehaviourGO','onDeviceDisconnectedEvent',e.gamepad.index.toString())});" "window.addEventListener('gamepadconnected',function(e){ UnityObject2.instances[0].getUnity().SendMessage('WebHIDBehaviourGO','onDeviceConnectedEvent',JSON.stringify({ id: e.gamepad.id, numButtons:e.gamepad.buttons.length, numAxes:e.gamepad.axes.length, index: e.gamepad.index }))});" + "window.addEventListener('gamepaddisconnected',function(e){ UnityObject2.instances[0].getUnity().SendMessage('WebHIDBehaviourGO','onDeviceDisconnectedEvent',e.gamepad.id)});" ); } else//manuall check { Timer enumeratorTimer = new Timer(1000); enumeratorTimer.Elapsed += new ElapsedEventHandler(EnumerateGamepadsTimedEventHandler); enumeratorTimer.Enabled = true; }
Manual Enumeration:
private string ENUMERATE_COMMAND = "var gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);" + "for (var i = 0; i < gamepads.length; i++) {"+ " var gamepad=gamepads[i]; " + "if (gamepad) {"+ "UnityObject2.instances[0].getUnity().SendMessage('WebHIDBehaviourGO','onDeviceConnectedEvent',JSON.stringify({ id: gamepad.id, numButtons:gamepad.buttons.length, numAxes:gamepad.axes.length, index: gamepad.index }));" + " }"+ "}";
Reading position commands where defined like:
private string GAMEPAD_COMMAND = "var gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);" + "if(gamepads.length>0 && gamepads[{0}]){{" + "UnityObject2.instances[0].getUnity().SendMessage('WebHIDBehaviourGO','onRead',JSON.stringify(gamepads[{0}]));" + "}}else{{"+ "UnityObject2.instances[0].getUnity().SendMessage('WebHIDBehaviourGO','onDeviceDisconnectedEvent','{0}');"+ "}}"; //FF JSON doesn't work well private string GAMEPAD_COMMAND_COMPLEX = "var gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);" + "if(gamepads.length>0 && gamepads[{0}]){{" + "var gamepad=gamepads[{0}]; var buttons = []; for (var i = 0; i < gamepad.buttons.length; i++) buttons[i] = gamepad.buttons[i].value;"+ "UnityObject2.instances[0].getUnity().SendMessage('WebHIDBehaviourGO','onRead',JSON.stringify({{ id: gamepad.id, axes: gamepad.axes, buttons: buttons, index: gamepad.index }}));" + "}}";Read function
public void Read(int index) { // UnityEngine.Debug.Log(String.Format(GAMEPAD_COMMAND, index)); if(_hasEvents) Application.ExternalEval(String.Format(GAMEPAD_COMMAND_COMPLEX, index)); else Application.ExternalEval(String.Format(GAMEPAD_COMMAND, index)); }
I've very low opinion for JSON and dynamic object {} as increase data size and parsing time
and don't know why JS is forced overall but used it as quickest solution. Even then JSON on FF failed to stringify Gamepad objects.
Demonstration shows controller input remapping while playmode (button of Thrustmaster wheel and then on wheel positive X axis) to AnimationState Wave.
No comments:
Post a Comment