テーマ:

SGE(Smartphone Games & Entertainment)のグレンジ所属の塚原と袴田です。

 

2016/04/20に開催されたリアルタイム通信ゲーム勉強会で発表してきたので報告をします。

 

グレンジについて

CAのゲーム事業部(SGE)の中の1つです。

ポコロンダンジョンズ

イグドラシル戦記

の2つを開発・運営しています。

勉強会ではポコロンダンジョンズの共闘(多人数の協力プレイ)の仕組みについて発表しました。

 

ポコロンダンジョンズについて

2014年夏にリリースされた「なぞるパズルRPG」です。

当初は1人プレイのみでしたが、2015年春に最大4人の協力プレイ「共闘」が実装されました。

共闘はSocket.IOを使ったリアルタイム通信システムによって動作していて、勉強会ではサーバサイド/クライアントサイドの仕組みを「そこまで見せるのか」というほど公開しています。

 

サーバサイド編(発表者:塚原)

主に、利用技術、サーバ構成、やりとりしているデータを例にどのようにマルチプレイを実現させているのかを説明しています。

サーバサイドは非リアルタイム通信部分をPHP、リアルタイム通信部分をNode.js(socket.io)で構成されているので、その棲み分けの話もしています。

ちなみに、発表の数日後に仕組みを改修し、課題としていたNodeプロセスのCluster化を行いました。(なので、発表資料の説明の一部は古いです)
1コア1ワーカプロセスでサーバを並べていたのを4コア4ワーカプロセスにしてサーバー台数を削減しています。

発表資料

 

クライアントサイド編(発表者:袴田)

こちらは利用技術、構成、発生した問題と解決方法の話を織り交ぜながら、どのように端末間での同期を実現しているのか処理の流れを追いながら説明しています。

クライアントサイドはcocos-2dxとsocket.ioでリアルタイム通信をしているのですが、ソケットが切断されてしまった際の復旧や、端末間で盤面にズレが生じた際の仕組み、通信データ量を抑えるためにどうしているのか、乱数を各端末で同期する仕組みの話とポコロンダンジョンズのリアルタイム通信のキモになっている部分の多くを公開しています。

発表資料

 

さいごに

今回はポコロンダンジョンズで行っているリアルタイム通信について公開しました。

自分達なりに試行錯誤してきた結果ですが、別の方法はあると考えています。

何かご意見等あれば是非お願いします。

 

 
いいね!した人  |  リブログ(0)
同じテーマ 「ゲーム」 の記事

テーマ:

 

ゲーム技術戦略室のミカエルキュン佐藤です。

 

この度、サイバーエージェントグループで、ゲーム関連の最新技術ばかりを扱う新しい組織「ゲーム技術戦略室」を立ち上げました。

宣伝も兼ねてブログを書かせていただきたいと思います。

 

ゲーム技術戦略室では、UnrealEngine・Amazon Lumberyard・CryEngineといったゲームエンジンだったり、Oculus Rift・HTC Vive・Play Station VRといったVRの話だったり、さらにはAppleTV・AppleWatch・ChromeCast・Leap Motion・Theta Sといったガジェット系などなど、色んな最新技術に対してガツガツ攻めていきます。

 

技術戦略室で取り組んだ調査や制作物に関しては、下記の公式ブログにて展開していきますので、ブックマークをお願いいたします!

 

TechnoloGEEK ~ゲーム技術戦略室 公式ブログ~

 

さて、前置きはこのくらいにして、実際に技術に触れていきたいと思います。

今回は”UnrealEngine+MMD+VR”を題材にします。

 

Unreal Engineに触れてみる

 

 Unreal Engineという統合開発環境をご存知ですか?昨年7月に発表された、「FINAL FANTASY VII REMAKE」がUnreal Engine4を採用したというニュースを耳にした方も多いのではないでしょうか?このニュースがUnreal Engineのランチャーメニューに表示されていたのを見て私たちも心が踊りました。また、Unreal Engineは昨年3月より誰でも無料で利用することが可能となりました。その影響により、企業だけでなく多くの一般ユーザによるUnreal Engineを使った開発が活発になったように思えます。最近では「UNREAL FEST」や「Unreal Engine MeetUp」などUnreal Engineに詳しい方たちによる講演が各地で行われています。

 

