ゲーム開発初心者の僕がUnity + WebSocketで何か作ってみた

64,582 views
64,130 views

Published on

2011年10月22日に大阪で開催された「第3回 HTML5など勉強会」での発表に使ったプレゼン資料です。

Published in: Technology
1 Comment
102 Likes
Statistics
Notes
No Downloads
Views
Total views
64,582
On SlideShare
0
From Embeds
0
Number of Embeds
9,657
Actions
Shares
0
Downloads
266
Comments
1
Likes
102
Embeds 0
No embeds

No notes for slide

ゲーム開発初心者の僕がUnity + WebSocketで何か作ってみた

  1. 1. ゲーム開発初⼼心者の僕が Unity  +  WebSocketを使って何かつくってみた 2011/10/22  第3回  HTML5など勉強会 @kadoppe 1
  2. 2. ⾃自⼰己紹介!  名前:kadoppe !  Twitter  twitter.com/kadoppe !  Blog  www.kadoppe.net!  職業:フリーランスエンジニア ! iOS,  Web(Rails,  Node.js,  etc)!  HTML5-‐‑‒West.jp  コアメンバー! about.me/kadoppe 2
  3. 3. この勉強会との関係!  第1回 ! WebSocketことはじめ!  第2回 ! SocketStream⼊入⾨門!  そして今⽇日が第3回⽬目の発表 3
  4. 4. アジェンダ!  イントロダクション !  Unity,  WebSocketについての簡単な 説明!  Unity  +  WebSocketで何かつくってみ た !  開発過程を時系列列にそって紹介 4
  5. 5. イントロダクション 5
  6. 6. 突然ですが質問です。 6
  7. 7. みなさんとUnityの関係A.  名前だけは知っている。B.  サンプルを動かした。C.  バリバリ使ってる。 7
  8. 8. みなさんとWebSocketの関係A.  名前だけは知っている。B.  サンプルを動かした。C.  バリバリ使ってる。 8
  9. 9. WebSocketとは?! WebSocket !  HTML5関連仕様の⼀一つ !  Webブラウザ/サーバ間でリアルタイ ム通信(双⽅方向通信)を実現!  従来の⽅方式(Cometなど)との⽐比較 !   サーバー/ネットワーク負荷:低 !   標準仕様(W3C,  IETFにより策定中) 9
  10. 10. 最近の⾃自分の悩み!  ⾃自分の表現⼒力力のなさ! WebSocketを使って チャットアプリしか作 れない!  チャットはリアルタイ ムなのか? 10
  11. 11. そんなときにUnityのお話が!  10⽉月x⽇日  都内某所 !  Aさん「かどっぺ,  Unityやってみな い?」 !  僕「Unityって?」 11
  12. 12. Unity!  Unity  Technologies  社が提供するゲー ム開発ツール  +  ゲームエンジン!  コンセプト !  「ゲーム開発の⺠民主化」 !   ゲームエディタ カンタンに !   物理理エンジン かつ !   グラフィックスエンジン 低費⽤用で利利⽤用可能 12
  13. 13. 13
  14. 14. 対応プラットフォーム!  マルチプラットフォーム !  Webブラウザ   !   Unity  Web  Playerというプラグインを 使って動作 !  Windows,  Mac  OS  X !  Wii,  PS3,  XBox  360 ! iOS,  Android 14
  15. 15. 製品構成、価格 対応プラットフォー 通常版 Pro ム Unity  Pro Windows,  Mac,  Unity(無料料) (136,000円) Web Unity  iOS   Unity  iOS  Pro   iOS  (iPhone,  iPad) (36,500円) (136,000円)Unity  Android   Unity  Android  Pro   Android (36,500  円) (136,000円) Pro:  バージョン管理理システムへの対応、⾼高速化 オプション、分析ツールなど 15
  16. 16. Unityの基本要素!  Scene !  ゲーム中のある場⾯面!  Game  Object !  ゲームに登場するあらゆるもの !  直⽅方体、球体、ポリゴンモデル、カメラ、 光源、などなど!  Script !  Game  Objectの挙動、Game  Object間 の連携を記述 16
  17. 17. Unityの基本要素Scene Script Material Game  Object Component 17
  18. 18. 使える⾔言語!  JavaScript(UnityScript) !  JavaScriptに静的型付けやOOPの要 素を追加した独⾃自の仕様!  C# !  UnityはMonoの上で動作するの で.NET⽤用クラスが利利⽤用可能!  Boo 18
  19. 19. どんなものが作れるのか 19
  20. 20. Unity  +  WebSocket!  Unityの表現⼒力力! WebSocketのリアルタイム通信 !  もし組み合わせることができれば ↓Web開発者にとって新しい表現の⼿手段になるのではないか? ⾃自分の悩みも解決? 20
  21. 21. というわけで、Unity  +  WebSocketで なにかつくってみた。 21
  22. 22. ⽬目標設定!  第1⽬目標 !  UnityからWebSocketを使ってサーバ と通信する!  第2⽬目標 !  複数プレイヤーで対戦できるゲーム のようなもののプロトタイプを作る 22
  23. 23. 僕のゲーム開発スペック!  ゲーム開発歴 !  ⼤大学の講義で少し !   アセンブラ !   C⾔言語 !  マルチプレイヤー 参加型ゲーム !   経験なし!  スペック不不⾜足!! 23
  24. 24. まずはUnityの勉強!  10⽉月16⽇日(⽇日)!  書籍を購⼊入 !  「Unity⼊入⾨門」 ! SoftBank  Creative !   ⾼高橋  啓治郎郎  (著) !  たくさん平積みされていてUnityの盛 り上がりを実感した   24
  25. 25. しかし  かどっぺは べんきょうができなかった!  10⽉月17⽇日(⽉月) !  お仕事 25
  26. 26. しかし  かどっぺは べんきょうができなかった2!  10⽉月18⽇日(⽕火) !  お仕事 26
  27. 27. しかし  かどっぺは べんきょうができなかった3!  10⽉月19⽇日(⽔水) !  お仕事 27
  28. 28. ようやく勉強開始!   10⽉月20⽇日(⽊木)!   「Unity⼊入⾨門」の以下の章だけ読む !   Chapter  1  Unityスタートガイド !   Chapter  2  とりあえず何か作ってみよう !   Chapter  4  迷路路ゲーム !   Chapter  5  ブロックシューター!   サンプルは⾃自分で⼿手を動かしてつくってみた !   「習うより慣れよ」が本書のコンセプト !   サンプルを通して少しずつ出来ることが増えて いく良良書 28
  29. 29. つくったサンプル 29
  30. 30. いよいよ開発開始!  10⽉月21⽇日(⾦金金)  7:00AM!  1⼈人Hackathonのつもりで開発するこ とに決定 30
  31. 31. 企画!  7:30  AM!  ネットワーク対戦型「ポン(PONG)」 をつくることに 31
  32. 32. 構成 WebSocket Server Unity UnityPlayer  A Player  B 32
  33. 33. スケジュールの決定!  7:35  AM 1.  「1⼈人で遊べるPONGもどき」をつく る 2.  UnityからWebSocketでサーバに通 信できるようにする 3.  マルチプレイヤー対応 4.  時間のあるかぎり作り込む 33
  34. 34. 1⼈人で遊べるPONGもどき完成!  9:30  AM !  ひとまず完成 !  仕様 !   ⾃自分/相⼿手のパドルを同時に操作できる !   ボールがゴールに⼊入ると、台中央に再び 出現する !   ボールの挙動は物理理エンジンで表現 34
  35. 35. 相⼿手のパドル ゴール(透明) ボール ⾃自分のパドルゴール(透明) 35
  36. 36. スクリプト⼀一覧! Ball.js !  ボールの処理理を記述! MyPaddle.js !  パドルの処理理を記述! Goal.js !  ゴール(透明)の処理理を記述 36
  37. 37. Ball.js//  ゲーム開始時に呼びだされるfunction  Start  ()  { //  ボールに⼿手前⽅方向の速度度を与える rigidbody.AddForce(Vector3(0,  0,  -‐‑‒1)  *  4,  ForceMode.VelocityChange);} 37
  38. 38. Goal.js//  他のオブジェクトと衝突したときに呼び出されるfunction  OnTriggerEnter(other  :  Collider)  { //  相⼿手がボールだった場合 if  (other.gameObject.tag  ==  "Ball")  {              //  リスポーン地点にボールを移動させる              var  respawn  :  GameObject  =                                                        GameObject.FindWithTag("Respawn");              other.gameObject.transform.position  =                                                        respawn.transform.position; }} 38
  39. 39. MyPaddle.js(抜粋)(略略)//  ⼀一定間隔で定期的呼び出されるfunction  Update  ()  {           //  キーボードの⼊入⼒力力を元にパドルの位置を左右に移動          var  velocity  =                                      Vector3(Input.GetAxis("Horizontal"),  0,  0);          controller.Move(velocity  *  Time.deltaTime  *  2);} 39
  40. 40. WebSocketの導⼊入開始!   10:10  AM!   調査 !   UnityにWebSocketの機能は搭載されていな い !   ブラウザのWebSocket  APIは操作できない 模様!   ⼯工夫 !   .NETのクラスを使ったSocket通信は⾏行行える →  C#のWebSocketライブラリが使えるは ず! 40
  41. 41. C#のWebSocketライブラリ! SuperWebSocket !   http://superwebsocket.codeplex.com/ ! WebSocketサーバ構築⽤用C#ライブラリ !  クライアントライブラリも付属! websocket-‐‑‒sharp !   https://github.com/sta/websocket-‐‑‒sharp !  シンプル!  名前に惹かれて前者を利利⽤用することに 41
  42. 42. Unityプロジェクトへの 外部ライブラリの追加!  ⽅方法 !  プロジェクトのPluginsフォルダにラ イブラリを配置すれば⾃自動的にロー ドされる !   .dll(開発環境がMacでも⼤大丈夫) !   .cs(C#のソースコード) 42
  43. 43. SuperWebSocketの導⼊入!  10:30  AM!  ライブラリの配置 !  Pluginsフォルダに.dllファイルを配置 →しかし、クラスがロードされない!  リトライ !  .dllファイルではなく、ソースコード (.csファイル)を配置 →コンパイルエラー! 43
  44. 44. SuperWebSocket ソースコード修正!  10:45  AM !  ソースコード中から⾚赤い部分を削除 !   Unityでマクロを定義する⽅方法がわから なかったため →コンパイル成功! #if  SILVERLIGHT #if  NET35 (略略A)         (略略A)         #else #else        (略略B)        (略略B) #endif #endif 44
  45. 45. サーバサイド実装!  11:10  AM!  UnityからWebSocket接続できるか確認す る⽬目的!  利利⽤用したもの ! Node.js   !  Node  WebSocket  Server ! Node.js⽤用のシンプルなWebSocketサーバ モジュール 45
  46. 46. app.js(サーバーサイド)//  モジュール読み込みvar  http  =  require(http);var  ws  =  require("websocket-‐‑‒server");//  サーバーインスタンスの⽣生成var  httpServer  =  http.createServer();var  wsServer  =  ws.createServer({server:  httpServer});//  クライアントが接続してきたときに呼び出されるイベントwsServer.addListener("connection",  function(connection)  { console.log(“connected”);  //  とりあえずログ出⼒力力}wsServer.listen(80); 46
  47. 47. サーバサイド実装完了了!   11:30  AM!   動作確認 !   「Connected」が表⽰示されない !   特にエラーは発⽣生していない!   原因解析 !   UnityからWebSocketの接続確⽴立立⽤用データは 送信されている !   サーバはデータを受信している !   Unity、サーバ側のWebSocketプロトコル バージョンは⼀一致している(はず。) 原因わからず、焦る 47
  48. 48. しばし仕事の打ち合わせ!  12:00  PM !  神⼾戸に打ち合わせに出かける 48
  49. 49. 帰宅宅、作業再開!  5:00  PM !  原因究明を試みる!  6:30  PM ! SuperWebSocketを諦めることに ! websocket-‐‑‒sharpを使⽤用!  7:30  PM →  すんなり接続成功  orz 49
  50. 50. Unity側WebSocket 接続スクリプト ! Server.cs(抜粋) !  SocketクラスはC#からのみ利利⽤用可能public  class  Net  :  MonoBehaviour  {          void  Awake  ()  {  //  初期化メソッド                    WebSocket  ws  =                                                new  WebSocket("ws://127.0.0.1:80/");                    ws.OnOpen  +=  (o,  e)  =>  {  //  接続確⽴立立時のイベント                              Debug.Log("Open");                    };                    ws.Connect();  //  接続          }} 50
  51. 51. サーバサイド実装!  7:55  PM〜~!  対戦相⼿手マッチング機能(簡易易版)を 実装 !  ⻘青プレイヤー: !   最初に接続したプレイヤー !  ⾚赤プレイヤー: !   ⼆二番⽬目に接続したプレイヤー 51
  52. 52. app.js(サーバーサイド)var  playerBlue,  playerRed;var  count  =  0;wsServer.addListener("connection",  function(connection)  { switch  (count)  { case  0:   playerBlue  =  connection;          playerBlue.send(JSON.stringify({type:“color”,  value:“Blue”}));  //  クライアントにプレイヤー種類を伝える break; case  1:     playerRed  =  connection;          playerRed.send(JSON.stringify({type:  "color",  value:  "Red"})); } count++;}); 52
  53. 53. ユーザのパドル⾊色の変更更!  8:15  PM〜~ !  サーバから送られてくるプレイヤー 種類を元に変更更 !  UnityにはJSONをパースする機能が ない ! LitJSONというC#ライブラリを利利⽤用 !   http://litjson.sourceforge.net/ 53
  54. 54. Client.js(Unity)public  class  Client:  MonoBehaviour  {          void  Awake  ()  {  //  初期化メソッド                    (略略)                    ws.OnMessage  +=  (o,  s)  =>  {  //  メッセージ受信時                Message  message  =                                                    JsonMapper.ToObject<Message>  (s);  //パース                if  (message.type  ==  "color")  {                                      (略略:パドルの⾊色を変える処理理)                          }                    };                    (略略)          }} 54
  55. 55. 動作確認!  8:45  PM  〜~!  問題発⽣生 !  パドルの⾊色が変化しない!  例例外が発⽣生 !  “Can  only  be  called  from  the   main  thread” 55
  56. 56. 原因解析! GameObjectはスレッドセーフではない! websocket-‐‑‒sharpはマルチスレッドで動 作! OnMessageイベントは別スレッドで発⽣生!  別スレッドからGameObjectを操作 →例例外が発⽣生 56
  57. 57. メッセージキューの導⼊入 !  10:45  PM !  サーバから受信したデータをキュー を使ってスレッド間でやりとり別スレッド メインスレッドOnMessage スレッドセーフなキュー 57
  58. 58. Client.cs(Unity)public  class  Client:  MonoBehaviour  {          private  Queue  messageQueue;          void  Awake  ()  {  //  初期化メソッド                    messageQueue=Queue.Synchronized(new  Queue());                    ws.OnMessage  +=  (o,  s)  =>  {                            messageQueue.Enqueue(s);  //  キューに追加                    };          } void  Update()  {  //  定期的に呼び出される        lock(messageQueue.SyncRoot)  {  //  キューをロック                  //  キューからメッセージを取り出す処理理        }                  //  メッセージを解析し、パドルの⾊色を変える処理理 }} 58
  59. 59. 仕上げ!  11:00  PM !  ゲームスタートの合図をサーバから送信!  11:15  PM !  プレイヤーのカーソル⼊入⼒力力をサーバ経由 で相⼿手プレーヤーに送信!  11:30  PM !  サーバから受信した相⼿手プレーヤーの カーソル⼊入⼒力力をもとに相⼿手パドルを操作 59
  60. 60. 完成?Webでの動作確認!  11:45  PM !  Web  Player向けにビルド !   今まではMac  OS  Xアプリケーションと して動作確認していた !  例例外発⽣生 !   “SecurityException:  Unable  to   connect,  as  no  valid  crossdomain   policy  was  found” 60
  61. 61. 原因解析!  サーバからポリシーファイルを取得し ていないことによる例例外!  Unity  Web  Playerで843番ポート以外 にソケット接続をする際に必要 !  今回は80番ポートに接続している !  Mac  OS  X⽤用にビルドしている場合は 不不要 61
  62. 62. Client.cs(Unity)public  class  Client:  MonoBehaviour  {          private  Queue  messageQueue;          void  Awake  ()  {  //  初期化メソッド                  //  WebSocket接続を⾏行行う前に以下を記述                  Security.PrefetchSocketPolicy  (“127.0.0.1”,  80);          ws.Connect();          }} 62
  63. 63. app.js(サーバーサイド)httpServer.on(connection,  function(socket)  {          //  ソケット接続でデータが送信されてきた socket.addListener("data",  function(data)  {                  //  データに「policy-‐‑‒file-‐‑‒request」という⽂文字列列が存在                  if  (data.toString("utf8").match(/policy-‐‑‒file-‐‑‒request/))  {                          //  クライアントにpolicry-‐‑‒fileの内容を送信                socket.write(ʻ‘<cross-‐‑‒domain-‐‑‒policy>  <allow-‐‑‒access-‐‑‒from  domain=“*”  to-‐‑‒ports=“*”/>  </cross-‐‑‒domain-‐‑‒policy>ʼ’,  ʻ‘utf8ʼ’);        } });}); 63
  64. 64. 実装完了了!  10⽉月22⽇日  1:00  AM !  ひとまず完成 !  ⼒力力尽きて、就寝!  10⽉月22⽇日  6:00  AM !  起床。 !  資料料を作って今に⾄至る。 64
  65. 65. Demo 65
  66. 66. 改善点!  実装漏漏れ !  ボールの同期を⾏行行なっていない !   各プレイヤーで物理理シミュレーションを⾏行行 いボールを動かしている !   パドルの同期に遅延があった場合、両プレ イヤーのボールの動作にズレが⽣生じてしま う!  その他 !  スコアリングなど、ゲームとしての機能 66
  67. 67. まとめ!   Unity !   カンタンに使えるマルチプラットフォーム⽤用ゲーム開 発エンジン! WebSocket !   Webにおけるリアルタイム通信の標準化された仕様!   「Unity  +  WebSocket」は実現可能 !   実際にサンプルゲームを(途中まで)開発することが できた!   Webエンジニアが⾃自分の世界を広げるための良良いきっか け? !   Letʼ’s  try!! 67
  68. 68. ご清聴ありがとうございました 68

×