Unityでスクリプトオフにしたのに動く…GetComponentやInterfaceはインスペクターオフ非アクティブでも拾うっぽいのでメモ

unity getcomponent 非アクティブ おかしい 動かない Unity
※記事内に広告が含まれています。

バーチャル3Dクリエイター神部まゆみです(*^_^*)

この記事はUnityでスクリプトをオフにしたのに動いていてハマったので、それについての記事です。

動作確認した最新バージョンは Unity 6000.3.1 です。

●PRスペース●
■PR■

現在、Unityアセットストアで毎日日替わりでアセットが無料配布されています。(2025/12/31 まで)。

A Free Asset Every Day | Unity Assets Store

ページに記載されているクーポンコード入力で0円になりますが、記載の日程は時差で日本より遅れてるっぽい?ので注意。

〇まゆみマート|BOOTH

BOOTHでVRoidテクスチャやVRChat向けオブジェクトなどを販売しています。いいねしてくれると励みになります(*^-^*)

起きたこと:スクリプトをオフにしたのに実際は動いていて不具合が起きた

インスペクターでスクリプトをオフにしていたのだけど、Unity内部的には部分的に実行されていて不具合が出たっぽい。

unity getcomponent 非アクティブ おかしい 動かない

EnemyDamageReceiverは最初に書いた敵専用のダメージスクリプトで、後にプレイヤーにも使える汎用的なDamageReceiverを作った感じ。

後で使うかもしれないのでEnemyDamageReceiverはオフにしておいたのだけど…それが良くなかったみたい(^_^;)

↓DamageReceiverが正常に動いていればダメージ量が表示されるはずなんだけど、これだと動かなかった。

コンポーネントを削除するか下にもってくると正常に動く

しかしEnemyDamageReceiverをオフではなく削除すると正常に動きました。

もしくは順番を変えて下に持ってくると動く。

まぁ意図しない動作をする可能性があるから削除が無難か…

ChatGPTパイセンに聞いたらGetComponent系の命令使ってるとよくあるっぽい

GetComponent系はインスペクターでオフにしていても拾うっぽい。

unity getcomponent 非アクティブ おかしい 動かない

今回何が起きてたか(整理)

  • EnemyDamageReceiver.cs
    👉 Inspector で OFF(チェック外し)
  • Unity的には
    👉 「存在はしているが、動いていない」
  • でも
    • そっちが IDamageable を実装している
    • Raycast → GetComponent<IDamageable>()
      👉 そっちを拾っていた

結果として:

  • HP は減る(EnemyDamageReceiver 側)
  • 新しい DamageReceiver
    • ShowDamagePopup
    • Setup
      一切呼ばれない

という、超わかりにくい状態になってました。


なぜログが出なかったか

これも全部説明つきます。

  • START
    👉 DamagePopup の Start()(Prefab側)
  • ダメージログは
    👉 EnemyDamageReceiver 側のログ

別々のスクリプトが別々に動いていたわけですね。


今回の学び(かなり重要)

✔ Inspector で OFF の Component

  • 完全に無効ではない
  • GetComponent<T>() では取得される

👉 インターフェース実装があると特に危険


ベストプラクティス(今後の事故防止)

① 役割が被るスクリプトは共存させない

  • Damage 系は 1つに統一

② 使わない Component は「OFF」ではなく削除

  • 特に Interface 実装クラス

③ デバッグ時はログを出す

Debug.Log(hit.collider.GetComponents<IDamageable>().Length);

何個付いてるか見るのも有効

インスペクターオフでも拾われる命令

① GetComponent / GetComponents(すべて)

GetComponent<T>()
GetComponents<T>()
GetComponentInChildren<T>()
GetComponentInParent<T>()

👉 すべて「有効・無効を無視」


② SerializeField / public フィールド

[SerializeField] EnemyDamageReceiver receiver;
  • Inspector で OFF にしても
  • 参照は 普通に入る
  • 呼び出せば普通に実行される(※Update除く)

③ Interface 型

IDamageable damageable;

👉 一番事故りやすい

  • クラス名が見えない
  • 複数実装に気づきにくい

④ Find / FindObjectOfType

FindObjectOfType<EnemyDamageReceiver>();
  • 無効な Component も対象
  • Editorでは特に危険

Inspector OFF で「拾われない」もの

❌ Update / Start / OnEnable

void Update() { }
  • OFFなら呼ばれない
  • ここが混乱の元

👉 「動いてない=使われてない」と誤解する


なぜ GetComponent が特に危険に見えるのか

理由① 使用頻度が圧倒的に高い

  • ダメージ処理
  • 当たり判定
  • インタラクション

理由② Interface とセットで使われがち

GetComponent<IDamageable>()
  • 「どれを拾ったか」見えない
  • バグが静か

理由③ エラーが出ない

  • null じゃない
  • 型も合っている
  • 動いてしまう

👉 サイレントバグ

Interfaceってのも危険っぽい

ChatGPTが書いたスクリプトで、これ作っとくと継承して使えて便利って言ってたんだけど、オフにしてても走って不具合の原因になりやすいっぽい。

unity getcomponent 非アクティブ おかしい 動かない

まぁ一つ一つデバッグログを出して原因が特定できたので気づけて良かった。

おわりに

少しハマったけど地道にログを出して不具合特定できて良かった。

これ気づきにくいからハマる人結構いそうだなぁ(^_^;)

忘れないように記事にしてみました。

また何かあれば追記します(*^_^*)

タイトルとURLをコピーしました