講演ファイル(PDF)

運営中のモバイルゲームを
Newニンテンドー3DS™へ移植中!
よくある問題とその対策
ニンテンドー3DSは任天堂の商標です。
Yusuke Kurokawa
Unity Technologies Japan
本講演について
• 現在運営中のモバイルゲームタイトル「ドラゴンファン
グ ~竜者ドランと時の迷宮~」をNewニンテンドー3DS
へ移植するためのサポートを行って得たノウハウをお話
しいたします。
Unity for Newニンテンドー3DS について
• Newニンテンドー3DS向けソフトの開発が、Unityで出来
るようになりました
• スペックさえ満たせば、ニンテンドー3DS向けのソフトとしての
出力も可能です
• Unity5ベースでの動作(5.1、5.2β版)
• β版では製品のリリースを行うことが出来ません
• 任天堂への開発者登録をすることで開発可能
サポート中のタイトル
「ドラゴンファング」について
・運営型のローグライクRPGゲーム
・ダンジョン追加/キャラ追加/イベントダンジョ
ン/ガチャ 等、運営型ゲームの要素あり
・2Dメインのゲーム
・描画は殆どNGUIで構成、一部にSpriteStudioが使
用されている
Newニンテンドー3DSへの移植時に
考慮する事
•
•
•
•
•
•
•
IL2CPPでの動作のみサポート
二画面対応(上側画面は立体視)
解像度変更対応
ボタン操作への対応
WebViewの代価手段の検討
Shader対応
少ないメモリ空間
IL2CPPのみサポート
• IL2CPP環境下では、Emitなどの動的に命令を生成する
Reflectionの機能が使えない
• iOSも製品リリースはIL2CPPのみなので、iOSでリリース出来て
いれば大きな問題ではない
※1.各種アセットはNewニンテンドー3DSの考慮がされていないの
で、defineを見直す必要がある
※2.IL2CPPとなったので、パフォーマンスに関しては問題が出な
かった
二画面対応について
上画面表示用のカメラと下画面
表示用のカメラを二つ用意し
て、対応する必要がある
今回は別シーンを用意した
パーツ単位で使いまわしをして
画面を再構築した
※画面は開発版です
立体視対応について
・上画面は、エンジン側で立体視に対
応している
・立体視機能を使うかどうかを
PlayerSettingsにて変更可能
⇒今回は立体視を行わない対応を予定
解像度変更対応について
・400×240(上画面)、320×240(下画面)へ
画面の解像度が変わる
・テクスチャの解像度を下げて表示対応
が可能
・テクスチャの解像度変更はTextureの
Inspector上で、プラットフォーム別の指
定が可能
解像度変更対応について②
・ファイルパスのルールに応じて、
Textureの最大サイズを変更するツー
ルを作成
・上から順にファイルパスがマッチする
か検索し、該当するルールだった場合、
指定されたTextureサイズにする仕組み
・これにより特定のファイルだけは解像
度を下げたくないなども可能に
解像度変更対応について③
・テクスチャの解像度を変えたら、
NGUIのAtlasが崩れた
・NGUIのAtlasに元々どのテクスチャ
サイズで作成されたかという情報を
埋め込み、表示側のソースをいじる
ことで解決
ボタン操作への対応
• ボタン操作の取得は、UnityのInputManagerで可能
• どうボタン操作を行うかは二画面化対応と合わせて、企画段階でど
うしていくか検討の必要あり
WebViewの代価手段の検討
・運営型ゲームではよく使われるWebViewでの
HTML表示は、そのまま持ってくることが出来ない
⇒お知らせのフォーマットを決めて、テキストや画
像を表示する専用ダイアログの作成が必要
Shader対応
• Newニンテンドー3DSでは、プログラマブルなpixel
shaderがなく、固定機能の組み合わせで表現される
• そのため、うまく絵が出ないShaderも出てくる
• 今回は2Dメインだったので大きな問題にはならなかった
• Sprites/Default にすれば大体問題ない絵が出た
少ないメモリ空間
• テクスチャの解像度を下げたことで大分減ったものの、
未だ足りない。
• 運営型のモバイルゲームでは常識なやり方が、実は多大
なメモリ負荷になっている
運営型モバイルゲームでは常識でも、
多大なメモリ負荷となっている所
•
•
•
•
巨大なJSONデータ
www.texture によるバナー表示
圧縮形式のアセットバンドル
沢山のSpriteオブジェクト
巨大なJSONデータ
• 多くのモバイルタイトルで採用されているJSONフォー
マットだが、実はかなりメモリを持っていく
• 殆どのJSONを扱うアセットが、一度DOMツリーに展開
してからアクセスをさせる形式になっている
• JSON[“test”]のような形でアクセスできる場合、これに該当
• この場合、JSONデータサイズの倍以上のメモリが消費される
DOMツリーに展開されたJSONデータ
object
{
“str”:”HelloWorld”,
“arr”:[ 100,102 ]
}
という文字列は右図のように展開さ
れる。
文字列と右図のグラフが同時にメモ
リ上に存在することになるので倍以
上のメモリが消費される
“str”
“arr”
“HelloWorld”
array
100
102
巨大なJSONデータへの対応
• マスターデータ(ゲームの設定に関するデータ)が巨大
だったので、Protocol Buffersへ変更してもらった
• データサイズが半分以下になった上に、直接オブジェク
トに値を入れることになり、使用メモリは激減
www.texture によるバナー表示
・UnityEditorを介さずに、バナー設定が出来るので
かなり多く使われている手法
・wwwのtextureは、無圧縮(RGBA32bit)のTextureが
メモリ上に展開される
・更に2の累乗サイズで作成しようとするため、テク
スチャサイズを膨らませます
• 例:130×65 ⇒ 256×128
www.texture への対応
• アセットバンドルとして作成して、表示する方法に切り
替えを予定
圧縮形式のアセットバンドル
• 5.2以前では、圧縮形式のアセットバンドルを扱うとき
に、C#ヒープメモリ上にデータを展開しないと圧縮形
式のアセットバンドルを使えなかった
• 圧縮前と圧縮後のデータを二重持ちになりメモリを圧迫
var bindata = File.IO.ReadAllBytes( path );
var asset = AssetBundle.CreateFromMemory( bindata );
圧縮形式のアセットバンドルへの対応
• 無圧縮形式のアセットバンドルをロードするように修正
var asset = AssetBundle.CreateFromFile( path );
沢山のSpriteオブジェクト
・Mapの1マス毎に、Sprite付の
GameObjectが生成されていた
・いくつかのレイヤーに分けて表示もさ
れているので、相当数のGameObjectと
Spriteがシーン中に存在している状態
沢山のSpriteオブジェクトへの対応
• 1つのGameObjectでマップのレイヤーを一括で表示するNGUI拡張
機能を独自で実装をした
• この対応により、1MBほどのメモリが削減。更に処理速度も向上
Game Objects in Scene 3128 => 2047
Total Objects in Scene 11648 => 7733
その他 メモリ周りでの対策
• Fontデータがメモリを圧迫していたので、DynamicFont
ではなく静的なFontに差し替え
• AudioManagerの設定を見直し
• マスターデータを読み込むタイミングの見直し(起動直
後に全てを読み込まない)
メモリのボトルネックを探すTips①
・Unity標準のProfilerでひたすら
チェック
・Deep Profileを利用して、どこで
メモリを消費しているのか細かく
チェック
メモリのボトルネックを探すTips②
・Unityが提供するMemoryProfiler
を使ってメモリの情報をチェック
(Unity5.3以上でないと動かないため、
プロジェクトを5.3のEditor上で動かし
て確認した)
https://bitbucket.org/Unity-Technologies/memoryprofiler/
メモリ周りボトルネックを探すTips③
・シーン中にあるComponentを調べ
るComponentCounterというツール
を作成
・明らかに多いComponentをチェッ
クして調べる
https://github.com/wotakuro/ComponentCounter
まとめ
• Newニンテンドー3DS向けソフトの開発がUnityで可能に
なっています
• モバイルゲームから移植する際は、2画面対応/ボタン操作対応等
コンテンツ側での対応が必要になります
• モバイルゲームでのやり方が実はメモリを大きく圧迫しているの
で、メモリが足りない場合は見直しが必要です