白井研究室セミナーを通して学んだこと(古田真緒)

こんにちわ。神奈川工科大学情報学部情報メディア学科3年の古田真緒です。今回は白井研究室セミナーで自分が学んだ事について書いていきます。

前期白井研究室セミナーで自分がやったことは大きく分けて3つです。

・IVRC2015に企画を投稿

・IFTTTを使ったBot作成

・ゴーストブラスト企画コンペに参加(2015年7月末現在も継続中)

他にもニコニコ超会議のスタッフとして参加したり、IVR展を見て回ったりもしましたが、今回は上記3つについての学びについて書くことにします。

セミナー記事02

IVRC2015について

IVRCとは「International collegiate Virtual Reality Contest」、国際学生対抗バーチャルリアリティコンテストのことで1993年から毎年行われています。

企画の投稿にあたり、自分達は過去作品の調査から始めました。各年のIVRCの受賞作品の傾向や過去作品を知ることでの企画被りを避ける事で審査員の目に留まりつつ、新規性の追求をすることで評価されやすい企画を考える材料にしました。過去作品の調査についてはこのブログで記事にもしています。

その後本格的に企画を作り始めました。いくつかのチームに別れ、自分は藤澤君とチームを組むことになりました。企画を考えるにあたり過去作品との差別化、特許を取得されていないか、実際に役に立つのかなどに重点を置いて企画しました。

自分はとにかく行動するという意識でやっていました。調査をして、見所を考え、文章で伝える、と駆け足で企画を立てていました。しかし途中で考えが至らない点や文章力の低さなど、まとめる力が足りないことを痛感しました。企画を提出する前日まで文章作成を藤澤君に頼ってしまいがちだった事は反省すべき事だと思っています。

2人で形にした企画は無事IVRC2015に投稿されました。結果は落選でしたが、追い詰められる経験やチームの協調性の重要さ、1人で全てやりきることの困難さなどを実際に体験できて良かったと思っています。もちろん1人で出来る体験ではなく、自分と一緒に企画を立ててくれた藤澤君にもとても感謝しています。

セミナー記事01

IFTTTのBot作成について

IVRCの企画が終わった後、かなり燃え尽きていましたがそれで終わりではありません。常に次を見据えて行動しなければなりません。セミナーでやってみたい事は何かを考える事になり、自分は「スマホで何かを作りたい」、「ゴーストブラストの企画コンペに参加したい」という2つを挙げました。

各項目の記事はこの記事を書いた後に仕上げていきたい思います。Botの詳しい作り方や企画コンペについてはそちらにて紹介させていただきます。

IFTTTとはざっくりと説明すると「○○した時、××する」という形式(レシピ)にのっとってアプリケーションを動かすアプリケーションです。たとえば「Facebookで自分がタグ付けされた写真を保存する」といった形式で自動で実行されます。

最初は「何でも出来るけど何したらいいんだこれ……!?」といった料理人用の包丁を全て並べられた時のような感想でした。

しかしここでも「とりあえずレシピを実行してみよう」とその日の天気をスマホの通知で教えてくれるレシピを使ってみました。そこからとりあえず天気について使ってみようと思いました。

中間報告でとにかく何か形にした方が良いとの意見を頂いたのでTwitterで横浜周辺の天気を知らせるBotを作成する事にしました。自分でレシピを調べ、「どうやって実装しよう」、「どうやって表示しよう」と考えながら手を動かす時間はとても楽しかったです。

実際に作ったものについてはIFTTTの記事でも掲載しますが、こちらでもリンクを作成します。これが自分が作ったBotになります!

twitter.com/sunny_river_

完成した、とはまだ言い切れませんが、一度形にした時は「モノを作ることはやはり楽しい」と感じました。こちらのBotは今後も改良していく予定です。

11777515_1662082600695389_97837284_o

ゴーストブラスト企画コンペについて

ゴーストブラストとは、去年は長崎ハウステンボスに、今年1月にはトウキョウタワー地下ホールに展示されたシューティングアトラクションです。企画コンペについて詳しくはこちらのページをご覧下さい。

今回この企画に参加したいと思ったのは、IVRCに投稿した企画が使えるかな、と軽い気持ちで参加表明をしました。そして7/23(木)の製品説明会に参加してその気持ちが大きく変わりました。

説明会で実際にお話を聞かせていただくと、根本的に企画が合っていないな、思いました。しかしそれで企画コンペへの参加をやめよう、とは思いませんでした。

製品説明会の前に少し勝田会長とお話をする時間があったのでゴーストブラストについて疑問に思っていたことをガチガチに緊張した状態でも訊ねてみました。どれも納得の出来る回答で、続いて古武道について聞かせていただきました。

一般に「武道」と聞くと剣道やフェンシング、テコンドーなどがイメージに近いでしょうか。これらの競技に判定されるのは「当たったか否か」という01での審判です。しかし古武道は「むしろ当ててからが勝負」というお話を聞かせていただきました。

昔の合戦では刃を敵に当てれば勝ちではありません。刃を当て、切り抜いて戦闘不能にすることが重要なのです。そのため古武道では「その攻撃が浅いか、深いか」が重要になってきます。そしてゴーストブラストでもその思想が実装されていました。

ゴーストブラストと古武道についてはまた別の記事で書かせていただくとして、今ここで必要なのは企画コンペに参加し続けようと思った理由です。

IVRCの企画が使えないと分かった後も参加しようと思った理由、それは古武道に興味を持ったからです。自分は軟式、公式ともにテニスの経験があり、それと類似する点が古武道にはありました。そして話は膨らんでいき、最終的にゴーストブラストのシステムを使ってやりたいことについてのお話も聞かせていただきました。

それを聞いた自分は「それを実現したい」と思いました。この項目についてはまだ終わっていないのでこれ以上は追って記事にしていきたいと思っています。

 

まとめ

さて、前期白井研究室セミナーで学んだことについてまとめていきたいと思います。

