見出し画像

ScriptableObjectでUIもフラグ管理もスッキリ

Marine School Simulator の進捗
今回は、武器を実装しました。
これでサメやイノシシを倒せます。ダメージモーションが変だけど

ゲームパッドならカメラとジャンプと攻撃を3本の指で同時に操れますが
スマホのタッチ操作は左右の指一本ずつしか使えないわけで、操作系統を工夫する必要がありました。
アクションボタンとカメラボタンがカメラを動かせるアナログスティックにもなってて、カメラを回しながらジャンプやアクションができるように。
しかしそれは、広いエリフが必要なアナログスティック複数個が、画面右半分の狭い場所を占領するので、置けるUIの数が限られてしまう。
そこで、武器持ってる時はDropボタンが出現し、椅子に座ってるなどのアクションの最中はカメラ移動と立ち去るボタン以外非表示になる、みたいなフレキシブルUIにしました。

武器使用時は武器を手放すボタンが出現、

画像1

アクション実行中だとアクション終了ボタンとカメラ移動のみ表示

画像2

・UnityのUIには、ボタン押したら自身や他のオブジェクトの表示を切り替えるみたいなイベントを設定する機能がありますが、これを使うとボタンと機能を追加するたびに切り替えの組み合わせがねずみ算で増えてパンクするので、一つのスクリプトですべてのUIを一元管理のほうが楽です。

画像3

これやると、とても管理が簡単になるのですが、このスクリプトにプレイヤーの状態を随時参照させる必要があります。

・一方、物を拾うとか武器を振るとかの機能の追加は、オブジェクトにコンポーネントを追加することで実現していきますが、
※なおキャラクター操作関連のコンポーネントがあるメインオブジェクトが機能を盛るごとにインスペクターが超縦長になっていって視認が困難になったので、メインオブジェクトにアタッチしなくても問題なさそうな機能は、わかりやすい名前の空オブジェクトに継ぎ足すことにしてます。

画像4

このやりかたは、基本独立して稼働してる各コンポーネントを何らかの方法で同期させる必要があり、うかつな方法では機能=コンポーネントが増えるたびに同期に必要な処理とパラメータの組み合わせがねずみ算で増えていくので、共通で参照したいパラメータはプレイヤーデータベースとして、ScriptableObjectにまとめました。

※Unity知らない人向け解説:複数コンポーネント間でパラメータやデータベースを記録・共有させる方法はいくつかありますが、同一オブジェクト内でしかできないとかデメリット制約がいろいろあって、ScriptableObject使うのが一番マシというのが私の持論です。

[SerializeField, Header("プレイヤーデータベースをセット"), Tooltip("プレイヤーデータベース")]
       DataPlayerStatus dataPlayerStatus;

画像5


ScriptableObjectに登録した変数はすべてのコンポーネントが参照でき、どこかがScriptableObject内の変数を書き換えたらー武器を拾ったとか、椅子に座ったとかの状態遷移のフラグとか-すべてのコンポーネントに即座に正確に伝えられます。
UI管理コンポーネントもこれを参照しておけば、フラグにあわせたUIの表示切り替えも同時に実現させることができます。

不具合が出たときも、ひとまずこのプレイヤーデータベースの中身をインスペクタに表示しとけばすべての状態のリアルタイムの変化が視認できて、なにか機能を追加する度にすべてのコンポーネントを動作チェックする苦労も軽減されます。

画像6

・ScriptableObjectのデメリットは、エディタ実行時に数値を変えたらプレイを止めてもそのまま残る点です。これは利点でもあり欠点でもあります。
フラグ管理に使う場合は、エディタ上で武器使ってる最中に止めて再度プレイしたら武器使用中フラグがオンになったままという不具合を起こすので、起動時にデータベースを初期値にリセットするコードを自作する必要があります。

・なおプレイヤーを制御するコンポーネントのいくつかはNPCも流用してるため、NPCが使ってる時はプレイヤーScriptableObjectをセットするとこを空欄にして、Nullチェックで機能を止めるという分岐処理が必要になります。
まちがってNPCのコンポーネントにもプレイヤーScriptableObjectを取り付けてしまったら、プレイヤーとNPCたちが全く同時に違う条件で(プロジェクト中唯一の存在である)データベースのパラメータを異なる値で書き換えるという矛盾が生じるからか、エラーは出ないけど明らかに動きがおかしい、言葉で言い表せない不具合にさいなまれました。(単にそのパラメータがおかいくなるだけでなく、データベースを使ったコンポーネントとかオブジェクトとかがです)

この記事が気に入ったらサポートをしてみませんか?