テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

uGUIでノベルゲームのようなものを作る、その2 コマンドによる挙動の管理

uGUIでノベルゲームのようなものを作る…の続きです。

今日はコマンド周りをやります。


uGUIでノベルゲームのようなものを作る。その1 - テラシュールブログ

f:id:tsubaki_t1:20141207115423p:plain

 

シナリオをテキストファイルから読み込む

ノベルゲームのようなゲームの多くは、シナリオをテキストファイルで格納します。これは単純にシナリオライターが一番楽な方法がテキストエディタであるという事に依存します。

 

とりあえずテキストファイルをUnityから取得する方法を考えます。

  1. System.IO.FIle.ReadAllTextで取得する*1
  2. WWWクラスでWeb(もしくはローカルストレージ)から参照する
  3. Resources.Loadで取得する
  4. 直接参照する

今回はResources.Loadで取得する方法を選択肢します。

後は、テキスト制御のTextControllerとシナリオ制御のScenarioManagerに分割します。

 

改行でテキストを区切っても良いのですが、複数行の表現が難しくなるため改行タグ(@br)を使用しテキストを区切ることにします。

その際、改行のみの空行が出来てしまうので、それらの文字列は排除します。

 

ちなみに参照関係の構築が面倒くさいので、マネージャーは全部シングルトンにしてしまいます。

tsubakit1.hateblo.jp


超簡単なテキスト制御4

 

あとは作成したコンポーネントを適当なオブジェクトに配置し、以下の様なテキストファイルをResources/Scenarioフォルダに 配置すると、シーン起動時に読んでくれるようになります。

吾輩(わがはい)は猫である。
名前はまだ無い。

@br

// これは冒頭のセリフです。

どこで生れたかとんと見当(けんとう)がつかぬ。

@br

何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。 // と思っているのか? 

 

コマンドの制御

 コマンドの制御は、表示する行が特定の文字列を持っていた場合、その文字列を消してコマンドを実行する処理で行います。

本当はこの手の処理は事前にScriptableObject等に出力しておいて読むほうがCPUに優しいですが、ここでは面倒なので説明しません。今のモバイルやPCの性能だとココを頑張っても余り意味無いですし。

 

コマンドの実行方法ですが、EventとかSwitchとかSendMessageで一括コールとか色々とやり方がありますが、今回はCommandパターンで行きます。

 

コマンドの構文は最も簡単な(頭に@)の行ならコマンド処理にまわし、その後のテキストを正規表現で確認し一致するならコマンド実行…という感じの方法を使います。

正規表現を使うことで、コマンドの中身をかなり柔軟に読み込むことが出来ます。

例えば、(\\S+)=(\\S+)正規表現判定を行えば、◯◯=△△のような文書を判定し、◯◯と△△の内容を取得することが出来ます。これで取得した値はDictionaryにでも入れておきます。

何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。 // と思っているのか?

@br

// 名前がLayer1のレイヤーで画像「01_1」を表示する

@img name=Layer1 image=01_1

吾輩はここで始めて人間というものを見た。

 

後は各Commandオブジェクトに取得したコマンド情報を渡し、該当するコマンドに動いてもらいます。また表示時に呼ばれるCommandとは別にPreCommandを用意します。これは文字が表示完了したタイミングに呼び出す処理で、画像ロード等の重い処理を行います。*2

コマンドはm_commandListにインスタンス化しておきます。ここはComponenttとして配置するか迷いましたが、とりあえず普通のクラスとしてインスタンス化しました。実際はゲームのAPIを直接叩くケースが多い為、コンポーネントにしたほうが何かと使い勝手が良いかもしれません。

 


超簡単なテキスト制御5

 

コマンドの中身ですが、Commandメソッドの引数にパラメータが入っているため、それを表示したりすればOKです。例えば画像の表示コマンドはこんな感じにしました。

CommandUpdateImageは@imgのコマンドの中身で、nameでオブジェクト名、imageで画像名を指定して呼び出します。


超簡単なテキスト制御6コマンド

画像読込はちょっとだけ工夫してます。

具体的には、そのままの状態ではなく「拡張子bytes」等に変更し、テクスチャーではなくpngjpegのようなフォーマットを維持することによって、アプリサイズを1/20から1/100にします。

ノベルゲームは特に画像サイズが大きく枚数も多いので、テクスチャーをそのまま維持したら50GB~100GBとか簡単に超えてしまうので、その対策

*1:WebPlayerではローカルストレージを参照するIO系は動かないので注意

*2:このタイミングが一番ロード負荷が気にならないので、このタイミングで行います