このセミナーでは上記に書いた以外にも情報発信者として大切にするべき点や展示者としての意識の持ち方、プレゼンをした人に対して痛い箇所への質問をすることの重要さなどを知りましたが、特に重要だと思った事は「チームメンバーに謝るのではなく感謝する事」と「やはりエンジニアリングがしたくて仕方ない」と再確認できたことです。

セミナーでのディスカッションやプレゼン、企画、行動。この白井研究室セミナーで体験した事全てが自分の世界を広げてくれました。やはりそれらは楽しくて、面白くて、そして何より学びになりました。もちろんしんどい事や上手くいかずにイライラした事もありましたが、それらも含めて今までにないものを体験できたと思っています。

最後になりますが白井先生を始め、一緒に企画を進めてくれた藤澤君や意見をくれた研究室の先輩、セミナーの同級生に感謝しています。約3ヶ月半の間でしたが、ありがとうございました。

 

そして、最後まで読んでくださった皆様、お付き合いいただいてありがとうございました。

 

 

 

 

 

大学3年生でCEDECに初参加してみる~情報収集編~

こんにちは、神奈川工科大学情報メディア学科3年生の菊崎駿介です。

皆さんは「CEDEC2015」をご存知ですか?
パシフィコ横浜で2015年8月26日から28日までの3日間開催される
日本最大のゲーム開発者向けカンファレンスのことで、
ゲームに関連する様々な分野の講演が行われているそうです!

パシフィコ横浜の外観

1年生のときにCEDECの存在を知って、そのときから興味はあったのですが、
参加費用の関係で毎年断念していました……
しかし、今年はなんとセミナーの調査ミッションとして行けることになりました!
「CEDEC2015」に初参加してきます!!
この機会に、今後進みたい研究分野を探してきたいと思います。

ということで、どのセッションに参加するか事前に調べていたのですが、
あまりのセッション数の多さに迷ってしまいます……

ひと通り見て、興味のあるところを挙げていきます。

基調講演

8/26(水) 9:45~11:05
つくる、ということ。
中村 伊知哉(慶應義塾大学大学院 メディアデザイン研究科 教授)

8/27(木) 9:45~11:05
Data Art and Entertainment
実際に行ってきたプロジェクトをコンセプトから実際に用いたデータの詳細、デザインまで
真鍋 大度(株式会社ライゾマティクス)

8/28(金) 9:45~11:05
妖怪ウォッチ ゲーム・アニメ・映画・漫画・玩具 ~各界クリエイター共同戦線~
各業界のクリエイターたちとのSessionのお話
日野 晃博(株式会社レベルファイブ 代表取締役社長/CEO)

招待

8/26(水) 16:30~17:30 レギュラーセッション
エンターテインメント技術を使った空間アプリケーションの創造
BIM(Building Information Modeling)とUnityを活用した「ビルコミ3D」や「VRuno」の紹介とスマートライフハッカソンの取り込みについて紹介
粕谷 貴司(株式会社竹中工務店 情報エンジニアリング本部 エンジニア)

8/27(木) 11:20~12:20 レギュラーセッション
さらにアジャイルなゲーム開発者になるために:欧米からの教訓
Nathalie Goh-Livorness(Microsoft Gaming Evangelist)

8/27(木) 14:00~14:30 ショートセッション
汎用スマホ利用VRゴーグルって。やっぱりダメですかね?
スマホVRの現状と今後の展望のまとめ、これまで作成してきたスマホVRゴーグルの紹介
伊達 康司(日本Androidの会 金沢支部・VR部 組み込みシステム・エンジニア)

TMCN(Tokyo MotionContorol Network)ブース』 インタラクティブセッション
最新のセンサー&デバイスに関する知識、応用例などを知ることができる
伊藤 武仙(TMCN(Tokyo MotionControl Network) 事務局 理事長)

8/28(金) 13:30~14:30 レギュラーセッション
サマーレッスン」が誘う非現実のリアル(1) プロデュース編
「サマーレッスン」はどのような考えで計画され、どのような障害を乗り越えてきたのか。
それと現状のVRコンテンツが抱える問題を説明し、将来の展望について
原田 勝弘(株式会社バンダイナムコエンターテインメント 部長/ゲームディレクター/チーフプロデューサー)

8/28(金) 14:50~15:50 レギュラーセッション
サマーレッスン」が誘う非現実のリアル(2) テクニカル編
「VRにおける3Dエンジン制御・UI制御」「VRにおけるキャラクター表現・背景表現」「VRにおけるフェイシャル・アニメーション表現」の3軸の紹介
原田 勝弘(株式会社バンダイナムコエンターテインメント 部長/ゲームディレクター/チーフプロデューサー)

8/28(金) 16:30~17:30 レギュラーセッション
サマーレッスン」が誘う日現実のリアル(3) 開発者ディスカッション編
「サマーレッスン」に関する技術やコンセプトに関するパネルディスカッション
原田 勝弘(株式会社バンダイナムコエンターテインメント 部長/ゲームディレクター/チーフプロデューサー)

8/28(金) 17:50~18:50 レギュラーセッション
人工知能の未来 — ディープラーニングの先にあるもの —
人工知能が今後社会や産業をどう変えるか
松尾 豊(東京大学大学院 工学系研究科 准教授)

公募

8/26(水) 13:30~14:30 レギュラーセッション
スクウェア・エニックス AIアカデミーの試み「ゲームAI技術のための教育カリキュラムを考える
三宅 陽一郎(株式会社スクウェア・エニックス テクノロジー推進部 リードADリサーチャー)

8/26(水) 16:30~17:30 レギュラーセッション
FINAL FANTASY XV -EPISODE DUSCAE- におけるキャラクターAIの意思決定システム
白神 陽嗣(株式会社スクウェア・エニックス 第2ビジネスディビジョン プログラマー)

