[Unity] 大量のユニットデータを管理しよう!![基底クラス]

[Unity] 大量のユニットデータを管理しよう!![基底クラス]

こんにちは!福田です!
今日はUnityで大量のユニットデータを扱う際に便利な基底クラス(Virtual Class)について解説していきます!
Virtualクラスは、継承とポリモーフィズムを実現するための重要な機能です!
コード例を中心に、Virtualクラスの使い方、活用方法、応用方法について解説していきます!

Virtualクラスの基本的な使い方

以下は、Virtualクラスの基本的な使用例です。

// BaseClass
public class BaseClass
{
    public virtual void VirtualMethod()
    {
        Debug.Log("BaseClass: VirtualMethod");
    }

}
// DerivedClass
public class DerivedClass : BaseClass
{
    public override void VirtualMethod()
    {
        Debug.Log("DerivedClass: VirtualMethod");
    }
}
// 各クラスを動かします
public class TestVirtualClass : MonoBehaviour
{
    private void Start()
    {
        BaseClass baseObj = new BaseClass();
        BaseClass derivedObj = new DerivedClass();

        baseObj.VirtualMethod();
        derivedObj.VirtualMethod();
    }
}

出力結果

BaseClass: VirtualMethod
DerivedClass: VirtualMethod

こんな感じで、BaseClassを継承したDerivedClassはメソッドのoverrideをすることで、自身のメソッドを発火させます。

次のコードを見ていただけるとこの便利さがよくわかると思います!

//汎用敵ユニット
public class Enemy
{
    public virtual void Move()
    {
        Debug.Log("Enemy: Move");
    }

    public virtual void Attack()
    {
        Debug.Log("Enemy: Attack");
    }
}
//Slime 
public class Slime : Enemy
{
    public override void Move()
    {
        Debug.Log("Slime: Move");
    }
}
//Dragon
public class Dragon : Enemy
{
    public override void Attack()
    {
        Debug.Log("Dragon: Attack");
    }
}
//ユニットを動かします!
public class TestEnemyClass : MonoBehaviour
{
    private void Start()
    {
        Enemy slime = new Slime();
        Enemy dragon = new Dragon();

        slime.Move();
        slime.Attack();

        dragon.Move();
        dragon.Attack();
    }
}

出力結果

Slime: Move
Enemy: Attack
Enemy: Move
Dragon: Attack

見ていただいたらわかると思うのですが、派生クラス(SlimeやDragonなど、Enemyを継承したクラス)で関数をoverrideした場合自身が持つ関数を使用し、派生クラスにない関数はBaseのEnemyで定義された関数を使用しています!

つまりこれを使うと、各ユニットデータを作る際に汎用の関数をいちいち書く必要もなく、変更があったときには基底クラスのみに変更を加えればいいわけです!
とても便利ですね!

しかも、一元管理もしやすいです!
詳しくは書きませんが下に状態管理を簡潔に実装した際の例のコードを置いておくのでぜひ確認ください!

public abstract class GameState
{
    public virtual void Enter()
    {
        Debug.Log("Entering state");
    }

    public virtual void Exit()
    {
        Debug.Log("Exiting state");
    }

    public abstract void Update();
}

public class MenuState : GameState
{
    public override void Update()
    {
        Debug.Log("Updating menu state");
    }
}

public class PlayState : GameState
{
    public override void Update()
    {
        Debug.Log("Updating play state");
    }
}

public class GameManager : MonoBehaviour
{
    private GameState _currentState;

    private void Start()
    {
        _currentState = new MenuState();
        _currentState.Enter();
    }

    private void Update()
    {
        _currentState.Update();

        if (Input.GetKeyDown(KeyCode.Space))
        {
            _currentState.Exit();
            _currentState = new PlayState();
            _currentState.Enter();
        }
    }
}

どうでしたか?
基底クラスと派生クラス(あとついでに抽象クラス)を効果的に使ってコード管理をしていきましょう!
福田でした!


現在シェルパグループでは、一緒に働く仲間を募集中!
建築パース、3DCG、UnrealEngine、Unity、プログラミングに興味のある方は
是非リクルートサイトをご覧ください!

■リアルな3DCG制作の仕事をしたい方必見!
https://sherpa-recruit.jp/