【Unity】SRDebuggerのタブの拡張方法

# はじめに

本記事は[サムザップ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/sumzap)の23日目の記事です。

昨日は [noguchi_toma](https://qiita.com/noguchi_toma) さんの[<font color="LimeGreen">パケットキャプチャツール/Charlesを試してみた</font>](https://qiita.com/noguchi_toma/items/d50a85c6b42b75f61fed)でした！

※ [<font color="LimeGreen">【Unity】SRDebuggerの使い方と拡張方法の紹介</font>](https://qiita.com/tomoriaki/items/a2372333f8b73b421113)の補足記事でもあります。

# SRDebugger

- 実機でコンソールログを確認したい
- 実機でプロファイラーを確認したい
- 特定の状態を再現するためにキャラクターのステータスなどを変更したい

上記のような機能が必要になる場面は多々あると思います。
それらの要望を手軽に実現出来るアセットが[SRDebugger - Console & Tools On-Device](https://www.assetstore.unity3d.com/jp/#!/content/27688)です。

[![2017-12-02_19h49_04.png](https://qiita-image-store.s3.amazonaws.com/0/126970/66fd51e4-2f90-18e6-3664-3326644dd65d.png)](https://www.assetstore.unity3d.com/jp/#!/content/27688)

#### 実機でコンソールログを確認する

![ss2.gif](https://qiita-image-store.s3.amazonaws.com/0/126970/c6a15852-05a7-ee16-8375-275abce6ebc0.gif)

#### 実機でプロファイラーを確認する

![ss3.gif](https://qiita-image-store.s3.amazonaws.com/0/126970/482d1966-94c2-ff46-54ae-029887bd1365.gif)

#### オプションタブにデバッグ機能を実装する

![ss4.gif](https://qiita-image-store.s3.amazonaws.com/0/126970/d6116aa1-8f0e-abb9-0faf-ed362d0117ab.gif)

## タブの拡張方法

今回は独自のオプションタブを例に作成します。

### オリジナルオプションタブのプレハブ作成

`Assets > StompyRobot > SRDebugger > Resources > SRDebugger > UI > Prefabs > Tabs > Options.prefab`を選択して複製(Ctrl + D)して、複製したプレハブ名をOriginalOptionsにリネームします。

![2017-12-21_17h24_33.png](https://qiita-image-store.s3.amazonaws.com/0/126970/3d7ad2b1-f59b-41a2-47a2-cba7c8c029f2.png)

### SRTabコンポーネントのパラメータ編集

![2017-12-21_17h51_01.png](https://qiita-image-store.s3.amazonaws.com/0/126970/502155c1-5b5f-0621-ec41-32f3cd96994f.png)

SRTabのTitleとKeyをOriginalOptionsにします。
一度SRDebuggerを起動してみると既にOriginalOptionsタブが追加されていることが確認出来ます。
ですが、Optionsタブに追加したデバッグ機能を参照していて独自のオプションとしてはまだ機能していません。

![2017-12-21_18h04_04.png](https://qiita-image-store.s3.amazonaws.com/0/126970/0a9b6569-d985-3d25-d16d-fc646b44934f.png)

### OriginalSROptionsスクリプトの作成

`Assets > StompyRobot > SRDebugger > Scripts > SROptions.cs`を選択して複製(Ctrl + D)して、複製したスクリプト名をOriginalSROptionsにリネームします。

![2017-12-21_17h24_34.png](https://qiita-image-store.s3.amazonaws.com/0/126970/73151768-a0a4-3a2d-9cce-88f68b6289ac.png)

スクリプトを開き、先頭のdelegateを削除、SROptionsになっている箇所をOriginalSROptionsに書き換えます。

```csharp
public partial class OriginalSROptions
{
    private static readonly OriginalSROptions _current = new OriginalSROptions();

    public static OriginalSROptions Current
    {
        get { return _current; }
    }

    public event SROptionsPropertyChanged PropertyChanged;
#if UNITY_EDITOR
    [JetBrains.Annotations.NotifyPropertyChangedInvocator]
#endif
    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, propertyName);
        }
    }
}
```

### OriginalOptionsTabControllerコンポーネントの作成

`Assets > StompyRobot > SRDebugger > Scripts > UI > Tabs`にOriginalOptionsTabController.csを作成します。

![2017-12-21_18h53_18.png](https://qiita-image-store.s3.amazonaws.com/0/126970/3ab96704-3dba-4071-c6b4-17c6da705487.png)

スクリプトを開き、OptionsTabControllerコンポーネントを継承します。
Startイベントメソッドをオーバーライド、PopulateメソッドをOriginalSROptionsを参照するように基底クラスのメソッドを隠蔽して実装します。

```csharp
using System.Collections.Generic;
using SRDebugger.Internal;


namespace SRDebugger.UI.Tabs
{
    public class OriginalOptionsTabController : OptionsTabController
    {
        protected override void Start()
        {
            PinButton.onValueChanged.AddListener(SetSelectionModeEnabled);
            PinPromptText.SetActive(false);
            Populate();
        }

        protected new void Populate()
        {
            var sortedOptions = new Dictionary<string, List<OptionDefinition>>();

            foreach (var option in SRDebuggerUtil.ScanForOptions(OriginalSROptions.Current))
            {
                // Find a properly list for that category, or create a new one
                List<OptionDefinition> memberList;

                if (!sortedOptions.TryGetValue(option.Category, out memberList))
                {
                    memberList = new List<OptionDefinition>();
                    sortedOptions.Add(option.Category, memberList);
                }

                memberList.Add(option);
            }

            var hasCreated = false;

            foreach (var kv in sortedOptions)
            {
                if (kv.Value.Count == 0)
                {
                    continue;
                }

                hasCreated = true;
                CreateCategory(kv.Key, kv.Value);
            }

            if (hasCreated)
            {
                NoOptionsNotice.SetActive(false);
            }
        }
    }
}
```

### オリジナルオプションタブのプレハブに作成したコンポーネントをアタッチ

`Assets > StompyRobot > SRDebugger > Resources > SRDebugger > UI > Prefabs > Tabs > OriginalOptions.prefab`を選択してOptionsTabControllerコンポーネントをOriginalOptionsTabControllerコンポーネントに差し替えます。

タブの拡張は以上で完了です。

![ss1.gif](https://qiita-image-store.s3.amazonaws.com/0/126970/39437fcc-4dc7-5053-3b92-417ac18d1979.gif)

InspectorのモードをNormalからDebugに変更することで、同名のメンバ変数のパラメータを引き継いでコンポーネントを差し替えることが出来ます。

## オリジナルオプションタブにデバッグ機能を実装する

### デバッグ機能の実装

```csharp
using UnityEngine;
using System.ComponentModel;


/// <summary>
/// 独自のデバッグ機能
/// </summary>
public partial class OriginalSROptions
{
    #region 定数

    /// <summary>
    /// オリジナルカテゴリ
    /// </summary>
    private const string OriginalCategory = "Original";

    #endregion


    #region デバッグ機能

    [Category(OriginalCategory)]
    [DisplayName("ポーズ")]
    [SROptions.Sort(0)]
    public void Pause()
    {
        Time.timeScale = 0f;
    }

    #endregion
}
```

### 実行結果

![ss2.gif](https://qiita-image-store.s3.amazonaws.com/0/126970/c9a39d27-db95-bcea-a43d-33a5743c799d.gif)

# 参考記事

[【Unity】オブジェクトにアタッチされているスクリプトを Inspector でドラッグ&ドロップして置き換える方法](http://baba-s.hatenablog.com/entry/2017/09/15/100000)

# おわりに

[SRDebugger](https://www.assetstore.unity3d.com/jp/#!/content/27688)は導入の手軽さと拡張性の高さを兼ね備えた素晴しいアセットです。
興味を惹かれた方はお手に取ってみてはいかがでしょうか。

明日の[サムザップ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/sumzap)は [ninomiya_shota](https://qiita.com/ninomiya_shota) さんの[<font color="LimeGreen">波動に渦に！極座標移動による回転拡縮シェーダーを作ってみた</font>](https://qiita.com/ninomiya_shota/items/a58f8e7fc43204ef25f4)です！