【Unity】独自クラスの継承の場合のStart()メソッドの振る舞い

Unityには、Start()メソッドやUpdate()メソッドなど、イベント関数が用意されています
Start()メソッドはゲーム開始時でゲームオブジェクトが有効になった時に1回だけ実行されます

サンプルでは、2つのゲームオブジェクトを作成して、それぞれ同じスクリプトをアタッチします
ただし、スクリプトは基底クラスから継承された派生クラスになります

サンプルの概要

2つのゲームオブジェクトを作成しておきます
2つとも同じEnemyStatusスクリプトをアタッチしています
ただし、このEnemyStatusは、MobStatusを継承しています

EnemyStatusをゲームオブジェクトにアタッチするためMobStatusはMonoBehaviourを継承します

コード

2つのゲームオブジェクトにEnemyStatusスクリプトだけアタッチします
MobStatusスクリプトのアタッチは不要です

gameObject.nameは、スクリプトがアタッチされているゲームオブジェクト名を取得します

MobStatus.cs

using UnityEngine;

public class MobStatus : MonoBehaviour
{
    protected virtual void Start()
    {
        Debug.Log($"{gameObject.name}のMobStatus Start");
    }
}

EnemyStatus.cs

base.Start();のbaseとは、基本という英単語で、基底クラスを指します
つまり、MobStatusのStart()メソッドを実行するコードになります

using UnityEngine;

public class EnemyStatus : MobStatus
{
    protected override void Start()
    {
        base.Start();
        Debug.Log($"{gameObject.name}のEnemyStatus Start");
    }
}

シーン構成

Enemy1ゲームオブジェクト

Enemy2ゲームオブジェクト

実行結果

Enemy1のMobStatus Start
Enemy1のEnemyStatus Start
Enemy2のMobStatus Start
Enemy2のEnemyStatus Start

規定クラスのメソッドが呼ばれ(baseのメソッド)、続いて派生クラスのメソッドが呼ばれています

UML図

クラス図

PlantUML diagram

シーケンス図

EnemyStatusスクリプトの記述変更による実行結果の違い

Startメソッド自体を削除

クラス宣言とMobStatusから継承された派生クラスの宣言のみです

using UnityEngine;

public class EnemyStatus : MobStatus
{
}

基本クラスのStartメソッドだけは実行されます
UnityEngineのコンパイラは、Startメソッドを実行しようとしますが、派生クラスにないので、規定クラスのStartメソッドを見つけて実行するためです

Enemy1のMobStatus Start
Enemy2のMobStatus Start

Startメソッドは記述されているが、空ブロック

Startメソッドが空のブロック

using UnityEngine;

public class EnemyStatus : MobStatus
{
    protected override void Start()
    {
    }
}

base.Startがないので基底クラスのメソッドも呼び出されません

参考

PlantUML図

クラス図

@startuml

class MonoBehaviour {
}

class MobStatus {
  + Start()
}

class EnemyStatus {
  + Start()
}

MobStatus --up|> MonoBehaviour
EnemyStatus --up|> MobStatus

@enduml

シーケンス図

@startuml

actor UnityEngine
UnityEngine -> EnemyStatus : Start()

EnemyStatus -> MobStatus : Start()
activate MobStatus

MobStatus --> EnemyStatus : Return
deactivate MobStatus
activate EnemyStatus
EnemyStatus --> UnityEngine : Return
deactivate EnemyStatus

@enduml
@startuml

actor UnityEngine
UnityEngine -> EnemyStatus : Start()
EnemyStatus --> MobStatus : Start()
activate MobStatus

MobStatus --> EnemyStatus : Return
deactivate MobStatus
EnemyStatus --> UnityEngine : Return
deactivate EnemyStatus

@enduml
@startuml

actor UnityEngine
UnityEngine -> EnemyStatus : Start()
activate EnemyStatus

EnemyStatus --> UnityEngine : Return
deactivate MobStatus
deactivate EnemyStatus

@enduml

Unity

Posted by hidepon