UnityでWebSocketを使ってチャット -Playと一緒-

Posted on 2013-06-21 by takezoux2

最近は、Unityをいじっているtakezoux2こと竹下です。

今回は、UnityでWebSocketを使ったチャットを作って動かしてみたいと思います。
UnityはC#で実装しています。有料のAssetは使っていません。
サーバーにはPlayを使っていますが、scalaのコードは今回全く書かなくてOKです。


まず、Unityって何?WebSocketって何?Playって何?っていう人がいるので簡単に説明しておきます。
簡単にしか説明はしないので、詳しくは各自ググってください。
全部知ってるよって人は、ここは飛ばしてください。

Unity

3Dゲームエンジン。iOS,Androidなど、各種プラットフォームのアプリをワンソースで開発することができるツールです。
言語はC#,UnityScript(JavaScriptベース),Boo(Pythonベース)が使えます。
3Dオブジェクトの空間配置などはGUIで可能なので、割と非プログラマやスキル不足のプログラマにも優しいです。
各種Asset(有料のものが多い;;)で、様々な機能拡張なども可能です。

無料で30日のPro版トライアルあります。それ以降は、ライセンスの購入の必要あります。
Unity公式ページ

WebSocket

最近流行の双方向通信規格です。同期通信を簡単に行えます。
WebSocket(wiki)

Play

scalaで書かれたWebサーバーです。WebSocketもNode.js並みに簡単に実装できます。今回のサーバープログラムとして使用しました。
この辺のことについてもっと詳しく知りたい方は、弊社でやっているscala勉強会に参加すると
ソースコードレベルまで詳しく教えてくれる人がいますw
Play公式


検証環境

Mac上で検証しています。
ただ、UnityもPlayもWindows上で動作するので、おそらくWindowsでも動作するとは思います。

手順

  1. Unityの準備
  2. WebSocketSharpの準備
  3. クライアント実装
  4. サーバーの準備
  5. 接続!

1.Unityの準備

Unityのインストール

Unity公式からダウンロードをしてきてください。
あとは、画面の指示に従ってインストールしましょう。起動すると、シリアルコードが聞かれますが、シリアルコードを持っていない人はtrialで開始してください。機能はトライアル期間はフルで使えます。

Unityプロジェクトの準備

file > New Projectから新しいプロジェクトを作ってください。名前はWebSocketSampleとか適当でいいです。


2. WebSocketSharpの準備

WebSocketSharpのビルド

今回は、UnityでWebSocketを使うために、WebSocketSharpというライブラリを使います。

※2014/1/21追記
AssetStoreで15$で販売中だそうです。ビルドが面倒だったり、使ってみて良かったらAssetStoreで購入してあげてください。

まず、ソースコードをgithubからcloneしてきてください。
次に、WebSocketTest.slnを開きます。MonoDevelopで開いてOKです。Windows環境なら、VisualStudioでも大丈夫だと思います。

プロジェクトが開けたら、ビルドレベルをReleaseにしてビルドします。私の環境では、サブプロジェクトのExampleXでビルドエラーが出たので、websocket-sharpだけビルドできればOKなので、ExampleX達をソリューションから削除してビルドしました。

ビルドが完了したら、websocket-sharp/bin/Release/websocket-sharp.dllが生成されているので、
これを先ほど作ったUnityプロジェクトのAssetsディレクトリ以下にコピーしてください。(Assetsディレクトリ以下に入っていればどこでもいいのでAssets/Dllディレクトリを作ってその下に入れるなどすると、後で整理しやすいです)


3. クライアントの実装

GameObjectの準備とComponentのアタッチ

Unityで先ほどのプロジェクトを開いたら、
Game Object > Create Empty
から新しいGameObjectを作成します。
名前は何でもいいですが、Chatぐらいにしておきましょう。
ヒエラルキーもどこに置いておいても大丈夫なので、作成したままの場所に置いておいてください。

つぎに、処理を記述するためのスクリプトを作成しChatオブジェクトにアタッチします。
Projectペインで、Assetsディレクトリを右クリックし、Create > C# Scriptを選択してください。
作られたファイルはChatぐらいにリネームしてください。(リネームはProjectタブ上でファイルを2回クリックすれば変更できます。ダブルクリックしてしまうとファイルを開いてしまうので注意)