8/27(木) 13:30~14:30 レギュラーセッション
カプコンVS全学生! CAPCOM GameJamで生まれた学生とカプコンとの絆
初めてGameJamイベントを開催した振り返りを開発者目線で
大井 勇樹(株式会社カプコン 技術開発室 テクニカルコーディネーションチーム テクニカルディレクター)

8/28(金) 11:20~12:20 レギュラーセッション
ゲームにおける既視感で、どうユーザーの気持ちを掴むか?
ゲームにおける既視感とは、既視感のメリット・デメリット、既視感の使い方
馬場 保仁((株)ディー・エヌ・エー Japan リージョンゲーム 事業本部 プロデューサー)

8/28(金) 17:50~18:50 CEDEC CHALLENGE
PERACON2015
ペラ企画コンテストの結果発表
遠藤 雅伸(東京工芸大学 芸術学部ゲーム学科 教授)

こうして挙げてみると、企画のほかVRとAIの分野にも興味があることがわかりました。
今後はスケジュール順でどのセッションに参加するか決めていこうと思います。

プログラミングができない大学3年生がオンラインゲーム作りに挑戦する。

こんにちは、神奈川工科大学情報学部情報メディア科3年の齊藤です。今回私はUnityを使ったオンラインゲームの開発に挑戦したいと考え行動しました。
そして私は私と同じようにオンラインゲームに興味を持ち作りたいと考えている人たちの助けになるようにと私が参考にした本と自分が行った流れをこのブログに載せていこうと考えました。

私が使った本は河田匡稔著の「オンラインゲームのしくみ Unityで覚えるネットワークプログラミング」という本です。
本の内容に触れる前に一つ注意事項があります。
この本はタイトルにある通りUnityを使って様々なサンプルを実行するためUnityのインストールが必須になりますのでご注意ください。
以下この本を書いてくれた著者に感謝して記事を書いて行きます。

1章ではオンラインゲームを作るうえで考えていかなくてはいけないことやオンラインゲームならではの考え方などが載っています。正直なところ速くサンプルを使ってみたいという人たちからすると読み飛ばしたくなる場所ではあるかもしれないですが、個人的には軽くでもいいから一通り眼を通すべき場所だと思いました。
前知識なしで飛ばしてしまおうと考えた人でも1.3は確実に読んでもらいたいと感じました、個々では本書を読み進めるにあたってというタイトルで本の構成やサンプル、用語についてと、あるので本書を読み進める上で助けになります。

2章では通信プログラムの基礎知識というタイトルで通信の仕組みについてや送受信プロトコルであるTCPとUDPの違いなど、通信についての基礎知識の紹介になります。
TCPとUDPについて知っているからといってこの部分を全て飛ばさないでほしいと私は考えます。この章では基礎的な部分に加えオンラインゲームでよく使われるプロトコルや通信の遅延に対しどのように考えるべきかが書かれています。

3章から待ちに待ったサンプルプログラムを使用した演習になって行きます。3章ではソケットプログラムを用いたデータの送受信のサンプルを使います。

実行画面は以下のもののように非常に地味なものであります

サンプル実行画面

空白の部分に相手のIPアドレスかあるいはローカルホストでテストを行うならばlocalhostと入力して自分をサーバーとして動かすか、サーバーに接続するかを選択します。
相手との接続が成功していればサンプルが入っているファイルのbinフォルダの中にあるTCPを使ったサンプルのほうならばSocketSampleTCP_Dataを開いてUDPならばsocketSampleUDP_Dataを開く、そうすると中にoutput_log.txtができておりこれが通信の履歴になります。

ここからプログラムの解説を行いたいと思います。
まずはじめに待ち受けようのソケットの生成を行います。

// 待ち受け開始.
void StartListener()
{
Debug.Log("Start server communication.");

// ソケットを生成します.
m_listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 使用するポート番号を割り当てます.
m_listener.Bind(new IPEndPoint(IPAddress.Any, m_port));
// 待ち受けを開始します.
m_listener.Listen(1);

m_state = State.AcceptClient;
}

こちらにm_listenerと言う変数がありますね?こちらが待ち受けを行う専門のソケットでリスニングソケットと呼ばれるものです。
そしてそのすぐ下の部分でソケットの種類をStreamと選択しプロトコルをTCPと指定しています。その次にm_listenerにポート番号を割り当てます。そして最後に待ち受け状態にするためにListen関数を呼び出します。

次にクライアントからの接続要求受付についてです。

// クライアントからの接続待ち.
void AcceptClient()
{
if (m_listener != null && m_listener.Poll(0, SelectMode.SelectRead)) {
// クライアントから接続されました.
m_socket = m_listener.Accept();
Debug.Log("[TCP]Connected from client.");
m_state = State.ServerCommunication;
}
}

サーバーはクライアントからの接続要求の受付を行うためにこちらのAccept関数を呼び出します。この関数はクライアントからの接続要求があるまで処理をブロッキングします。
ブロッキングとは呼び出した関数の処理が完了するまで処理の制御が帰ってこないようにすることです。
しかしこのままだとゲームを作る際にブロッキングされてしまうとゲームとして成り立たなくなってしまうためPoll関数でクライアントからのデータ受信を監視して、データを受信したときだけACcept関数を呼び出すようにします。
Poll関数とは複数のファイルディスクリプタを監視、制御するものである。
ファイルディスクリプタで処理を待ち合わせるシステムコールを実行すると、データが到着するなどの一連の処理が完了するまでシステムコールから処理制御がリターンされなくなります。

次にサーバーへの接続、メッセージの送信、通信の切断の説明です。

void ClientProcess()
{
Debug.Log("[TCP]Start client communication.");

// サーバへ接続.
m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ・・・①
m_socket.NoDelay = true; ・・・②
m_socket.SendBufferSize = 0;
m_socket.Connect(m_address, m_port); ・・・③

// メッセージ送信.
byte[] buffer = System.Text.Encoding.UTF8.GetBytes("Hello, this is client.");
m_socket.Send(buffer, buffer.Length, SocketFlags.None);

// 切断.
m_socket.Shutdown(SocketShutdown.Both);
m_socket.Close();

Debug.Log("[TCP]End client communication.");
}

