Qemelly(けめる)のプログラム備忘録

Unity / AtCoderについて書きます

Unityの便利な無料ライブラリ(パッケージ)を紹介する

今回はUnityの便利なライブラリ(パッケージ)を列挙していきます。
全部GitHubに公開されています。

⚠️注意

  • 非常に情報の確度が低い内容になっています。間違い等があればコメントにて指摘ください。
  • 個人の感情が多分に含まれます。ご注意ください。

目次

結論

以下は全部独断と偏見です。異論は当然認めます。

パッケージ名 個人的好き度 学習難易度 汎用性
UniTask ★★★★☆ ★★★★★ ★★★☆☆
UniRx ★★★★★ ★★★★☆ ★★★☆☆
DOTween ★★★★★ ★★☆☆☆ ★★★★★
VContainer ★★☆☆☆ ★★★☆☆ ★★★★☆
uPalette ★★☆☆☆ ★☆☆☆☆ ★★☆☆☆
LucidAudio ★★★☆☆ ★☆☆☆☆ ★★★☆☆
LucidEditor ★★☆☆☆ ★★☆☆☆ ★★☆☆☆
MessagePipe ★☆☆☆☆ ★★☆☆☆ ★★☆☆☆
SoftMaskForUGUI ★★★★☆ ★☆☆☆☆ ★☆☆☆☆

1. UniTask - 非同期処理何でも屋さん

github.com

超有名シリーズ。非同期処理(async/await)を使いたい場合はまず導入したいです。

簡単に複雑な非同期処理(処理を同時並行で行うこと)が記述できます!

一応、UnityにもCoroutineAwaitableといった非同期処理用の機能が存在しますが、より応用が利くのはUniTaskといったイメージです。

ですが、後述の理由から、無理してUniTaskを使うまでもない機能はCoroutine等で対応した方が安全な場合も多いです。

✅Good

  • 非同期処理ができる
    • ロード中にグルグル表示したり、ターン制ゲームの待ち状態を作ったり、条件達成したら動くエネミーを作ったり...
    • ゲームジャンルによってはかなり重宝する
  • 何でも待てる
    • UniTask, Coroutine, Async○○, WaitWhile(Func)...
    • 後続のUniRx等とも相性がいい
  • 文法自体は分かりやすい
    • Coroutineよりも直感的

❌Not Good

  • 学習コストが超絶高い
    • UniTaskを使った非同期処理を適切に書くのがめちゃムズイ
      • 偉そうな口調であれだけど、自分もまだうまく使えてない...
  • 待ちの処理を止めるのが非常に面倒
    • 止めないと大変なこと(=メモリリーク)になる可能性大だけど、正しく止めるのが難しい

使用例

(厳密には下の使用例は無作法です。メモリリークの危険性があります。全メソッドにCancellationTokenを渡しながら例外処理で破棄するようにしたり、MonoBehaviourのライフタイムに合わせて破棄するGetCancellationTokenOnDestroy()を使うべきです。)

public class UniTaskTest : MonoBehaviour
{
    // 1秒待ったり
    private async UniTask Wait1Second()
    {
        await UniTask.Delay(1000);
        Debug.Log("1秒経過");
    }

    // ロードを待ったりできる
    private async UniTask WaitLoad()
    {
        var hoge = await Resources.LoadAsync("Prefabs/Hoge"); // ファイルをロードする
        Debug.Log("ロード完了");
    }

    // 実際に使う場合
    private void Awake()
    {
        WaitLoad().Forget();
        Debug.Log("ロード中の処理");
    }
}

2. UniRx - リアクティブの広辞苑

github.com

超有名シリーズその2。

よくUniRx/UniTaskとして紹介されることもありますが、元々一緒だったライブラリが分離した、という経緯があります。

こちらも非同期処理を扱えるほか、値の変化を監視するObserverパターンを実現するのが非常に簡単になります。

何でも屋さん感もかなり高いです。頼りすぎるとコードがぐちゃぐちゃになっちゃうかも。

✅Good

  • Observerパターン,MVP系パターンの実装が非常に楽になる
    • Observerパターン=値を監視して、その変化だけをクラス間で伝達しあうデザインパターン
      • クラス間の結合が疎になる他、コードが直感的になる場面も多い
    • MVP=Observerパターンを応用して、3つのクラスで上手くやり取りするデザインパターン
      • スコアの変化をTextに伝えたり、HPの変化をHPバーに伝えたりが簡単に書ける(書きこぼしが出ない)

❌Not Good

  • 非同期処理ができる→それUniTaskでいいじゃん!
  • 学習コストが高い
    • 結構クセが強い
    • 肝心のMVPパターンやObserverパターンのメリットが体感できなかったら学習意欲が出ない

使用例

個人的に「MVPパターンといえばUniRx!」と言っていいくらい毎回利用しています。

キー入力等を読み取る際もかなり便利です。

public class PlayerCollision : MonoBehaviour
{
    [SerializeField] private HpModel hpModel;

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Enemy"))
            hpModel.Add(-1);
        if (other.CompareTag("HealItem"))
            hpModel.Add(1);
    }
}

