宴のカスタムコマンド作成について


# 「宴」とは？

> 「宴」はビジュアルノベルをUnityで簡単に作成するためのツールです。シナリオデータはExcelでシンプルに書けるので、複雑なスクリプトの文法を覚える必要はありません。Unityを使っているためPCだけでなく、スマートフォンやブラウザ用のアプリを作ることもできます。ビジュアルノベルに限らず、ゲームの会話シーンの作成を作ることもできます。

(公式サイトより引用)

また、「宴」はアセットストアで購入・ダウンロードが可能です。
https://www.assetstore.unity3d.com/jp/#!/content/15905

# カスタムコマンドとは？

「宴」ではカスタムコマンドを作成することで、Excelで使用できるコマンドに独自のものを追加することができます。
Debug.Logを呼び出すサンプルの説明が公式サイトにあります。
http://madnesslabo.net/utage/?page_id=3195

# 作成例

ではさっそくカスタムコマンドを作成してみます。
どうせ作るなら今までにない機能を「宴」に追加してみたいですね…。

と思っていたらTwitterでこんな動画が！これは「宴」から動かせたら面白いかも…(棒)

<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr">UnityのサイクロンX10(電動オナホール)対応できたよー。回転パターン10種類・強弱10段階をUnityから制御可能！Windows対応。これぞちんマシンインターフェイスや！！&#10;<a href="https://t.co/g9oHuqVd40">https://t.co/g9oHuqVd40</a> <a href="https://t.co/KZOl6gvKiP">pic.twitter.com/KZOl6gvKiP</a></p>&mdash; tnayuki (@tnayuki) <a href="https://twitter.com/tnayuki/status/661869543921311744">2015, 11月 4</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

ソースも公開されているので、これを「宴」のカスタムコマンドから呼び出すようにしたいと思います。

```CustomCommandCycloneX10クラス
    public class CustomCommandCycloneX10 : AdvCustomCommandManager
    {
        public override void OnBootInit()
        {
            Utage.AdvCommandParser.OnCreateCustomCommnadFromID += CreateCustomCommand;
        }

        public override void OnClear()
        {
            CycloneX10 cycloneX10 = GetComponent<CycloneX10>();
            if (cycloneX10)
            {
                cycloneX10.pattern = 0;
                cycloneX10.level = 0;
            }
        }

        public void CreateCustomCommand(string id, StringGridRow row, AdvSettingDataManager dataManager, ref AdvCommand command)
        {
            switch (id)
            {
                case "CycloneX10":
                    command = new AdvCommandCycloneX10(row);
                    break;
            }
        }
    }
```

まず、AdvCustomCommandManagerを継承したクラスを作成します。
OnBootInitが初期化時に呼ばれるので、そこでカスタムコマンドを作成するデリゲートを追加します。
コマンド名は「CycloneX10」とします。
また、シナリオ終了時にOnClearが呼ばれるので、回転を止める処理を書いておきます。

```AdvCommandCycloneX10クラス
    public class AdvCommandCycloneX10 : AdvCommand
    {
        public AdvCommandCycloneX10(StringGridRow row)
            : base(row)
        {
            this.pattern = ParseCell<int>(AdvColumnName.Arg1);
            this.level = ParseCell<int>(AdvColumnName.Arg2);
        }

        public override void DoCommand(AdvEngine engine)
        {
            CycloneX10 cycloneX10 = engine.GetComponent<CycloneX10>();
            if (cycloneX10 == null)
            {
                cycloneX10 = engine.gameObject.AddComponent<CycloneX10>();
            }

            cycloneX10.pattern = pattern;
            cycloneX10.level = level;
        }

        int pattern;
        int level;
    }
```

次に、実際にコマンドの処理を行うためのAdvCommandクラスを継承したクラスを作成します。
コマンド処理クラスにはコンストラクタでExcel上のコマンド行の情報が渡されるので、それをパースして保管します。
実際に処理を行う際はDoCommandメソッドが呼ばれます。ここではサイクロンX10を制御するためのコンポーネントを(なければ追加してから)呼び出します。Arg1を回転パターン、Arg2を回転の強さとしました。

作成したソースは以下にまとめて公開しました。
https://github.com/tnayuki/Unity-UtageForCycloneX10

# 使用方法

まず作成したカスタムコマンドマネージャをシーン中のAdvEngineに追加します。

![コンポーネントの追加](https://qiita-image-store.s3.amazonaws.com/0/38786/697f59b7-e435-7306-577d-67fe5936d6f4.png "コンポーネントの追加")

さらにExcelに以下のように記述することで…

![Excel.png](https://qiita-image-store.s3.amazonaws.com/0/38786/ebecc7c3-dc80-4d1a-3398-fc5deff74ebf.png "Excel.png")

<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr">ふむ…セリフの前後で回転パターンが変わっているのがお分かりいただけるだろうか？ <a href="https://t.co/iZE0yvhXrt">pic.twitter.com/iZE0yvhXrt</a></p>&mdash; tnayuki (@tnayuki) <a href="https://twitter.com/tnayuki/status/679942736766607360">2015, 12月 24</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

# アセットコンテスト大賞受賞おめでとうございます！

ちょうど本日結果が発表されたUnityアセットコンテストで、「宴」は大賞を受賞しました！
おめでとうございます！

http://blogs.unity3d.com/jp/2015/12/24/unityassetcontestjp1st/

# そしてメリークリスマス！

以上、12日目に続きUnity 2 Advent Calendar 2015の24日目として書かせていただきました。

さて、今夜はクリスマスイブ。ひとりで過ごしたり勉強会に参加したり、いろいろな過ごし方があると思いますが、今回作成したカスタムコマンドを使えばUnityとより親密な夜を過ごせるんじゃないでしょうか。
ではぼくはクリスマスプレゼントを買って家に帰ります。みなさんいい夜を！