Unreal Engineでここみんを踊らせてみる

 「ここみん」とは、Amebaによって運営されているスマートフォン向けソーシャルゲーム「ガールフレンド(仮)」に登場する「椎名心実」というキャラクターです。

 

 

 このように、Unreal Engineは簡単にVRプレビューができますし、MMDのモデルを使うことによって好きなキャラクターを動かすことも容易です。マーケットプレイスで販売されているアセットの数も徐々に増えてきているので、プロダクトの開発速度も加速していくことでしょう。

 

Unreal Engineでここみんを操作するためにやったこと

 

 今回、Unreal EngineにMMDモデルを読み込むために利用したものとしては、IM4UプラグインによるMMDモデルインポート、MMDとMMDBridgeを使ったモーションデータの出力となります。ここからは実際に行った手順をスクリーンショットと併せて説明していきます。

 

開発環境

Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz
実装RAM 16.0GB
64ビット オペレーティングシステム
Windows 8.1 Pro
Unreal Engine 4.10.4
Oculus Rift DK2
Unreal Engineの新規プロジェクトにて利用したテンプレート:Third Person

 

 

使用したモデルは下記書籍に収録されています。

 

 

 

使用したモーションは下記の通りです。ありがとうございました。

 

モーション名作者
H57_SO_女の子走り速め_s2500_p20.vmdsusuki様
歩行モーション_おんな_ゆっくり.vmdノラ様
11.やったぁ.vmdおかっち様
rea_stand.vmdあー、とり様
海自っぽい敬礼(海自).vmdMcDuck<めぐみ>様
ようかい体操第一_配布用.vmdjmccmy様

 

Unreal EngineでOculus Riftを使う前に

 Unreal Engine4.10.4では、Oculus Runtimeのバージョンが0.8でなければVRプレビューを利用できませんでした。Oculus Runtime のインストール後はコンピュータを再起動しましょう。(※Unreal Engine4.11以降の場合は Oculus Runtimeのバージョンが0.8で動作しません。公式サイトより最新のRift Runtimeをインストールして下さい。)

 

 

Unreal EngineでMMDモデルを読み込む

 モデルインポートには、Unreal EngineにMMDモデルをインポートする時に便利なIM4Uプラグインを利用しました。こちらは、GitHubからアクセスすることができます。ご利用のUnreal Engineのバージョンに合ったプラグインを取得して下さい。


作者:bm9様
MIT License

https://github.com/bm9/IM4U/tree/4.10.X


 ダウンロードしたIM4Uプラグインは、作成したUnreal Engineプロジェクトのフォルダ内に「Plugins」フォルダを作って中に入れます。

 

 

 

 KokominTest.uprojectを起動し、上部メニューの「編集>Plugins」からIM4Uプラグインが有効になっているか確認します。チェック操作をした場合は、一度エディタを再起動して反映させます。

 

 

 

 

 コンテンツブラウザ(ウィンドウ>コンテンツブラウザ)を開き、お手持ちのMMDモデルデータをドラッグアンドドロップしてインポートします。MMDインポートオプションでは、「Import Morph Targets」、「Import Materials」、「Import Textures」にチェックを入れて「Import All」ボタンをクリックして下さい。

 

 

 

 スケルタルメッシュを開くと「メッシュに有効なスケルトンがありません。新しいスケルトンを作成しますか?」と表示されますが「はい」をクリックして問題ありません。シェーダーのコンパイルが終わるとモデルが表示されるはずです。

 

 

 

ここみんにモーションを付ける

 ここまでの操作でモデルデータを読み込めましたが、まだ動作モーションが付いていないので歩いている動きなどを表現することができません。そこで、Unreal Engineでインポートしたモデルに適用可能なモーションデータを作っていきます。モーションデータの作成方法については「【MMDBridge】 VMD出力機能」という作者による投稿動画が参考になります。「元々人柱向けのプラグインのため、運が悪いと動かないこともあります」とも書かれているので、残念ながら確実に動作するという保証は無さそうです。また、「Unreal Engine4でMMDモデルに表情を付ける方法」にて操作手順を記しているので必要であればご覧になられて下さい。

 


 無事にインポートできると、スケルタルメッシュのアニメーションタブを開いたときに、アセットブラウザウィンドウ内でアニメーションシーケンスがある事を確認できます(スクリーンショットでは4つのモーションデータをインポートしています)。これを使ってキャラクターの動きを制御していきます。

 

 

ここみんの動作を制御する

