【第7回】ハードコードにさよならバイバイ! Inspectorから値を変更する
- 2018.04.11
- Unityチュートリアル
- Unity, チュートリアル
前回までのUnityチュートリアルでキーボードからの入力、画面上のボタンからの入力を処理できるようになりました。どちらの手段でもボールを飛ばせます。
じゃあ次は……といったところでスクリプトを覗くと、力の大きさや向きがハードコードされてる……!?
値を変えるたびにスクリプトを修正するなんて、世の中のプログラマ達が武器を手に取り襲いかかってきそうな案件です。
特にボールに加える力の大きさなどは、ゲーム実行中に値を変えながら調整したいところ。
ということで、今回はゲーム実行中にInspectorウィンドウから値を調整する方法のチュートリアルです。
前回のチュートリアルはこちらから。
今回の目的
ゲームの実行中に、Inspectorウィンドウから力の大きさの値を変更できるようにします。
プロジェクトの準備
前回のチュートリアルで作成したプロジェクトをそのまま使います。
このページに先にたどり着いた方は、チュートリアルの初回から追っていただけるといいかもしれません。
値をInspectorウィンドウから変えるには?
メンバ変数の値をInspectorウィンドウから変更するには、2つのやり方があります。
- 対象のメンバ変数のアクセス修飾子をpublicにする
- 対象のメンバ変数に[SerializeField]属性をつける
どちらもスクリプトで設定しますが、労力はそう変わりません。一言追加するだけですからね!
前回作成したSphereBooster.csのスクリプトで、力の大きさ、向きのメンバ変数を上に持ってきたものがこちら。
このメンバ変数の頭に、publicと[SerializeField]をそれぞれつけてみましょ。
publicの場合は同じ行に入れます。[SerializeField]は同じ行に入れてもいいのですが、上の行につけることが多いかな。アクセス修飾子の位置にあると、パッと見てpublicなのかprivateなのか分からないですし。
この状態でUnityに戻ってコンパイルが終わると、『Sphere』オブジェクトにアタッチしたSphereBoosterに「Force Direction」と「Force Magnitude」が表示されました。メンバ変数の宣言時に初期値をセットしているので、その値が入っていますね。
なお、画面撮影のため、その他のコンポーネントは名前の左にある[▼]をクリックして閉じています。
この状態でゲームを実行してみましょ。実行中にInspectorウィンドウから値を変えられるので、[Boost!]ボタンを押す前に変更してみると飛び方が変わります。なお、設定した値を画面に表示しているのはUnityの機能ではないのでご注意。
ゲーム実行中に値を変更すると、ゲームの実行を止めた際、ゲームを開始した時点の値に戻ります。元の値を壊さない利点はありますが、ゲーム実行中に調整し、良い値が見つかった時はそれを覚えておいて、ゲーム停止後に改めて設定する必要があります。
文字だけだとイメージが湧かないかも。上のGIFだと、ゲーム開始時のForce Magnitudeは10で、ゲーム実行中5や20に値を変えても、停止した時に10に戻ります。実際にやってみよう。
publicとSerializeFieldの使い分け
2通りのやり方があるからには、やっぱりそれぞれ役割があるんです。
publicを使う場面
C#では、自クラス以外からメンバ変数にアクセスするためには、ターゲットのメンバ変数をpublicとして公開する必要があります。
Inspectorから値を操作するのは、自クラスからの操作ではないんですよねぇ。なので、基本的にはpublicを使って公開しないといけません。
また、外部のクラスからそのメンバ変数を参照したい場合はpublicを使う必要があります。
SerializeFieldを使う場面
そうは言っても、デバッグや調整が楽になるからと、むやみやたらにpublicのメンバ変数を用意するのはよろしくないんです。
publicなら、Inspector以外からでも値が読み書きできちゃいますからね。カプセル化の考え方からしてもイケてない実装ですし、予期しない値を突っ込まれたら目も当てられません。バグが生まれる土壌は改善しないと。
そんなお悩みを解決してくれるのがこちら!
[SerializeField]をつけると、privateやprotectedなメンバ変数でもInspectorウィンドウで値を変更できるんです!
もちろん、外部のスクリプトからは、ターゲットのメンバ変数が隠されたまま!
これでお値段なんと0円! さぁ、いますぐ実装を!!
使い分けの方針
という訳で、使い分けの方針は以下のように。
- Inspectorから値を変更したい場合はpublicか[SerializeField]を使う
- Inspector以外に、外部のスクリプトからメンバ変数を使う場合はpublic
- Inspectorから参照したいだけなら[SerializeField]
- 初心者だしよく分かんないっす->とりあえずpublic
個人的には[SerializeField]を中心に使い、必要になったらpublicにするのがおすすめです。
スクリプトの方でも、両方とも[SerializeField]としました。
まとめ
今回はInspectorウィンドウから値を変更する方法のチュートリアルでした。
publicを使うか、[SerializeField]を使うかといった違いはあるものの、難しい操作もなく実現できるので積極的に活用したいところ。
さて、今回はあまり触れませんでしたが、力を加える方向である「forceDirection」をInspectorウィンドウで表示しましたが、このままだと設定しにくいんですよね。Vector3で向きを設定するのは直感的じゃないですし。
なので、次回は角度をfloatで指定できるようにスクリプトを改修するチュートリアルをお送りします。
ゲーム開発の攻略チャートを作りました!
-
前の記事
【第6回】ボタンの動作・処理を実装するUnityチュートリアル 2018.04.11
-
次の記事
【第8回】角度から力の向きを計算するUnityチュートリアル 2018.04.12
コメントを書く