サーバーとの接続を行うためのソケットの生成を行います。
m_soketにsoketクラスのインスタンスを生成します。これが①の部分です。次に小さなパケットをバッファリングしないようにSoket.NoDelayプロパティをtureにsoket.SendBufferSizeの値を0に設定する、これが②の部分です。最後にm_soketに接続先のIPアドレスとポート番号を指定して接続要求を行います、これが③の部分になります。

ソケットの送受信にはSend関数とReceive関数を使ってデータの送受信をすることができます。この2つの関数はペアで扱われる関数であり、Send関数で送ったデータをReceive関数を呼び出すことによってデータを取り出すことができるようになっています。

最後に切断についてです。通信を終了させるときはShutdown関数を使用してパケットの送受信を遮断します、そしてClose関数を使用して通信の切断を行います。

// 待ち受け終了.
void StopListener()
{
// 待ち受けを終了します.
if (m_listener != null) {
m_listener.Close();
m_listener = null;
}

m_state = State.Endcommunication;

Debug.Log("[TCP]End server communication.");
}

お互いに送信したデータを全て受け取ってから通信を終了させる場合は、Shutdown関数で送信だけ終了させて、全ての受信が終了してからClose関数を呼び出して終了します。

サーバーの待ち受けを終了する場合は、リスニングソケットを、Close関数を呼び出して破棄します。

UDPのソケットプログラミングではTCPと違い接続処理を行わずに通信することができる。なので待ち受けを行う必要がありません。
UDPの送信、受信ではSendTo関数とReceiveFrom関数を使用します。TCPのほうで使われていたSend関数とReceive関数と同じようにこの二つの関数はペアで扱われる関数でありUDP通信時(コネクションレス型のデータ送信時)にデータ送受信を行う関数です。
UDPでのポート番号の割り当てを行って通信可能になるまでのプログラムを以下に示します。

void SendMessage()
{
Debug.Log("[UDP]Start communication.");

// サーバへ接続.
m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

// メッセージ送信.
byte[] buffer = System.Text.Encoding.UTF8.GetBytes("Hello, this is client.");
IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse(m_address), m_port);
m_socket.SendTo(buffer, buffer.Length, SocketFlags.None, endpoint);

// 切断.
m_socket.Shutdown(SocketShutdown.Both);
m_socket.Close();

m_state = State.Endcommunication;

Debug.Log("[UDP]End communication.");
}

このように接続の処理がないだけでソースがかなり短くなります。

 

次に4章のチャットプログラムについての解説をします。チャットプログラムを作る際考えておくべきことがあります。それは会話の流れです。相手が送っている間自分が入力できないなんて仕様だと会話として成り立たなくなってしまいます。他にもチャットを打ち込んだはずなのに相手に届いていないという事態になってしまっても会話が成り立ちません。なので相手に確実にデータを届け、かつ相手とのデータのやり取りで片方が待たなくてはいけないという状況を作らないようにしなくてはいけません。

このプログラムは確実にデータを届けるためTCP通信を使います。なので通信ライブラリ、TransportTCPクラスを使用を使用して作成されています。
チャットプログラムはプレイヤーが自分でルームを作るか参加するかを選択するシーケンスと実際にチャットを行うシーケンスの2つで作られます。

チャット

はじめにチャットルームの選択を行う処理のソースについてです。

void SelectHostTypeGUI()
{
float sx = 800.0f;
float sy = 600.0f;
float px = sx * 0.5f - 100.0f;
float py = sy * 0.75f;

if (GUI.Button(new Rect(px, py, 200, 30), "チャットルームの作成")) {

m_transport.StartServer(m_port, 1);

m_state = ChatState.CHATTING;
m_isServer = true;
}


Rect labelRect = new Rect(px, py + 80, 200, 30);
GUIStyle style = new GUIStyle();
style.fontStyle = FontStyle.Bold;
style.normal.textColor = Color.white;
GUI.Label(labelRect, "あいてのIPあどれす", style);
labelRect.y -= 2;
style.fontStyle = FontStyle.Normal;
style.normal.textColor = Color.black;
GUI.Label(labelRect, "あいてのIPアドレス", style);

Rect textRect = new Rect(px, py + 100, 200, 30);
m_hostAddress = GUI.TextField(textRect, m_hostAddress);


if (GUI.Button(new Rect(px, py + 40, 200, 30), "チャットルームへの参加")) {
bool ret = m_transport.Connect(m_hostAddress, m_port);
if (ret) {
m_state = ChatState.CHATTING;
}
else {
m_state = ChatState.ERROR;
}
}
}

この部分でサーバーとなるかクライアントを選ぶかで接続の方法を変えています。サーバーとして部屋を作るボタンを選択すると3章であったようにStartSeaver関数を呼び出し待ち受け状態になり相手からの接続を待ちます。
既存のサーバーに接続する際はテキストに記入された相手のIPを読み取りそのIPアドレスに接続します。サーバーに接続できればチャットに移行し、接続に失敗すると再度チャットルームの選択に戻ります。

次にチャットルームでのメッセージのやり取りの部分になります。

enum ChatState {
HOST_TYPE_SELECT = 0,    // ルーム選択.
CHATTING,                // チャット中.
LEAVE,                    // 退出.
ERROR,                    // エラー.
};

 

void Update()
{
switch (m_state) {
case ChatState.HOST_TYPE_SELECT:
for (int i = 0; i < CHAT_MEMBER_NUM; ++i) {
m_message[i].Clear();
}
break;

case ChatState.CHATTING:
UpdateChatting();
break;

case ChatState.LEAVE:
UpdateLeave();
break;
}
}


