[SerializeField] private GameObject target; // 参照している。nullじゃない。
    private void Awake()
    {
        Debug.Log(target == null); // Falseと表示される
        DestroyImmediate(target);
        Debug.Log(target == null); // Trueと表示される
    }
上のコードは、Unityにいくつかある「はまりポイント」や「なんじゃこりゃってなるポイント」の一つです。
変数target がオブジェクトを参照していてnullじゃないのに、target == nullがtrue。
解説
GameObjectやComponentを==オペレーターを使って、target == nullのように評価する際、変数がオブジェクトを参照しているのにも関わらず、trueと評価されることがあります。
これらの親クラスであるUnityEngine.Objectには、==や!=、boolのオペレーターが定義されています。
そして、その挙動が「対象のGameObjectやComponentが、生存していないならば、==でnullと比較するとtrueを返す」という仕様になっています
内部でこんなメソッドを作って生存しているかチェックをしています。
- IsNativeObjectAlive
- DoesObjectWithInstanceIDExist
この挙動は、私はあまり好きではありません。「コードは、利用者の期待や予測に対して、驚きが最小であるべき」と思っています。この挙動は、==に対して利用者が予期しない「生存チェックもする」という驚きを与えてしまっています。
覚えておかないと、予期せぬバグを発生させることがあるので、注意が必要ですね。(多分、ごくまれに発生するめんどいバグを生み出す原因になりそう)
次のコードを見てみることもオススメします。
おまけ。対応策
変数が参照するオブジェクトが破壊されるケースがあり、純粋にnullと比較したい場合System.Object.ReferenceEqualsを使うことをオススメします。
    [SerializeField] private GameObject target; // 参照している。nullじゃない。
    private void Awake()
    {
        Debug.Log(target == null); // Falseと表示される
        Debug.Log(ReferenceEquals(target, null)); // Falseと表示される
        DestroyImmediate(target);
        Debug.Log(target == null); // Trueと表示される
        Debug.Log(ReferenceEquals(target, null)); // Falseと表示される
    }