歩行モーションを設定する

 今回は歩行モーションの作成に、単一の入力値に基いてブレンドされる「ブレンドスペース1D」と呼ばれるアセットを使います。ブレンドスペース1Dを作成したいフォルダで下図のように選択して下さい。

 

 

 

 スケルトンを選択するように促されるので対象のスケルトンを選択します。

 

 

 

 ブレンドスペース1Dを開くと、中央下部にアニメーションシーケンスを配置できる一本の線が確認できます。赤い枠内にアニメーションシーケンスをドラッグアンドドロップして下さい。

 

 

 

 「椎名心実_待機_椎名心実_Skeleton2」を配置したのが下図になります。プレビュー中のここみんが動き始めました。

 

 

 

 次に、待機モーションをドラッグアンドドロップした場所から少し離した場所に、歩きモーションをドラッグアンドドロップします。すると、X軸を移動させることで自然に待機モーションから歩きモーションに切り替わっていくことが確認できると思います。

 

 

 

 最後に、歩きモーションをドラッグアンドドロップした場所から少し離した場所に、走りモーションをドラッグアンドドロップします。

 

 

 

 以上で歩行モーションの作成は完了です。

 

ジャンプモーションを設定する

 ジャンプモーションは待機モーションと異なり、3つのアニメーションコンポジットに分割する必要があるので少し手間がかかります。まず、アニメーションコンポジットを作成したいコンテンツブラウザ上で右クリックして下図のように選択します。こちらもブレンドスペース1D同様に、スケルトンを選択するよう促されるので対象のスケルトンを選択しましょう。

 

 

 

  ここでは、JumpStartAnimComposite、JumpLoopAnimComposite、JumpEndAnimCompositとして3つ作成しておきました。まず、JumpStartAnimCompositeを開いてみると下図のような画面が表示されるので、赤い枠内に「椎名心実_ジャンプ_椎名心実_Skeleton2」をドラッグアンドドロップします。

 

 

 
 すると、ここみんがジャンプを開始します。しかし、JumpStartAnimCompositeにはジャンプを開始してから一番高い地点になるまでのモーションを設定したいので、開始時間と終了時間を設定してアニメーションシーケンスから切り取りましょう。上記スクリーンショットの赤い枠内に表示されているコンポジットトラックの上部分をクリックすると詳細ウィンドウが表示されます。この詳細ウィンドウで開始時間と終了時間を指定できるので、それぞれ「0.0」、「0.536」に設定しました(0.536秒の地点がジャンプしてから一番高い位置だったためです)。

 

 

 

  JumpLoopAnimCompositeにはジャンプ中の状態を設定したいので、開始時間と終了時間を共に「0.537」に設定しておきます。

 

 

 

  JumpEndAnimCompositにはジャンプ中からジャンプ終了までのモーションを設定したいので、開始時間と終了時間をそれぞれ「0.538」、「1.35」に設定しました。

 

 

 

 以上でアニメーションコンポジットの設定は完了です。次に、アニメーションブループリントを使ってここまで作成してきたアニメーションアセットを状態によって切り替えていきます。これにより、ここみんが動いていない時は待機モーションが実行されたり、空中にいる時はジャンプモーションが実行されたりといったことが可能となります。

 