void UpdateChatting()
    {
        byte[] buffer = new byte[1400];

        int recvSize = m_transport.Receive(ref buffer, buffer.Length);
        if (recvSize > 0) {
            string message = System.Text.Encoding.UTF8.GetString(buffer);
            Debug.Log("Recv data:" + message );
            m_chatMessage += message + "   ";// + "\n";

            int id = (m_isServer == true)? 1 : 0;
            AddMessage(ref m_message[id], message);
        }    
    }
    

Update部分はチャットを退出するまで繰り返すというものである。
UpdateChatting関数は送受信するメッセージをキャラクターごとのバッファに保存されます。このバッファはm_messageに保管されています。

次にチャットの送受信を行う部分のソースについてです。

void ChattingGUI()
{
Rect commentRect = new Rect(220, 450, 300, 30);
m_sendComment = GUI.TextField(commentRect, m_sendComment, 15);

bool isSent = GUI.Button(new Rect (530, 450, 100, 30), "しゃべる");
if (Event.current.isKey &&
Event.current.keyCode == KeyCode.Return) {
if (m_sendComment == m_prevComment) {
isSent = true;
m_prevComment = "";
}
else {
m_prevComment = m_sendComment;
}
}


if (isSent == true) {
string message = "[" + DateTime.Now.ToString("HH:mm:ss") + "] " + m_sendComment;
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(message);
m_transport.Send(buffer, buffer.Length);
AddMessage(ref m_message[(m_isServer == true)? 0 : 1], message);
m_sendComment = "";
}


if (GUI.Button (new Rect (700, 560, 80, 30), "退出")) {
m_state = ChatState.LEAVE;
}


// とうふやさん(サーバ側)のメッセージ表示.
if (m_transport.IsServer() ||
m_transport.IsServer() == false && m_transport.IsConnected()) {
DispBalloon(ref m_message[0], new Vector2(200.0f, 200.0f), new Vector2(340.0f, 360.0f), Color.cyan, true);
GUI.DrawTexture(new Rect(50.0f, 370.0f, 145.0f, 200.0f), this.texture_tofu);
}

if (m_transport.IsServer() == false ||
m_transport.IsServer() && m_transport.IsConnected()) {
// だいずやさんの(クライアント側)のメッセージ表示.
DispBalloon(ref m_message[1], new Vector2(600.0f, 200.0f), new Vector2(340.0f, 360.0f), Color.green, false);
GUI.DrawTexture(new Rect(600.0f, 370.0f, 145.0f, 200.0f), this.texture_daizu);
}
}

この部分には3つの処理が存在しており1つ目が相手にメッセージを送るもの、2つ目に退出ボタンが押されているかの監視をして押されたときに退出処理をするものです。3つ目にメッセージを受信してそれを表示するものです。

最後に通信を切断行う部分についてです。

void UpdateLeave()
{
if (m_isServer == true) {
m_transport.StopServer();
}
else {
m_transport.Disconnect();
}

// メッセージの削除.
for (int i = 0; i < 2; ++i) {
m_message[i].Clear();
}

m_state = ChatState.HOST_TYPE_SELECT;
}

次に5章のターン製ゲームについてです。
サンプルでは3目並べのゲームを制作して行きます。
こちらのゲームはチャットプログラムのように好きなときに操作できてしまうとゲームとして成り立たなくなってしまいます。
なので相手の操作が終わるまで自分の操作ができないようにする必要があります。しかしそうするといつまでも相手が時間を掛けてしまうとゲームのテンポが非常に悪くなってしまいます。
上記の点について考えてゲームデザインを設計して行かなければいけません
ソースについて書いて行きます。

はじめに自分のターンかを判定する部分です

