結論
SerializeField で Null なフィールド
== nullは Null だと判定できる??、?.、??=、is nullは UnassignedReferenceException が発生する
Destroy した直後の UnityEngine.Object
== nullは Null だと判定できない??、?.、??=、is nullも Null だと判定できない
Destroy 後に 1 フレーム待った UnityEngine.Object
== nullは Null だと判定できる??、?.、??=、is nullは MissingReferenceException が発生する
Destroy 後に null を代入した UnityEngine.Object
== nullは Null は判定できる??、?.、??=、is nullも Null だと判定できる
引数が呼び出し元で Destroy された場合
== nullは Null だと判定できる??、?.、??=、is nullは MissingReferenceException が発生する
基本的には以下のルールを守れば正確に Null チェックできる
- UnityEngine.Object に対して
??、?.、??=、is nullを使用しない - Destroy したら変数に
nullを代入する
目次
- 結論
- 目次
- 検証環境
- 検証結果
- SerializeField で Null なフィールドに対して == null
- SerializeField で Null なフィールドに対して Null 合体演算子(??)
- SerializeField で Null なフィールドに対して Null 条件演算子(?.)
- SerializeField で Null なフィールドに対して Null 合体代入(??=)
- SerializeField で Null なフィールドに対して is null
- Destroy した直後に == null
- Destroy した直後に Null 合体演算子(??)
- Destroy した直後に Null 条件演算子(?.)
- Destroy した直後に Null 合体代入(??=)
- Destroy した直後に is null
- Destroy 後に 1 フレーム待って == null
- Destroy 後に 1 フレーム待って Null 合体演算子(??)
- Destroy 後に 1 フレーム待って Null 条件演算子(?.)
- Destroy 後に 1 フレーム待って Null 合体代入(??=)
- Destroy 後に 1 フレーム待って is null
- Destroy 後に null を代入して == null
- Destroy 後に null を代入して Null 合体演算子(??)
- Destroy 後に null を代入して Null 条件演算子(?.)
- Destroy 後に null を代入して Null 合体代入(??=)
- Destroy 後に null を代入して is null
- 引数が呼び出し元で Destroy されてから == null
- 引数が呼び出し元で Destroy されてから Null 合体演算子(??)
- 引数が呼び出し元で Destroy されてから Null 条件演算子(?.)
- 引数が呼び出し元で Destroy されてから Null 合体代入(??=)
- 引数が呼び出し元で Destroy されてから is null
- 関連記事
検証環境
- Unity 2020.3.13f1
検証結果
SerializeField で Null なフィールドに対して == null
using UnityEngine; public class Example : MonoBehaviour { [SerializeField] private Material m_material; private void Start() { Debug.Log( m_material == null ? "null です" : "null ではないです" ); } }

「null です」と表示される
SerializeField で Null なフィールドに対して Null 合体演算子(??)
using UnityEngine; public class Example : MonoBehaviour { [SerializeField] private Material m_material; private void Start() { m_material = m_material ?? new Material( Shader.Find( "Unlit/Texture" ) ); Debug.Log( m_material.name ); } }

「UnassignedReferenceException」が発生する
SerializeField で Null なフィールドに対して Null 条件演算子(?.)
using UnityEngine; public class Example : MonoBehaviour { [SerializeField] private Material m_material; private void Start() { Debug.Log( m_material?.name ); } }

「UnassignedReferenceException」が発生する
SerializeField で Null なフィールドに対して Null 合体代入(??=)
using UnityEngine; public class Example : MonoBehaviour { [SerializeField] private Material m_material; private void Start() { m_material ??= new Material( Shader.Find( "Unlit/Texture" ) ); Debug.Log( m_material.name ); } }

「UnassignedReferenceException」が発生する
SerializeField で Null なフィールドに対して is null
using UnityEngine; public class Example : MonoBehaviour { [SerializeField] private Material m_material; private void Start() { Debug.Log( m_material is null ? "null です" : "null ではないです" ); } }

「null ではないです」と表示される
Destroy した直後に == null
using UnityEngine; public class Example : MonoBehaviour { private void Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); Destroy( material ); Debug.Log( material == null ? "null です" : "null ではないです" ); } }

「null ではないです」と表示される
Destroy した直後に Null 合体演算子(??)
using UnityEngine; public class Example : MonoBehaviour { private void Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); Destroy( material ); material = material ?? new Material( Shader.Find( "Unlit/Texture" ) ); Debug.Log( material.name ); } }

「Unlit/Texture」ではなく「Unlit/Color」と表示される
Destroy した直後に Null 条件演算子(?.)
using UnityEngine; public class Example : MonoBehaviour { private void Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); Destroy( material ); Debug.Log( material?.name ); } }

「Unlit/Texture」ではなく「Unlit/Color」と表示される
Destroy した直後に Null 合体代入(??=)
using UnityEngine; public class Example : MonoBehaviour { private void Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); Destroy( material ); material ??= new Material( Shader.Find( "Unlit/Texture" ) ); Debug.Log( material.name ); } }

「Unlit/Texture」ではなく「Unlit/Color」と表示される
Destroy した直後に is null
using UnityEngine; public class Example : MonoBehaviour { private void Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); Destroy( material ); Debug.Log( material is null ? "null です" : "null ではないです" ); } }

