バナナラボ

Vtuber美作ワニのブログです

【実装のヒント】Interfaceの活用【Unity】

バナナラボの美作です。

今日はインターフェース(Interface)の活用についての記事になります!

インターフェースって?

インターフェースはクラスに対して「この実装もってるよ」ってことを明示させることができる仕組みみたいなものです。

めちゃくちゃ大雑把な説明をしているので詳しいことはリンク先を見てもらえたらと思います。

インターフェイス - 複数の型の動作を定義する | Microsoft Docs

実装例

以下のようなクラスがあるとします。

public class Human
{
}

public class House
{
}

上記のクラスはそれぞれまったく違うものですが、互いに共通の処理を持たせたいなーってなる時があります。

人間と家をクローンする仕組みが欲しいなーってなった時に以下のように実装します。

public class Human : ICloneObject
{
    public ICloneObject Clone()
    {
        // 省略
    }
}

public class House : ICloneObject
{
    public ICloneObject Clone()
    {
        // 省略
    }
}

public interface  : ICloneObject
{
    ICloneObject Clone();
}

このようにHumanHouseは別々の個体だが、互いに共通の機能を持っていることを明示することができます。

abstract(抽象クラス)との違い

abstractで継承してやればいいじゃん、といえばそうなんですが抽象クラスはひとつしか定義できない(ひとつしか継承できない)のに対して、interfaceは複数指定することができます。 またinterfaceは実装そのものは必須ですが、あくまで定義でしかないので扱い方も変わってきます。

どっちがいいか、については実装によるので良し悪しは使い方に変わってきます。

Interface実装のコツ

Interfaceの実装は必要最低限かつ必要に応じた実装のみに絞って実装することが大切です。 例えばですが以下のような例を出します。

public class Character : ICharacter
{
    // 省略
}

public interface ICharacter
{
    void Update();
    void JobChange();
    void SetAbility();
    ....
}

上記のようにCharacterクラスと1対1の関係性で実装するケースにおいては実装する意味がなくなってしまうので、こういったケースは避けたほうが良いと思います*1

下記のように機能粒度に合わせてInterfaceを作ったほうが綺麗にまとめやすいと思います。

public class Character : IPlayerCharacter, IJobCharacter
{
    // 省略
}

public interface IPlayerCharacter
{
    void Update();
}

public interface IJobCharacter
{
    void JobChange();
    void SetAbility();
    ....
}

クラスの型について

Interfaceは他にも変数の型に共通して当てはめ、明示された実装に関しては呼び出すことができます。

public class Main
{
    void Execute()
    {
        var c = new Character();

        IPlayerCharacter pc = c;
        pc.Update();

        IJobCharacter jc = c;
        c.JobChange();
    }
}


public class Character : IPlayerCharacter, IJobCharacter
{
    // 省略
}

public interface IPlayerCharacter
{
    void Update();
}

public interface IJobCharacter
{
    void JobChange();
    void SetAbility();
    ....
}

また実装されているクラスに対してであればInterfaceからclassへの変換も容易に行うことができます。

補足

Interfaceは目に見えて重いわけではないですが、Unityでの利用においては通常の関数よりも負荷がかかります。 そのため、1つ1つでは大したことがないが塵も積もれば重くなるのでそういう面では注意が必要です。

最後に

Interfaceの活用についてざっくりと説明しました。

ゲームの機能が多岐に渡らないようにうまくコントロールしたスクリプト実装を心がけていけば使いやすい機能なのでガンガン使っていきましょう!

宣伝

YouTubeでゲーム実況・ゲーム開発の動画投稿および配信をやっています! もしご興味があればチャンネル登録・高評価よろしくおねがいします!

www.youtube.com

*1:abstractでの実装にした方が後々整理しやすいという見解