アニメーションブループリントを設定する

 アニメーションBP(ブループリント)はドキュメントによると、スケルタルメッシュのアニメーションを制御するグラフとのこと。アニメーションBPには「EventGraph」と「AnimGraph」という2つの主要コンポーネントがあり、この2つが連動して各フレームの最終アニメーションが作成されます。アニメーションBPを作成したいコンテンツブラウザ上で右クリックして下図のように選択します。

 

 

 

 対象のスケルトンを選択して生成されたアニメーションBPを開きましょう。

 

 

 

 下図の赤の枠で囲まれたノード(最終アニメーションポーズ)に流し込まれたアニメーションポーズをここみんがやってくれることになります。ですので、流し込むアニメーションポーズを条件によって切り替える必要があります。

 

 

 

 今回はステートマシーンを使ってキャラクターのアニメーションを切り替えていきます。アニムグラフタブ内のどこかで右クリックして「新規のステートマシーンを追加...」を選択します。

 

 

 

 生成されたステートマシーンノードを最終アニメーションポーズに接続し、ダブルクリックして「Kokomin State Machine」(名前は変更しました)を開きます。

 

 

 

 「Kokomin State Machine」内では、既に作成している「歩行モーション」、「ジャンプスタートモーション」、「ジャンプループモーション」、「ジャンプエンドモーション」の状態を作ります。これらの状態を条件によって切り替えることで、最終アニメーションポーズに最適なアニメーションポーズを流し込みます。「Kokomin State Machine」内のどこかで右クリックして「ステートを追加...」を選択します(名前には分かりやすいものを付けます)。

 

 

 

 生成された状態をダブルクリックで開くと、最終アニメーションポーズノードがあることを確認できます。最終アニメーションポーズに流し込まれたアニメーションポーズが、この状態から出力されるアニメーションポーズとなります。ステートの名前に「Wait/Walk/Run」と付けたので、歩行モーションアセットをアセットブラウザからドラッグアンドドロップして最終アニメーションポーズに接続します。

 

 

 

 「KokominBlendSpace1D」ノードには入力ピンがありますが、これが「KokominBlendSpace1D」を開いたときに表示されていた、アニメーションを滑らかに切り替える線のX軸の値です。入力する値をここみんの移動速度によって変化させたいので「Speed」という変数を作ります。変数はマイブループリントタブの変数項目で追加できます。

 

 

 

 Speedには値を代入していく必要があるのですが、今回はThirdPersonテンプレートを使っているので、「Mannequin>Animations>ThirdPerson_AnimBP」を参考にします。

 

 

 

 グレーマンアニメーションBPのイベントグラフタブを見ると、ここみんに必要な実装が載っているので全てコピーします(実際ステートマシーンもグレーマンアニメーションBPと同じように実装すれば問題ないです)。この時、「IsInAir?」という変数が無いので作っておきます。

 

 

 

 この状態で左上の保存とコンパイルを実行すると、プレビュー中のここみんが動き出します。まだジャンプの状態は作っていませんが、動作確認をしたいのでデフォルトのキャラクターとここみんを入れ替えてみます。コンテンツブラウザの「ThirdPersonBP>Blueprints>ThirdPersonCharacter」を開いて下さい。

 

 

 

 ビューポートタブを選択してグレーマンをクリックすると、自動的に詳細タブが開かれます。詳細タブ内の「Mesh」項目でスケルタルメッシュを設定できるので、作成したここみんのスケルタルメッシュを選択すると...

 

 

 

 表示されるキャラクターがここみんになりました!アニメーションが再生されていないようなので「Animation」項目の「Anim BluePrint Generated Class」で「KokominAnimBlueprint」を選択します。これでここみんが動き始めるはずです。

 

 

 

 ゲームをプレビューしてみます。うむ...良い。

 

 

 

 ただ、待機モーションから走りモーションまでの遷移が早過ぎるので、「KokominBlendSpace1D」のX軸範囲を修正します。これでモーション遷移の違和感が抑えられました。

 

 

 

 ...と、完成した感が半端ないのですがジャンプの状態を作りましょう。作成したジャンプモーションアセットに対応した状態を作りたいので、「JumpStart」、「JumpLoop」、「JumpEnd」という3つの状態を作りました。

 

 

 

 まず「JumpStart」の設定です。アセットブラウザから「JumpStartAnimComposit」をドラッグアンドドロップして最終アニメーションポーズに繋ぎます。この時、デフォルトでループアニメーションのチェックが入っているのでチェックを取り除いておきます。これで設定は終わりです。同様の設定を「JumpLoop」、「JumpEnd」にも適用しておきます。

 

 

 

 次に作成したノードを線で繋がなければなりませんが、ジャンプという動作は歩行モーション中であればいつでも実行させたいので、「Wait/Walk/Run」ノードから「JumpStart」に繋ぎましょう。

 

 

 

 線を繋ぐとトランジションルール(遷移させるための条件)を付けることが出来ます。繋いだ線をダブルクリックして編集します。JumpStart状態には、ここみんが空中にいる時に遷移してほしいので、先ほど追加した「IsInAir?」を繋ぎましょう。

 

 

 

 次に、「JumpStart」と「JumpLoop」を繋ぎます。

 

 

 

 ここでは特に必要な条件がないので「Time Remaining」ノードを利用します。このノードを利用し、「JumpStartAnimComposit」の残り再生時間が0.1以下を切ったら「JumpLoopAnimComposit」に遷移するようにしました。「<」ノードは右クリックメニューで「<」と検索すると見つかります。また、ノードを整列する機能がありますので積極的に使っていきます!

 

 

 

 次に、「JumpLoop」と「JumpEnd」を繋ぎます。

 

 

 

 JumpEnd状態には、ここみんが空中にいない時に遷移してほしいので、「IsInAir?」の逆を条件としておきます。「Not」ノードは右クリックして表示されるメニューで検索すると見つかります。

 

 

 

 最後に「JumpEnd」と「Wait/Walk/Run」を繋ぎます。

 

 

 

 この遷移も特に必要な条件がないので「Time Remaining」ノードを利用します。条件については違和感のない見た目になるように秒数を調整しました。

 

 

 

 保存してコンパイルすればゲームプレビューにてここみんを自由に操作できるようになっています。状態を1つ追加すればここみんを踊らせることも容易です。

 