public class TicTacToe : MonoBehaviour {

// ターン種別.
private enum Turn {
Own = 0,        // 自分のターン.
Opponent,        // 相手のターン.
};

// 現在のターン.
private Mark            turn;

// ローカルのマーク.
private Mark            localMark;

// リモートのマーク.
private Mark            remoteMark;

ここでは自分がマークを置く順番かを判定しています。

次に全体のターンの処理の部分になります

void UpdateTurn()
{
bool setMark = false;

if (turn == localMark) {
setMark = DoOwnTurn();

//置けない場所を押されたときは、クリック用のSEを鳴らします.
if (setMark == false && Input.GetMouseButtonDown(0)) {
AudioSource audio = GetComponent<AudioSource>();
audio.clip = se_click;
audio.Play();
}
}
else {
setMark = DoOppnentTurn();

//置けないときに押されたときは、クリック用のSEを鳴らします.
if (Input.GetMouseButtonDown(0)) {
AudioSource audio = GetComponent<AudioSource>();
audio.clip = se_click;
audio.Play();
}
}

if (setMark == false) {
// 置き場を検討中です.
return;
}
else {
//マークが置かれたSEを鳴らします.
AudioSource audio = GetComponent<AudioSource>();
audio.clip = se_setMark;
audio.Play();
}

// マークの並びをチェックします.
winner = CheckInPlacingMarks();
if (winner != Winner.None) {
//勝ちの場合はSEを鳴らします.
if ((winner == Winner.Circle && localMark == Mark.Circle)
|| (winner == Winner.Cross && localMark == Mark.Cross)) {
AudioSource audio = GetComponent<AudioSource>();
audio.clip = se_win;
audio.Play();
}
//BGM再生終了.
GameObject bgm = GameObject.Find("BGM");
bgm.GetComponent<AudioSource>().Stop();

// ゲーム終了です.
progress = GameProgress.Result;
}

// ターンを更新します.
turn = (turn == Mark.Circle)? Mark.Cross : Mark.Circle;
timer = turnTime;
}

この処理では自分のターンであればマークを配置し、相手のターンであれば相手がマークを配置するのを待ちます。

次に自分のターンの処理についてです。

// 自分のターンの時の処理.
bool DoOwnTurn()
{
int index = 0;

timer -= Time.deltaTime;
if (timer <= 0.0f) {
// 時間切れ.
timer = 0.0f;
do {
index = UnityEngine.Random.Range(0, 8);
} while (spaces[index] != -1);
}
else {
// マウスの左ボタンの押下状態を監視します.
bool isClicked = Input.GetMouseButtonDown(0);
if (isClicked == false) {
// 押されていないのでなにもしません.
return false;
}

Vector3 pos = Input.mousePosition;
Debug.Log("POS:" + pos.x + ", " + pos.y + ", " + pos.z);

// 受信した情報から選択されたマスに変換します.
index = ConvertPositionToIndex(pos);
if (index < 0) {
// 範囲外が選択されました.
return false;
}
}

// マスに目を置きます.
bool ret = SetMarkToSpace(index, localMark);
if (ret == false) {
// 置けない.
return false;
}

// 選択したマスの情報を送信します.
byte[] buffer = new byte[1];
buffer[0] = (byte)index;
m_transport.Send (buffer, buffer.Length);

return true;
}

自分のターンではマウンスからの入力を受け付け配置するマス番号を算出する処理、算出したマス番号にマークを配置する処理、配置したマス番号のデータを相手に送信する処理の3つで成り立っています。

次に相手の処理についてです。

// 相手のターンの時の処理.
bool DoOppnentTurn()
{
// 相手の情報を受信します.
byte[] buffer = new byte[1];
int recvSize = m_transport.Receive(ref buffer, buffer.Length);

if (recvSize <= 0) {
// まだ受信していません.
return false;
}

// サーバなら○クライアントなら×を指定します.
//Mark mark = (m_network.IsServer() == true)? Mark.Cross : Mark.Circle;

// 受信した情報から選択されたマスに変換します.
int index = (int) buffer[0];

Debug.Log("Recv:" + index + " [" + m_transport.IsServer() + "]");

// マスに目を置きます.
//bool ret = SetMarkToSpace(index, mark);
bool ret = SetMarkToSpace(index, remoteMark);
if (ret == false) {
// 置けない.
return false;
}
return true;
}

相手のターンでは相手から配置するマス番号の情報を受信する処理と受け取ったマス番号からマークを配置する処理の2つから成り立っています。

次にゲーム開始についての部分についてです。
ここでゲームの初期化を行います

// ゲーム開始.
public void GameStart()
{
// ゲーム開始の状態にします.
progress = GameProgress.Ready;

// サーバが先手になるように設定します.
turn = Mark.Circle;

// 自分と相手のマークを設定します.
if (m_transport.IsServer() == true) {
localMark = Mark.Circle;
remoteMark = Mark.Cross;
}
else {
localMark = Mark.Cross;
remoteMark = Mark.Circle;
}

最後にエラー処理についてです

// イベント発生時のコールバック関数.
public void EventCallback(NetEventState state)
{
switch (state.type) {
case NetEventType.Disconnect:
if (progress < GameProgress.Result && isGameOver == false) {
progress = GameProgress.Disconnect;
}
break;
}
}
}

この部分は回線切断などのゲームに大きな影響を与えてしまう通信エラーが起こってしまったときに呼び出されます。そしてゲームのモードが切断状態のGame.Progress.Disconnectに変更されます。

現状自分ができたのはここまです。
自分がここまでやるのにはおおよそ5時間くらいかかりました。
サンプルの実行だけならば1時間も必要ないのですがそれの理解となると
オフラインのものと違うところが多く時間がかかってしまいました。
サンプルはネットで配布されているのでそれをダウンロードすれば実行結果もソースもすぐに見ることができます。良ければ本も見ていただければ幸いです。

オンラインゲームを作ろうとしている人の助けになっていれば幸いです。

参考文献
・オンラインゲームのしくみ
「Unityで覚えるネットワークプログラミング」

 

白井研究室セミナーを通して学んだこと(藤澤佳記)

こんにちは。神奈川工科大学情報メディア学科の藤沢です。

まず、私が神奈川工科大学のセミナーについて軽く触れて、それから学んだことを記していきたいと思います。

私が所属する情報メディア学科では、3年次前期に行う授業としてセミナーというものがあります。これは先生ごとに内容の異なる短期のゼミのようなものであり、授業をしながら研究室について学ぶことができます。

私はこのセミナーで白井先生の行うセミナーを選択しました。白井セミナーはIVRCという、日本バーチャルリアリティ学会が主催するコンテストへの企画作品の応募がメインテーマとなっており、私はそれに興味をもち、受講することを決めました。15回という短い期間の中で自身が学んだことや得たことを書いていきます。

初回から3、4回目まではブログの書き方やIVRCの過去の調査を行いました。

IVRCの過去の調査では、過去にどんな作品があったのか、それらを鑑賞しつつ、アイデアやその作品の主たるテーマなど、作品を作るうえで知っておくべき内容を調査するものでした。この結果はブログで報告しました。

ブログは、まさにこうして文章を書く方法を教えていただきました。最初の方ではIVRCの過去の作品の調査結果を報告する手法として紹介していただきました。現在はまとめとして、さまざまな文章を書いています。

5回目以降から10、11回目くらいまでは本格的にIVRCの企画を行いました。

まずチームを決め、そこからチームでの作業が続きます。私のチームは2人で、もう一人は同じ情報メディア学科の古田君という人でした。彼はすごく行動力のある人で、私が何もわからなくて手が出せなくているとき、一人で頑張ってくれていました。そんな彼に引っ張られるように動き出して、何度も試行錯誤を繰り返し、二人で一つの企画書を完成させました。私はこのとき、行動力、積極性の大切さを知り、それらをかなり高めることができました。

IVRCには企画書、及び企画梗概を提出しましたが、私はこれらに取り組むのが初めてであり、わからないことだらけでしたが、白井先生、先輩方、そして他チームの方に添削をしていただき、何度も何度も文章を校正していくことでチームの絆が深まると同時に意見もまとまっていきました。私は文章を何度も校正するうちに、自身には文章を“書く”力があることを発見することができました。眠っていた力が開花したようです。また、古田君と協力し、期限に向けて作業を共にしたり、それだけではなくたくさん迷惑をかけたことや助けてもらったことを含め、チーム、グループの大切さや重要さに気づくことができました。そしていまではチーム、グループワークで仲間と最大限力を発揮して作業に取り組む、そんな自信もあり、企画、そしてそれにむけたチーム作業を身を以て体験することができて本当に良かったと思っています。以下は企画梗概の画像です。

kougai

IVRCに応募した企画は通りませんでしたが、機会があればまた再挑戦してみたいと思っています。

IVRCの結果は、私のチームを含めほかのチームも企画が通らなかったため、自身のやりたいことを残りの授業で行うこととなりました。

私は同じ情報メディア学科の菊崎君とともに白井セミナーの先輩方の論文を添削する、ということを残りの授業で行うことに決めました。

最初に読み始めた時、なんとも難しいことが書かれていて、一人では理解するのが大変で菊崎君と一緒に添削を行っていました。時間もかかっていて効率が悪かったように思います。後々内容が理解できてくると、1つの論文を読む時間が短縮でき、さらに的確な添削ができました。普段、他人の文章をみて添削することはしないので、IVRCの企画作成で発掘した文章力がさらにここで向上しました。

論文添削時の画像を以下に紹介します。

20150729114818

 

文章力はインターンや就活、テストやレポートなど、多岐にわたる分野で存分に生かすことができるため、うれしい気持ちとこれからくるさまざまな課題にわくわくしています。

では、神奈川工科大学のセミナーを通して学んだことをまとめたいとおもいます。

ブログの書き方、企画書についての理解の向上、企画書の書き方、を学び、授業に取り組むうえで文章力が開花し、また、チームワーク、積極的に物事に取り組む姿勢、チャレンジ精神を養うことができました。先輩方とのふれあいや仲間、先生との話し合いの中で、意見を言い合い、ディスカッションにも慣れることができました。私がこのセミナー、そしてこのメンバーで取り組んだ企画や授業で多くのことを学び得て、たくさんの経験ができて、楽しかったし、なにより白井セミナーを選んでよかったと思っています。

最後になりましたが感想を述べたいと思います。

白井セミナーでは授業外かつ課外活動が多くて楽しかったです。白井先生をはじめ、研究室の先輩方や仲間のみんな、周りの人たちの明るい雰囲気が居心地がよくて、素直な気持ちで授業に参加できてとてもさわやかな気持ちです。今回のセミナーで学んだことを今後、フル活用できるように自身の力を高め、さらに多くの経験をしていきたいと思っています。

 

ここまでお付き合いくださり、ありがとうございました。

TEPIA先端技術館にてNHKの生放送をナマ体験(2015/7/18)

こんにちは!神奈川工科大学 情報学部 情報メディア学科 3学年の山口裕太です。

7月18日の早朝4時起きで「TEPIA 先端技術館」に行ってまいりました!
この先端技術館には、様々な分野の先端技術が展示・実演されています。神奈川工科大学の技術も多く展示されています。

IMG_3604
展示風景

今回は白井研究室の「ExPixel」がNHKの番組「おはよう日本」で生中継されるとのことなので、私はその展示のお手伝いをしてきました!

先端技術館に着くと早速NHKの放送車が!

IMG_3596
NHK中継車

NHKの中継車は初めて見ました。車 1 台で全国放送できてしまうんですね!!

我々も早速放送の準備を開始!
「ExPixel」もNHK特別仕様になりました。

IMG_3623
フィルターカット作業
IMG_3622
「ExPixel」NHK特別Ver

 

私たちが放送の準備をしている中、NHKの方々も打ち合わせしてリハーサルを行っていました。生放送なので中継時間に限りがあるため、時間を常に見ながら行っていました。プロの仕事を目の前で見て、リハーサルなどにおいて「他者からのレビュー」というものがどれだけ大切かということをより感じることが出来ました。最初は時間より何十秒もオーバーしていましたが、打ち合わせで「言葉選び」や「会話のテンポ・抑揚」などそのつど変えたり、「カメラワーク」や「各ブースへの導入」など計4回のリハーサルで我々がいつもテレビで見ている中継の形になっていました。
このように、他者の目がないと自己完結にしかなりません。レビューがあればあるだけよりよいものへと変化できます。リハーサルを通して見て、プロの人がいかにそこに力を入れているかを見ることが出来てよかったです。

IMG_3603
リハーサル・打ち合わせの様子

私たちもプロに負けぬよう、ExPixelの説明をアナウンサーさんに説明したりと、本番までの準備を進めていきました。

IMG_3621
アナウンサーさんとの情報共有

全ての準備が終わり、いよいよ本番!
出演するわけではないけれどもとても緊張していました。
いろいろな作品が紹介されていくのですが、ほとんどの技術がうまく動かず・・・。
心配が募るばかりでしたが、ExPixelは何の問題も無く中継することが出来ました!

 

中継が終了し、みんなホッとして拍手していました。NHKの方は「ここがしっかり動いてくれてよかった!ありがとう!」とコメントいただきました。

IMG_3618
中継終了後のホッと一息集合写真 (左からNHKの入田PD、牛田アナウンサー、神奈川工科大学より白井先生、山口、森先輩、柴本さん、富士通SSLの広報中村さんです)

あっという間の体験でしたが、生放送の大変さというものがすごく伝わって来ました。こうやってプロの方の仕事を間近で拝見できたのはとてもいい体験になりました。そこから得たものをこれから意識して役立てていこうと思います!

 

以上で今回のNHK中継のレポートとさせていただきます。最後までご覧頂きありがとうございました!

だれでもわかるUnityインストール方法

こんにちは,神奈川工科大学情報メディア学科3年生の赤羽です.
みなさんUnityというゲームエンジンを知っていますか.
Unityとは統合開発環境(※1)を内蔵し,複数のプラットホーム(※2)に対応する
ゲームエンジンのひとつです.
今回はUnityをインストールしたいけどサイトが英語でわからないという人の為に
インストール方法を図を用いて紹介していきます.

まず,Unityをインストールする前にいくつか知っておかないといけないことがあります.
・Unityには有料版と無料版がある.
・無料版は年度総収入が10万ドルを超える企業や法人は使用できない.
・企業での無料版と有料版の混合使用の禁止.
・30日無料版昨日を使用できるトライアル版で作成したものの販売の禁止.
・無料版と有料版でソフトが分かれているわけでなく有料版プロライセンスを購入して
アクティベーション(※3)すると有料版の機能が使用できるようになる.
以上のことを踏まえて早速Unityをインストールしてみましょう.スライド4
スライド5
スライド6
スライド7
スライド8
スライド9
スライド10
スライド11
以上でインストール方法の紹介を終わります.

最後に,現在自分が読んでいてUnity初心者にお勧めの本を紹介します.

本イラスト(スキャナー)【キャラクタであそぼう! Unity日和。】
この本はUnityのインストール方法やUnityのインターフェイスなどから丁寧に教えて
くれるので本をあまりよまない人でも読みやすくお勧めです.

本の購入はこちらからどうぞ
www.amazon.co.jp/dp/4861008468

 

 

次回はUnityの基本操作について紹介する予定です.
最後まで読んでいただきありがとうございました.

※1 統合開発環境
コンパイラ,テキストエディタ,デバッガなどばらばらで
利用していたものをひとつのGUIから利用できるようにしたもの
[ウィキペディア参照(統合開発環境)]

※2  プラットホーム
コンピュータにおいて、主に、オペレーティングシステム (OS) や
ハードウェアといった基礎部分を指す
[ウィキペディア参照(プラットホーム)]

※3 アクティベーション
機能を有効にする,正規のライセンスを持っていることを証明する
[IT用語辞典参照(アクティベーション)]

7/3 コンテンツ東京に行って来ました!

こんにちは!神奈川工科大学 情報学部 情報メディア学科 3学年の山口裕太です。

7月1~3日に東京ビッグサイトにて行われた「コンテンツ東京2015」に行ってまいりました。

IMG_3478

このイベントは、主に企業の方の商談のためのものなのですが、私は大学の授業の一環として先進技術を実際に触れてみようと思い、7月3日にこのイベントに参加させていただきました!

この「コンテンツ東京」では、6つの商談展が同時に行われています。「第4回 クリエイターEXPO」「第3回 プロダクションEXPO」「第1回 コンテンツマーケティングEXPO」「第5回 キャラクター&ブランドライセンス展」「第3回 制作・配信ソリューション展」「第1回 先進コンテンツ技術展」の6つです。私はその中で「第1回 先進コンテンツ技術展」を主に見学して来ました。

IMG_3494

このイベントの中で、私が見て・感じてきたものの一部を紹介したいと思います!

クリプトン・フューチャー・メディア株式会社

ミストプロジェクションシステム「Thru Graph」

IMG_3487

霧を下から吹き上げ、空気の膜で包んだスクリーンに、背面からプロジェクタで映像を投影することによって「ホログラムのような存在感のある映像を空間に投影できる」システムです。この装置は霧を吹き上げているだけなので自由に通過することが可能になっています。

私がこのブースの前に来たときに一番目に目に付いたのがこのシステムでした。下から霧が出てきて、そこに「初音ミク(同社開発 DTM ソフトウェアのキャラクター)」が投影されて驚きました。浮かんで見えるシステムはいくつか見て来ましたが、どれも装置は大きかったです。しかしこの装置は、地面とプロジェクタしか場所がとらないのでさまざまな使い方が出来そうです。アミューズメントパークなどにあったらとても目を引きますし、面白そうです。

 

リアルタイム 3DCG コントロールシステム「R3」

IMG_3489IMG_3488

モーションのデータや表情の動きなどをリアルタイムでコントロールできるシステムです。ライブ演出などのその現場の状況に合わせて自在に変化することが可能になっています。また、展示装置の「R3フィルム」は、映像プロダクション専用に開発された透過スクリーンとなっており、軽量でさまざまなサイズに対応することが出来ます。このシステムが実際に使われた例としては冨田勲さんの「イーハトーヴ交響曲」や、BUMP OF CHICKENさんの曲「ray」などでこの技術が使われていました。

このシステムを以前に聞いたことはあったのですが、実際に目にしたのは初めてでした。透過スクリーンに鮮明に映し出す技術や、リアルタイムで「初音ミク」の表情などを変化させることが出来る技術は体験してみてとても驚きました。コンサートシステムのみならず、他方で面白さを提供できるすばらしいシステムだと感じました。

 

こういった「新しい技術」を目の当たりにして、この先の未来のエンタテインメントがより楽しくなっていくと感じました。これからも技術が生まれていく中で、このような「エンタテインメントシステム」を私も開発できたらいいなと、こっそり闘志を燃やしたいい体験でした。頑張っていきたいです!

それでは最後までご閲覧ありがとうございました!

IVR展に行きました/が・・・・!?

こんにちは、神奈川工科大学 情報学部 情報メディア学科3年の強矢です。

6月25日(木)、東京ビッグサイトで行われた「3D&バーチャルリアリティ展」と
「設計・製造ソリューション展」に特別公演に行ってきました。

今回はセミナーで授業として参加させていただきました。
が、当日にスマホがショートを起こし、1日携帯が使えず、
現地の写真をとることができませんでした
あの時に充電しておけばと後悔しつつ・・・・

といっても取り返しはつきませんので、
私が興味を持ったブースを紹介します。

写真は先生から提供されたものです。


  
  

『クレッセント』
www.crescentinc.co.jp/mail/2015/0616/
4Kのディスプレイに車の表示を行っており、どの角度からでも忠実に再現されており、
車の部品からヘッドライトの反射、森や岩などの背景が車に反射するところまで
再現されていました。

  
  
 実際に写真残せなかったのが残念です。

来年こそも期待しつつ、必ずスマホの充電とカメラを持っていきたいと思います。