この記事でのバージョン
Unity2018.3.9f1
はじめに
今回はnull合体演算子とnull条件演算子の使い方についての記事になります!
前回null許容型についての記事を書いたのですが、そちらと合わせて用いられることも多いようです。
null合体演算子
null合体演算子
はnullかどうかを判断し処理を分岐させる時に使います。
演算子は??
と書きます。
using UnityEngine; public class Hoge : MonoBehaviour { private void Start() { Rigidbody rb = GetComponent<Rigidbody>() ?? gameObject.AddComponent<Rigidbody>(); } }
※これは正常に動かない可能性があります(後述)
これはどういう意味かというと、以下のコードと同じ意味になります。
using UnityEngine; public class Hoge : MonoBehaviour { private void Start() { Rigidbody rb = GetComponent<Rigidbody>(); if (rb == null) rb = gameObject.AddComponent<Rigidbody>(); } }
最初に見た時はやや分かりづらいと感じるかもしれませんが、結構直感的にコードを書くことができるんです。
①変数rb
にgameObjectのRigidbodyコンポーネントの参照
を代入しよう
②そういえばRigidbodyコンポーネント
がアタッチされていない場合(null)があるかも?
③??
でその時の対応をしよう
といった感じにコードを書いていくことが可能になります。
null条件演算子
こちらはC#6
での機能なので、Edit > Project Settings > Player
から、.NET 4.x
を選択しましょう。
null条件演算子
は?.
を使って書くことができます。
using UnityEngine; public class Hoge : MonoBehaviour { private void Start() { Vector3 force = new Vector3(1, 0, 0); GetComponent<Rigidbody>()?.AddForce(force); } }
※これは正常に動かない可能性があります(後述)
これがどういう意味かと言うと、以下のコードと同じ意味になります。
if(GetComponent<Rigidbody>() != null) GetComponent<Rigidbody>().AddForce(force);
またこの例では用いませんでしたが、返り値をもたせることもできます。
return sale?.Product;
この場合、sale変数がnullでないときは、Productプロパティの値が返し、nullのときにはnullが返ります。
unityで使うときの注意点
ただUnityではNull合体演算子
とNull条件演算子
が正しく動かない可能性があります。
その理由はUnityのオブジェクト(UnityEngine.Objectの派生クラス)はすべて独自nullであるからみたいです。
少し厄介ですがQiitaで拡張メソッドを使ってUnity Objectのnull
からいつもの(.NET)のnull
への型変換をする方法を書いてくださっていた方がいました。
少しだけそちらを紹介して終わりにしたいと思います。
UnityのGetCompornent<T>()でNull条件演算子が使えない - Qiita
Unityのnullはnullじゃないかもしれない - Qiita
.NETのnullへキャストする
こちらのスクリプトをunityに追加してください。
public static class ExtensionMethods { public static T NullCast<T>(this T obj) where T : UnityEngine.Object => (obj != null) ? obj : null; }
このコードをざっくり紹介すると、拡張メソッド
を用いてオブジェクトが存在するかどうか調べ、存在しない場合は.NETのnull
を返しています。
Object-bool - Unity スクリプトリファレンス
実際につかってみましょう。
using UnityEngine; public class Hoge : MonoBehaviour { private void Start() { Rigidbody rb = GetComponent<Rigidbody>().NullCast() ?? gameObject.AddComponent<Rigidbody>(); } }
using UnityEngine; public class Hoge : MonoBehaviour { private void Start() { Vector3 force = new Vector3(1, 0, 0); GetComponent<Rigidbody>().NullCast()?.AddForce(force); } }
さいごに
ややunityでnull条件演算子を使うのは厄介でしたが、上手く使っていけたらと思います!
ちなみになんですが、最後の例のような処理をしたい場合は[RequireComponent(typeof(Rigidbody))]
をする方が単純かつ最善だと思います。