A-Frameのキー操作を外部プログラムで制御

A-Frame使うとUnityとか開発環境がない場所でもさくっと3D空間使ったでも作れて便利なんだけど、デバイス系の事やると、シリアルポートとかpythonあたりでみといて「wasdキー押すだけでええんやけどなぁ。」って事ありますよね。

「外部バイス」-「Python」-<<謎の壁>>-「A-Frameのカメラ操作」

Websocketでやったろ、A-Frame側無改造で。

ということで、ブックマークレットとしてwebsocketを受信してキーコードを送り込むテストをしてみた。まずはpythonコード、websocketで一秒おきにW/Sを出力してるだけ。

import asyncio
import websockets
 
async def accept(websocket, path):
  while True:
    await asyncio.sleep(1)
    await websocket.send("W")
    await asyncio.sleep(1)
    await websocket.send("S")
 
start_server = websockets.serve(accept, "0.0.0.0", 9998)
asyncio.get_event_loop().run_until_complete(start_server)
print("I run")
asyncio.get_event_loop().run_forever()

次に登録するブックマークレット。Websocketで何か受信するたびにキーイベントとして投げるだけのブックマークレット。A-Frameのwsad-controlはKeybordEventのうちcodeしかみてないのでそれしか登録してないイベントを投げてる。

(セキュリティ制御のヘッダで禁止してない限り、他のサイトでも動いちゃうので誤操作に注意。)

javascript:(function(){
var webSocket = new WebSocket("ws://127.0.0.1:9998");
webSocket.onmessage = function(mes){
	window.dispatchEvent( new KeyboardEvent( "keydown",{ code: 'Key'+mes.data  })) ;
	setTimeout( () => {window.dispatchEvent( new KeyboardEvent( "keyup",{ code: 'Key'+mes.data  })); }, 100);
	console.log(mes.data);
};
})();

適当なA-Frameで作られたサイトを開いて、ブックマークレットをクリックすればカメラが前後するはず。例えば、https://aframe.io/aframe/examples/showcase/anime-UI/  ただし、本家A-Frameのサイトはフレームの中に表示されてるので、デモ画面で右クリックして「このフレームだけ表示」してからじゃないと使えないので注意。

まとめ

適当なwebサイトで動いてるゲームとかもJavaScriptで書いてあれば多分似た事できるので、外部デバイス対応させるhackとしては便利かも。