次に、ProjectペインのChatスクリプトをドラッグして、Hierarchyペインの先ほど作成したChatオブジェクトへドロップしてください。これで、アタッチは完了です。

Operation help

実装

いよいよ実装です。
先ほど作成したChatスクリプトをダブルクリックしてください。MonoDevelopが起動するので、Chatスクリプトを編集してください。

ソースコードは以下の通りです。

using UnityEngine;
using System.Collections;
using WebSocketSharp;
using System.Collections.Generic;

public class Chat : MonoBehaviour {

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

    // Update is called once per frame
    void Update () {

    }

    /// 
    /// The message which store current input text.
    /// 
    string message = "";
    /// 
    /// The list of chat message.
    /// 
    List messages = new List();

    /// 
    /// Raises the GU event.
    ///
    /// 
    void OnGUI(){

        // Input text
        message = GUI.TextArea(new Rect(0,10,Screen.width * 0.7f,Screen.height / 10),message);

        // Send message button
        if(GUI.Button(new Rect(Screen.width * 0.75f,10,Screen.width * 0.2f,Screen.height / 10),"Send")){
            SendChatMessage();
        }

        // Show chat messages
        var l = string.Join("\n",messages.ToArray());
        var height = Screen.height * 0.1f * messages.Count;
        GUI.Label(
            new Rect(0,Screen.height * 0.1f + 10,Screen.width * 0.8f,height),
            l);

    }

    WebSocket ws;

    void Connect(){
        ws =  new WebSocket("ws://localhost:9000/chat/ws");

        // called when websocket messages come.
        ws.OnMessage += (sender, e) =>
        {
            string s = e.Data;
            Debug.Log(string.Format( "Receive {0}",s));
            messages.Add("> " + e.Data);
            if(messages.Count > 10){
                messages.RemoveAt(0);
            }
        };

        ws.Connect();
        Debug.Log("Connect to " + ws.Url);
    }

    void SendChatMessage(){
        Debug.Log("Send message " + message);
        ws.Send(message);
        this.message = "";
    }
}

やっていることは、Connect()でWebSocketでサーバーに接続。
SendChatMessage()で、WebSocketメッセージの送信。
OnGUIで画面の描画を行っています。
あまり難しいことはやっていないので、ソースコードを追ってもらえればわかるかと思います。
わからなければ、ソースコードをコピペしてください。

これで、クライアントの実装は完了です。


4. サーバーの準備

最後にサーバーの準備です。githubに用意しているのでコードは書かなくてOKです。
sbtで実行していますが、既にplayが入っている人はplayで実行してもらっても大丈夫です。

sbtの準備

サーバーの実行に使うので、sbtをインストールしてください。バージョンは、0.12.2以降が入って入ればOKです。
なお、sbtはscala向けのビルドツールです。
sbtは、公式サイトのここからダウンロードできます。Jarとシェルスクリプトをダウンロードしてきて、パスを通すだけです。

プログラムのcloneとサーバーの実行

サーバープログラムはこちらのgithubからソースコードをcloneしてください。
cloneしたらプロジェクトのルートディレクトリで

sbt run

を実行してください。
初回の起動は、scalaのダウンロードや、playのダウンロード、ライブラリのダウンロードが発生するので、時間がかかります。
ネットワーク環境の整っているところで実行してください。
以下のようなメッセージが表示されると、起動完了です。

--- (Running the application from SBT, auto-reloading is enabled) ---

[info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

(Server started, use Ctrl+D to stop and go back to the console...)

5. 接続!

Unityクライアントは、Unityの上の方にある三角の再生ボタンを押すと実行できます。
テキストボックスに送信したいテキストを入力してボタンを押すせばメッセージを送れます。
テキストボックスの下には、チャットで発言されたテキストが表示されます。

1クライアントだけでやっても何も楽しくないので、
http://localhost:9000/chatにアクセスしてください。
ここでブラウザからチャットを使えます。

Unityクライアントで入力した文章が、ブラウザのほうでも表示され、
ブラウザで入力した文章がUnityクライアントでも表示されていることが確認できると思います。
おつかれさまでした。


Tags

C# Unity play framework