public class PlayerPresenter : MonoBehaviour
{
    [SerializeField] private HpView hpView;
    [SerializeField] private HpModel hpModel;

    private void Awake()
    {
        hpModel.Hp 
            .Subscribe(hp => hpView.Set(hp)) // Hpが変わったら勝手にhpView.Set(hp)が実行される
            .AddTo(this); // 購読解除処理
    }
}

/// <summary>
/// Hpを表示するView
/// </summary>
public class HpView : MonoBehaviour
{
    [SerializeField] private TextMeshProUGUI hpText;

    public void Set(int hp)
    {
        hpText.text = hp.ToString();
    }
}

/// <summary>
/// Hpを管理するModel
/// </summary>
public class HpModel : MonoBehaviour
{
    public IReadOnlyReactiveProperty<int> Hp => _hp; // <= ここの値が変わったら勝手に通知される
    private readonly ReactiveProperty<int> _hp = new();

    public void Add(int score)
    {
        if (_hp.Value + score < 0) 
            _hp.Value = 0;
        _hp.Value += score;
    }

    public void Reset()
    {
        _hp.Value = 3;
    }

    public int GetScore()
    {
        return _hp.Value;
    }
}

3. DOTween - アニメーションがコードで書ける

GitHub - Demigiant/dotween: A Unity C# animation engine. HOTween v2

簡単なアニメーションがコードで書けます!

メソッドチェーン(LINQとかUniRxの記法とか)に慣れていれば学習難易度もかなり低いです。

✅Good

  • コードでアニメーションが書ける
    • 一々Timelineとかを使わなくても簡単なアニメーションは書ける喜び
  • Callback等にも対応している
    • アニメーションが終わった後にメソッドを実行、などの簡単な非同期処理もOK
  • 複数のアニメーションを連結することも

❌Not Good

  • 強いて言うなら、DebugのWarningがイマイチ分かりづらい(Warning消そうとしたら結構面倒)

4. VContainer - らくらくDIコンテナ

github.com

vcontainer.hadashikick.jp

DI(依存性注入、Dependency Injection)を簡単に行うためのパッケージ。DIコンテナです。DIについてはここでは踏み込んで説明しませんが、非常に有用な概念です。誤解を恐れずにメリットを一言でまとめると、

Awake,Startの順番やオブジェクトの参照に迷うことが無くなる

↑こんな感じ。

✅Good

  • 簡単にDIできる
    • DIはいちいちコンストラクタや自前のInit()メソッドから参照を注入しないといけないので書き忘れが多発したり何よりちょっと面倒だけど、DIコンテナを使えばそれは軽減する
  • そもそもDIは頼もしい
  • 軽い(らしい)
    • 競合のDIコンテナであるZenjectよりもかなりパフォーマンスがいいらしい

❌Not Good

  • 学習コストが高め
    • そもそもDIの概念を理解するのに結構勉強しないといけない
    • VContainer自体も若干ムズカシイ
  • 難しい参照関係を解決しようとすると、自前で書いた方が分かりやすい感がある
    • (本当に個人の感覚です)
    • そもそもVContainerに慣れてないので、こういう感覚になってる気がする(そもそも複雑なパターンは自分で実装できない)

5. uPalette - UIの色を管理できる

github.com

uPaletteはUIの色を一括で管理して、編集しやすくするパッケージです。本当にそれだけなので書くことは無いのですがオススメです。

6. LucidAudio - 分かりやすいAudioManager

github.com

Unityの音管理は誰もが面倒だと感じるはずです。たいていの人は自分でテンプレートを作ったり、何らかのパッケージに頼ったりしているのではないでしょうか。

そんな頼れる音管理系のパッケージの候補の1つに、LucidAudioが挙げられます。

✅Good

  • 超シンプル
    • 基本的な機能は簡単なメソッドチェーンで実行できる

❌Not Good

  • 複雑な音管理はできない
    • これは良い点でもあるが...
    • 多分再生開始時間などは設定できない
    • 音管理にこだわるならfmodとかなのかな?

7. LucidEditor - 無料のEditor拡張系の中では最強?

github.com

Editor拡張と言えば有料のOdin等が有名ですが、無料でここまで多機能なのは珍しいと思います。

以下できる機能(README見た方が早い):

  • interfaceのserialize
  • Inspector上の表示を綺麗にするアレコレ
  • EditorのGUI表示を強化するアレコレ
  • GUIのイベントを楽に処理できる機能
  • その他いろいろ

8. MessagePipe - Pub/Subが綺麗に実装できる

github.com

Pub/SubはUniRxでも実装可能な機能ですが、DIコンテナと一緒に実現する場合には、MessagePipeを使うという選択肢もあります。
前提としてVContainer/Zenjectのいずれかに加え、UniTaskの導入が必要です。

9. SoftMaskForUGUI - Unityのダメダメソフトマスクを改善

github.com

Unity標準のソフトマスクは結構汚いです。できればSoftMaskForUGUI等を利用しましょう。