じっくり見る

敬礼!

 

 

 

 

いいね!した人  |  リブログ(0)

テーマ:

Goðan daginn!(こんにちは!)

秋葉原ラボのY.F.です。

 

ゴールデンウィーク、みなさんいかがお過ごしでしたか?

ブルーラグーン

アイスランドまで足を伸ばしてみました。

さて、連休明けにブログを書けと言われたもので、帰りの機内でぽつぽつ執筆しているのですが…

今回は、音楽から様々な特徴や情報を取り出すツール兼ライブラリ"OpenSMILE"で色々と遊んでみることにします。

※OpenSMILEは個人・研究(企業での基礎研究も含む)用と商用ではライセンスが異なります。今回はあくまで基礎研究として取り扱っています。

まずはOpenSMILEのダウンロードはこちら。[1]

おおむね、音楽分析の流れとしては

  • 音楽(=サンプリングされた数値の列)を入力
    • →これを基に一部情報を取得
  • フーリエ変換でもって周波数単位のデータに変換
  • 各種分析を行って結果を出力
  • 様々な曲の結果データから音楽の特性を判定したり、類似する音楽を探しだしたりする

となります。


今回はOpenSMILEの中の手法を使って、音楽の主旋律を取り出す処理を試してみることにします。とはいえ実際の曲を使うと色々と大変なのでテストデータ[2]で。
以下の図のように進めていきます。

(0) 元データの波形 元データ

(1) 時間単位に分割→窓関数をかける

音楽データを一定の秒数ごとに分割します。分析したい周波数領域によって長さを調整します。音楽であれば50ms-200ms程度。今回は50msごとに、前後50ms(合計100ms)ずつ分割しておきます。

さらに前後のデータの干渉をある程度取り除くために関数を掛け合わせます。

(2) フーリエ変換→周波数スペクトルを算出

大学で理工系を履修された方には聞き覚えがあるんじゃないかと思いますが、一応(離散フーリエ変換について)ざっくり書くと、ある数値ベクトルx_i(i=0, 1, ..., n-1)に対するフーリエ変換は

となります。これをうまいことバタフライ演算などでコンピュータ上で計算するもとを高速フーリエ変換(FFT)というわけですね。

フーリエ変換によって、元の波形データからは1波長~(データ数/2)波長の周波数ごとの強度が理屈の上では取得できます。

計算上、(1)で分割したデータからは、1波長=1/0.1(/s)=10Hz以上のデータが取得できることになるはずです。

今回のテスト用の音楽は22kHzがサンプリング周波数なので、上限は自ずと半分の11kHzになります(ナイキスト周波数)。

(3) 音程ごとに集約

現代音楽で一般的に使われている(と思われる)平均律は、A(ラの音)=27.5Hz の2の累乗をベースに、1音ごとに"2の1/12乗"ずつ積み上がっていくようになっています。

これを踏まえて、(2)で算出した周波数スペクトルを音階ごとに振り分けていきます。

Subtone結果

(4) CHROMA

(3)の結果をオクターブを外した音階(ドレミ…)ごとにまとめます。

CHROMA結果

(5) 主旋律を選択

(4)のうち、分割した単位ごとに最大の音階を計算すれば完成です。

CHROMA最大値(全域)

拡大してみると

CHROMA最大値(先頭25秒)

(3)の段階でも最大値を取ってみるとMIDIのようにデータが取れている(気がします)。

Subtone最大値(全域) Subtone最大値(先頭25秒)

いかがでしょうか? 簡単でしたが、皆さんもお試しあれ。

ただし著作権のある市販の音楽などで試す場合はあくまでも個人で楽しむ範囲にしましょう。

今回はゴールデンウィーク明けということで、こんな感じで失礼しますm(_ _)m

 

参考

いいね!した人  |  リブログ(0)