LoginSignup
22
18

More than 5 years have passed since last update.

iPhone/AndroidのブラウザからWebSocketを使ってUnityのゲーム操作を行う

Last updated at Posted at 2014-09-06

はじめに

OculusRift + Unityを使っていて、キャラをキーボードで操作、とかかなり辛いものがあります。
そこで、Oculusを持っている人なら必ず持っているであろう iPhone/Android と UnityをWebSocketで繋いで操作する方法を共有します。Oculusじゃなくても、スマートフォンで操作できるのは何かと使える機会もあるかな、と思います。

今回は 画面上のTouch位置(X,Y) と 端末の傾き(X,Y,Z) をUnityにリアルタイムに送って操作する というシチュエーションを考えます。

iPhone/Androidはそもそも加速度センサを持っていて傾きが検知できますし、画面上のどこをタッチしているかも取得できます。また、ここ数年のiPhone/AndroidはそれらがWebブラウザから利用できるので、アプリのUI側の構築もHTMLとJavaScriptがちょいちょいかければ作れて手軽で便利です。また、WebSocketによってそれなりにリアルタイムに通信できます。

各バージョン

動作確認した環境は以下になります。

  • MacOSX 10.9.4 + Wifi
  • Unity 4.5.3f3
  • iPhone5S (iOS 8 beta)

注意事項

  • UnityのWebPlayerではこの機能は使えません 。Unity側がWebSocketのサーバになることができない(たぶん)からです。PC向けビルドでのみ使えます。
  • 基本的に Mac と iPhone は同一のWifiに接続している必要があります(通信出来る必要がある)。
  • Androidではテストしていません。きっと動かないでしょう(^^;; 。ちょっと修正すると動くようになるのではないかな、、、と思っていますが。。
  • Macではなく、Windowsでもおそらく大丈夫です

構成

今回の構成を簡単に描くとこんな感じになります。

名称未設定_key.png

SourceCode

下記にSource Codeを置いてあります。
https://github.com/mokemokechicken/UnitySmartPhoneInputController

導入の仕方

上記githubをcloneして、
SmartPhoneInputController.unitypackage を実行してください。
Projectにファイルが追加されるます。

Assets/SmartPhoneInputController/Prefabs/
SmartPhoneInput.prefab というのがあるので、それをSceneに追加しましょう。

Debug用のGUITextの SmartPhoneControllGUIText.prefab もSceneに追加して Postion=(0,1,0)にすると左上に表示されると思います。

Demo

Assets/SmartPhoneInputController/demo.unity を実行すると、最初

demo_unity_-_aa_-_Web_Player.png

というような画面が表示されるので、そこのURLに iPhoneやAndroidでアクセスすると、

demo_unity_-_aa_-_PC__Mac___Linux_Standalone.png

という表示に変わります。意味としては
* 画面上のTouch位置 (X, Y): (0,0)が中心。-1 ~ 1の値。
* スマートフォンの傾き (X, Y, Z): どの軸がどれって書きにくいので割愛しますすが -1 ~ 1の値をとる傾きです。

API

このコードをみてもらうとわかるんじゃないかと思いますが、 SmartPhoneInput の static method で、
* (PadX, PadY) -> 画面上のTouch位置
* (PadGradX, PadGradY,PadGradZ) -> 傾き
を表します。

DebugDisplay.cs
public class DebugDisplay : MonoBehaviour {

    // Use this for initialization
    void Start () {
    }

    // Update is called once per frame
    void Update () {
        string msg = "";
        if (SmartPhoneInput.IsConnected()) {
            msg += "Connected, ";
            msg += "(" + SmartPhoneInput.PadX + "," + SmartPhoneInput.PadY + ")";
            msg += "(" + SmartPhoneInput.PadGradX + "," + SmartPhoneInput.PadGradY + "," + SmartPhoneInput.PadGradZ + ")";
        } else {
            msg += "Disconnected: Please Access " + SmartPhoneController.WebUrl;
        }
        guiText.text = msg;
    }
}

中の仕組み

WebSocket

Unity側でサーバサイドのWebSocketを実装する必要がありますが、
https://github.com/sta/websocket-sharp を使わせてもらっています。これすごく使いやすいです。

これをUnityで使うときは websocket-sharp の部分だけをBuildして、出てきた websocket-sharp.dll をAssetsフォルダに追加すればOKです。今回DLLをGitの中に同梱してあります。もし、Windowsなどで不具合が起きるようなら再度buildして、dllを置き換えたりしてみてください。

JavaScript in Webページ の配布

スマートフォンで表示するWebページは、どこから取得しても良い(WebSocketには originルールとか無いので)のですが、別途Webサーバを立てたりするのも面倒なので、それもUnityにさせています。
HTML自体は、 Assets/Resources/SmartPhoneInputController/ws.html にあります。
「Androidで動かねー!!」という場合はこれをいじってみてください。
動いたら是非Pull Request下さい (^^;

スマートフォンからUnityへの送信間隔もここで setTimeout しているだけなので、適宜調節してみてください。今は 100msくらい間隔を開けています。

見た目とか表示内容とかもいじると何かと楽しそうです。# DSの2画面みたいで

JavaScriptのコード的に汚いですが、、、どんまい。

通信内容

WebSocketでの通信内容ですが、 ブラウザ → Unity に対してコンマ区切りの文字列で5個の数値を渡しています。
ただ、ここでは -100~100 の整数を送っています。最初、なんか実数を送ると無駄に文字数が増えるなーと思ってそうしていますが、今となってみては気にすることも無いようにも思えて微妙な気もします。

さいごに

ちょっといじると、複数スマートフォンを同時接続できて、複数プレイとかもできると思います。
弾を撃つとかもどうにかUIを割り当てたいですねー。

22
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
18