代入する値の分岐は,三項演算子(条件演算子)でif
文より簡潔に記述できます。
また三項演算子は,実行するメソッドも分岐させる事が出来ます。
そのためには,デリゲートを使用する必要があります。
それでは,いくつか実例を挙げて御説明いたします。
(2019/11/11)追記しました。
(Unity 2018.3.0f2)
三項演算子とは
条件式を評価してtrue
とfalse
に応じた結果が実行されるため,if-else
文と似ています。
(厳密には,単純に代用すべきでないそうですが……。)
三項演算子の使用例を,以下に示します。
using UnityEngine; public class NewBehaviourScript : MonoBehaviour { // 整数値は “50” [SerializeField, Range(0, 100)] int number = 50; void Update() { // 1ずつ加算して 100 に達したら0にする number = (number < 100) ? (number + 1) : 0; // 同じ処理を if 文で /*if (number < 100) { number = number + 1; } else { number = 0; }*/ } }
上記のようなスクリプトファイルを適当な GameObject にアタッチして,Play してみましょう。
number
の値が増えてゆき,100に達すると0になるのが分かると思います。
?
の左辺を評価して真true
であれば?
の右辺を実行し,偽false
であれば:
の右辺が実行されます。
コメントアウトした部分のif
文に比べ,分岐を1行で簡潔に記述できていますね。
今回は値の増減を視覚的に分かりやすくするため,number
に RangeAttribute を付与して Inspector 上にスライダーを表示しています。
デリゲートとは
デリゲートを簡単に説明すると,関数を格納できる変数のような物です。
以下,デリゲートを使用したメソッド呼び出しの例です。
using UnityEngine; public class NewBehaviourScript : MonoBehaviour { // デリゲートの宣言 delegate void Method(); void Start() { // MethodA を代入 Method method = MethodA; // 代わりに Action を使えばデリゲートの宣言も省略できる //System.Action method = MethodA; // デリゲート実行 method(); // MethodB を代入 method = MethodB; // MethodA を追加 method += MethodA; // MethodA を削除 method -= MethodA; // デリゲート実行 method(); } void MethodA() { // コンソールに “A” と表示 Debug.Log("A"); } void MethodB() { // コンソールに “B” と表示 Debug.Log("B"); } }
2度繰り返されるmethod()
の実行前にそれぞれ別のメソッドを代入しているため,実際には2種類のメソッドが実行されています。
これを利用して,三項演算子の代入部分でメソッドを選ぶ事が出来ます。
ちなみにスクリプト内にも記述したように,Action
を使用すればデリゲートの宣言も省略できます。
三項演算子とデリゲート
それでは,実際にやってみましょう。
using UnityEngine; public class NewBehaviourScript : MonoBehaviour { // デリゲート delegate int Method(); // 加算・減算 enum Calculation { Addition, Subtraction }; // 列挙型は “加算” [SerializeField] Calculation calculation = default; // 整数値は “50” [SerializeField, Range(0, 100)] int number = 50; void Update() { // 計算実行 Calculate(); } void Calculate() { // 加算・減算状態の切り替え calculation = (number <= 0) ? Calculation.Addition : (number >= 100) ? Calculation.Subtraction : calculation; // 呼び出すメソッドの切り替え var method = (calculation == Calculation.Addition) ? (Method)Add : Subtract; // 代わりに Func<TResult> を使えばデリゲートの宣言も省略できる //var method = (calculation == Calculation.Addition) ? (System.Func<int>)Add // : Subtract; // 計算メソッド呼び出し method(); } int Add() { // 1加算 return number++; } int Subtract() { // 1減算 return number--; } }
これをアタッチした GameObject を Inspector 画面で見ると,次の画像のようになります。
次の部分が,今回のポイントになっている三項演算子です。
// 呼び出すメソッドの切り替え
var method = (calculation == Calculation.Addition) ? (Method)Add
: Subtract;
左辺には型推論var
が使用できますが,呼び出すメソッド名のいずれか1つにはキャスト(Method)
が必要になります。
ちなみにスクリプト内にも記述したように,Func<TResult>
を使用すればデリゲートの宣言も省略できます。
三項演算子とラムダ式
(2019/11/11)以下の内容を追記しました。
ラムダ式を使用する事で,更に記述を簡略化できます。
using UnityEngine; public class NewBehaviourScript : MonoBehaviour { // デリゲート //delegate int Method(); // 加算・減算 enum Calculation { Addition, Subtraction }; // 列挙型は “加算” [SerializeField] Calculation calculation = default; // 整数値は “50” [SerializeField, Range(0, 100)] int number = 50; void Update() { // 計算実行 Calculate(); } void Calculate() { // 加算・減算状態の切り替え calculation = (number <= 0) ? Calculation.Addition : (number >= 100) ? Calculation.Subtraction : calculation; // 呼び出すメソッドの切り替え //var method = (calculation == Calculation.Addition) ? (Method)Add // : Subtract; // 代わりに Func<TResult> や Action を使えばデリゲートの宣言も省略できる //var method = (calculation == Calculation.Addition) ? (System.Func<int>)Add // : Subtract; // 更にラムダ式を使えば Add() や Subtract() 等のメソッドも不要となる var method = (calculation == Calculation.Addition) ? (System.Func<int>)(() => (number = number + 1)) : (() => (number = number - 1)); // 計算メソッド呼び出し method(); } /*int Add() { // 1加算 return number++; } int Subtract() { // 1減算 return number--; }*/ }
今回のAdd()
やSubtract()
ように単純な処理であれば,ラムダ式で直接記述した方が良さそうですね。
以上,呼び出す関数を三項演算子で分岐させる方法でした。