Unity 6.4が2026年3月下旬にリリースされました!
この投稿では、Unity 6.4における「OnDisable」に関連の仕様変更を紹介します。
公式ガイドのアナウンス内容
OnDisableの仕様がUnity 6.4から変わりました。次のUnity 6.4へのアップグレードガイドにおける
「Changed OnDisable behavior」の部分です。
原文は、次のようになっています。
Unity now correctly invokes OnDisable callbacks on components of a GameObject
’s descendants when you destroy a GameObject using Object.Destroy.Previously, OnDisable was only invoked for components on the GameObject itself and its direct children. This change makes Object.Destroy behavior consistent with Object.DestroyImmediate, which has always invoked OnDisable across the entire hierarchy.
If you added workarounds to manually propagate OnDisable to deeper descendants, they will now cause duplicate calls and must be removed.
Unity 6.3 LTSまでの仕様
Unity 6.3 LTSまでは、Destroyされた直後にOnDisableが呼ばれるのは「Destroyされた対象自身」と「直属の子」だけで「孫以下」は呼ばれませんでした。もう少し厳密に書くと、次のような仕様でした。
- 直後に呼ばれる:DestroyされたGameObjectに付与されたコンポーネントの「OnDisable」
- 直後に呼ばれる:DestroyされたGameObjectの子GameObjectに付与されたコンポーネントの「OnDisable」
- 直後には呼ばない(呼ばれはする):DestroyされたGameObjectの孫以下(2階層以下)のGameObjectに付与されたコンポーネントの「OnDisable」
さて、厄介なのがUnity 6.3 LTSまでも「DestroyImmediate」は自身でも、子でも、孫でも関係なく、OnDisableは直後に呼ばれていたようです。
また、原文の説明文だけだと誤解しそうなのですが、「孫以下」もOnDisableが呼ばれはする(Destroy直後には呼ばれない)という点に注意してください。
Unity 6.4からの仕様
Unity 6.4からは「DestroyされたGameObjectの自身とその子孫」は、全て「直後」にOnDisableが呼ばれるようになりました。
DestroyImmediateの仕様とそろったようです。
コードによる比較検証
以下に示す「Destroyer」コンポーネントを作成します。
using UnityEngine;
public class Destroyer : MonoBehaviour
{
[SerializeField] GameObject destroyTarget;
void Start()
{
Debug.Log("Before Destroy");
Destroy(destroyTarget);
Debug.Log("After Destroy");
}
}
以下に示す「DestroyTarget」コンポーネントを作成します。
using UnityEngine;
public class DestroyTarget : MonoBehaviour
{
void OnDisable()
{
Debug.Log($"OnDisable called : {name}");
}
void OnDestroy()
{
Debug.Log($"OnDestroy called : {name}");
}
}
次のスクリーンショットのように、Destroyerという名前のGameObjectに「Destroyer」コンポーネントを付与します。
次のスクリーンショットのように、Target、Child、GrandChild、GrandGrandChildという名前のGameObjectに「DestroyTarget」コンポーネントを付与します。
このシーンを実行した際のログ出力結果を、Unity 6.3 LTSとUnity 6.4で比較します。
「Unity 6000.3.11f1」でのログ出力のスクリーンショットは次の通りです。Target、ChildはDestroy直後にOnDisableが呼ばれていること、GrandChildとGrandGrandChildは直後にOnDisableが呼ばれていないことに注目してください。
「Unity 6000.4.0f1」でのログ出力のスクリーンショットは次の通りです。Target、Child、GrandChild、GrandGrandChildすべてのOnDisableがDestroy直後に呼ばれていることに注目してください。
先のログのスクリーンショットが示すように、Unity 6.3 LTSとUnity 6.4でOnDisableの仕様が変わりました。
さいごに
この仕様は「発生がまれな不具合」を生みそうだったので、Unity 6.4での仕様変更は個人的には良い仕様変更かなと思います。
一方で公式アップグレードガイドでも
If you added workarounds to manually propagate OnDisable to deeper descendants, they will now cause duplicate calls and must be removed.
と注意書きがあります。Unity 6.3までの仕様の回避策として、何かしらのワークアラウンドを取っていた場合は問題が発生することもあり得るので、その可能性にも留意してください。
(「直後」と書いたけれど、実際はDestroy中なのかもしれない?)
リンク集



