一年前のコード書き直した(後編)

はじめに

これはKMC Advent Calendar 2020 の11日目の記事*1、並びにinonoa Advent Calendar 2020の2日目の記事です*2。また、 一年前のコード書き直した(前編) の続きでもあります。

はい

一年前のコードとはこちらになります。

StageSelector.cs

読まなくて大丈夫です。

これがこうなりました

StageSelectManager.cs

StageSelectView.cs

StageSelectBGChanger.cs

クラスが三つに分裂して関数も増えてますがそのあたりは前編を参照のこと………

インターフェースで切る

インターフェースをご存じでしょうかって書こうとしたんですが説明は人にぶん投げることにします。今回の場合はStageSelectManager.csの下部のこれです。

public interface IStageSelectView
{
    void Enter();
    IObservable<EDraft> StageSelected { get; }
    IObservable<Unit> OnGoToConfig { get; }
    IObservable<Unit> OnGoToRankings { get; }
}

で、StageSelectManagerのメンバの型に使われています。

public class StageSelectManager : SerializedMonoBehaviour
{
    [SerializeField] IStageSelectView view;

こうするとviewにはIStageSelectViewを継承(実装)しているものなら何でも入れられるわけです。例えば場面によって違うUIからステージ選択をしたい*3としても、ここにそれぞれ違うクラス(IStageSelectViewを継承している)を入れればStageSelectManager自体は使いまわせますし、そもそもどういうUIにするか決まってないけどとりあえずManagerだけ作っておこう、ただメンバのviewがnullだと動かない、というときにも、最低限のViewを素早く作って差し込み、あとからしっかりしたViewを作って取り換えるなんて芸当も可能です。というか実際今仮置きになっています。

f:id:inonoa:20201214030451p:plain
下部のボタンが仮置きというだけでそれ以外は体験版でもこれですしょぼいとか言わないで…………

というかそもそもManagerがViewへの参照を持たなくてすむ方法がある気がしてきましたが考えないことにします。

インターフェースの[SerializeField]………?

まだ説明が不足している部分があります。当たり前のようにStageSelectManagerのメンバに [SerializeField] IStageSelectView view; とか書いてましたが、 [SerializeField] は基本的にはMonoBehaviourやそのほかシリアライズできるクラスにしか対応していません(書いてもインスペクタに出ない)。インターフェースも [SerializeField] を消してしまってもスクリプト上で代入すれば使えはしますが、せっかくだしUnity上でドラッグアンドドロップしたい!そんな方にお勧めなのがOdinです。

assetstore.unity.com

public class StageSelectManager : SerializedMonoBehaviour
{
    [SerializeField] IStageSelectView view;

実は先ほどのStageSelectManagerはMonoBehaviourではなくSirenix.OdinInspector名前空間のSerializedMonoBehaviourを継承しています。これを継承することでなぜだかわかりませんがインターフェースでもインスペクタに表示できるみたいです。めでたしめでたし。

ほかに書くことなかったっけ……?

後編に書こうと思ってたこと少なくとも複数あったはずなんですがこれしか思い浮かばねえ………… とりあえずこれで終わります。思いついたら追記します…………

*1:にしようと思ってたんですが別に書くことにします……

*2:もはや埋める気が感じられない。今はただ埋めてくれた他の人達に感謝を

*3:実際のStageSelectManagerはなんかConfigManagerとかRankingSelectとか混じっててほかに転用しづらいのでそううまくはいきません。誰か直してください。