「null ではないです」と表示される
Destroy 後に 1 フレーム待って == null
using System.Collections; using UnityEngine; public class Example : MonoBehaviour { private IEnumerator Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); Destroy( material ); yield return null; // 1 フレーム待つ Debug.Log( material == null ? "null です" : "null ではないです" ); } }

「null です」と表示される
Destroy 後に 1 フレーム待って Null 合体演算子(??)
using System.Collections; using UnityEngine; public class Example : MonoBehaviour { private IEnumerator Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); Destroy( material ); yield return null; // 1 フレーム待つ material = material ?? new Material( Shader.Find( "Unlit/Texture" ) ); Debug.Log( material.name ); } }

MissingReferenceException が発生
Destroy 後に 1 フレーム待って Null 条件演算子(?.)
using System.Collections; using UnityEngine; public class Example : MonoBehaviour { private IEnumerator Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); Destroy( material ); yield return null; // 1 フレーム待つ Debug.Log( material?.name ); } }

MissingReferenceException が発生
Destroy 後に 1 フレーム待って Null 合体代入(??=)
using System.Collections; using UnityEngine; public class Example : MonoBehaviour { private IEnumerator Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); Destroy( material ); yield return null; // 1 フレーム待つ material ??= new Material( Shader.Find( "Unlit/Texture" ) ); Debug.Log( material.name ); } }

MissingReferenceException が発生
Destroy 後に 1 フレーム待って is null
using System.Collections; using UnityEngine; public class Example : MonoBehaviour { private IEnumerator Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); Destroy( material ); yield return null; // 1 フレーム待つ Debug.Log( material is null ? "null です" : "null ではないです" ); } }

「null ではないです」と表示される
Destroy 後に null を代入して == null
using UnityEngine; public class Example : MonoBehaviour { private void Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); Destroy( material ); material = null; Debug.Log( material == null ? "null です" : "null ではないです" ); } }

「null です」と表示される
Destroy 後に null を代入して Null 合体演算子(??)
using UnityEngine; public class Example : MonoBehaviour { private void Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); Destroy( material ); material = null; material = material ?? new Material( Shader.Find( "Unlit/Texture" ) ); Debug.Log( material.name ); } }

「Unlit/Texture」と表示される
Destroy 後に null を代入して Null 条件演算子(?.)
using UnityEngine; public class Example : MonoBehaviour { private void Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); Destroy( material ); material = null; Debug.Log( material?.name ); } }

「Null」と表示される
Destroy 後に null を代入して Null 合体代入(??=)
using UnityEngine; public class Example : MonoBehaviour { private void Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); Destroy( material ); material = null; material ??= new Material( Shader.Find( "Unlit/Texture" ) ); Debug.Log( material.name ); } }

「Unlit/Texture」と表示される
Destroy 後に null を代入して is null
using UnityEngine; public class Example : MonoBehaviour { private void Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); Destroy( material ); material = null; Debug.Log( material is null ? "null です" : "null ではないです" ); } }

「null です」と表示される
引数が呼び出し元で Destroy されてから == null
using System.Collections; using UnityEngine; public class Example : MonoBehaviour { private void Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); StartCoroutine( Check( material ) ); Destroy( material ); } private IEnumerator Check( Material material ) { yield return null; // 1 フレーム待つ Debug.Log( material == null ? "null です" : "null ではないです" ); } }

「null です」と表示される
引数が呼び出し元で Destroy されてから Null 合体演算子(??)
using System.Collections; using UnityEngine; public class Example : MonoBehaviour { private void Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); StartCoroutine( Check( material ) ); Destroy( material ); } private IEnumerator Check( Material material ) { yield return null; // 1 フレーム待つ material = material ?? new Material( Shader.Find( "Unlit/Texture" ) ); Debug.Log( material.name ); } }

MissingReferenceException が発生
引数が呼び出し元で Destroy されてから Null 条件演算子(?.)
using System.Collections; using UnityEngine; public class Example : MonoBehaviour { private void Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); StartCoroutine( Check( material ) ); Destroy( material ); } private IEnumerator Check( Material material ) { yield return null; // 1 フレーム待つ Debug.Log( material?.name ); } }

MissingReferenceException が発生
引数が呼び出し元で Destroy されてから Null 合体代入(??=)
using System.Collections; using UnityEngine; public class Example : MonoBehaviour { private void Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); StartCoroutine( Check( material ) ); Destroy( material ); } private IEnumerator Check( Material material ) { yield return null; // 1 フレーム待つ material ??= new Material( Shader.Find( "Unlit/Texture" ) ); Debug.Log( material.name ); } }

MissingReferenceException が発生
引数が呼び出し元で Destroy されてから is null
using System.Collections; using UnityEngine; public class Example : MonoBehaviour { private void Start() { var material = new Material( Shader.Find( "Unlit/Color" ) ); StartCoroutine( Check( material ) ); Destroy( material ); } private IEnumerator Check( Material material ) { yield return null; // 1 フレーム待つ Debug.Log( material is null ? "null です" : "null ではないです" ); } }

「null ではないです」と表示される