Unityのコードコメントからドキュメントを自動生成したいならDocFXはどうでしょう

前置きが不要な人は[こちら](#unityにおけるdocfx)からどうぞ。

# コメントによるドキュメント生成

ソースコード内に決まった形式でコメントを残すことで、そのコメントを基にAPIリファレンスなどのwebページをドキュメントとして生成するツールがあります。

コードに書いたコメントでドキュメント(APIリファレンスなどのwebページ)まで生成できれば、APIを **作る** 人用の資料をコードにコメントとして残しつつ、APIを **使う** 人用の資料をwebページとしてツールで自動生成できるので、特にAPIやライブラリ、プラグイン開発者には助かるツールといえるでしょう。
明確なメリットもあってか、いろいろな開発環境に対応するツールがあります。

* **doxygen** : http://www.doxygen.jp
* **javadoc** : https://docs.oracle.com/javase/jp/8/docs/technotes/tools/windows/javadoc.html
* **Swagger** : https://swagger.io
* **Sphinx** : http://www.sphinx-doc.org/en/master/
* **jazzy** : https://github.com/realm/jazzy

## C#におけるドキュメント生成
C#の代表的な開発環境である**Visual Studio**にてコメントのフォーマットが決められており、実質これが標準になっています。

```c#:summaryコメント例
/// <summary>
/// 関数の説明をここに書く
/// </summary>
public void DoSomething() {
  ...
}
```

詳細：[XML コメントによるコードの文書化](https://docs.microsoft.com/ja-jp/dotnet/csharp/codedoc)

また、Visual Studioでは `///` と入力するだけで `<summary>` のxmlタグの入力を補完してくれます。

上記microsoftの記事でも解説してくれている通り、Visual Studioそのものにドキュメント生成のためのxml出力機能があります。しかし、Unityのプロジェクトに関しては勝手が違うためかxml生成ができないようで、doxygenや[Sandcastle](https://archive.codeplex.com/?p=sandcastle)を使用している人が多いようです。

* [Unity C#でXMLドキュメントを作成したい](https://teratail.com/questions/154421)
* [export code documentation in XML format using Visual Studio](https://forum.unity.com/threads/export-code-documentation-in-xml-format-using-visual-studio.371763/)

## DocFX
しかし、調べてみると [DocFX](https://dotnet.github.io/docfx/index.html)というdotnet製のツールがあり、出力されるwebページもモダンでカッコよかったので、Unityで使用できないか試してみました。

# UnityにおけるDocFX
本題です。UnityプロジェクトでDocFXからwebページを出力するための手順を以下で述べます。なお、筆者の環境は Mac / Unity2018.3 / Visual Studio 2017 です。

## 1.セットアップ
[DocFX Getting Started](https://dotnet.github.io/docfx/tutorial/docfx_getting_started.html)

Homebrewでインストールします。

```
$ brew install docfx
```

`init` コマンドで出力ディレクトリを作成します

```
$ docfx init -q -o <ディレクトリ名>
```
このコマンドを打った時点でwebサイト生成のためのメタデータ群が出力ディレクトリ先に作成されます。
<img width="284" alt="スクリーンショット 2019-05-13 19.32.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274974/82470551-245e-689e-b726-9a56b674464a.png">
https://github.com/naninunenoy/UnityDocFXSample/tree/master/doc

## 2.プロジェクトファイル(`.csproj`)の作成
DocFXでのドキュメント生成にはコメント付きのソースコードに加え、プロジェクトの中身を表すファイルが必要です。先の手順で作成された `src/` ディレクトリ下にプロジェクトファイル(`.csproj`)とソースコード(`.cs`)を実際と同じ階層で配置する必要があります。

ここが１つのポイントなのですが、Unityで`.csproj`を作るには以下の条件を満たす必要があります。

1. Unity EditorとVisual Studioを連携させること(*)
2. 自分のプロジェクトにAssembly Definitionを定義すること

(*)もしかしたらMonoDevelopやRiderでもできるのかもしれませんが、筆者はVisual Studioしか使った経験がないので未確認です 。

UnityをVisual Studioと連携させれば`.sln`ファイルは作られますが、`.csproj`は作られません。しかし、Unity EditorからのAssembly Definitionを定義すればそれに対応する`.csproj`が作られるため、この仕様を利用します。

Unity Editorからプロジェクトの`Assets/`直下なり`Assets/Scripts/`なりで右クリックを押し[Create]から[Assembly Definition]を選択し、任意の名前をつけて作成します。
![スクリーンショット 2019-05-13 19.48.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274974/825d30df-ad4a-7f61-6f2a-8b7f96368a7e.png)

次に新規でScriptを作成し、そのScriptをダブルクリックしてVisual Studioを起動させます。すると、Unityのプロジェクトのroot階層(`Assets/`の上) にAssembly Definitionにつけた名前と同じ`.csproj`ファイルが出来上がっています。

## 3.ソースコードにコメントを打ち込む
Scriptに以下のようにコメントを入れます。

```c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MyPlugin;

// namespaceをつけるのを忘れずに!!
namespace docfxSample {
    /// <summary>
    /// Hoge component.
    /// </summary>
    public class HogeComponent : MonoBehaviour {
        /// <summary>
        /// Start is called before the first frame update
        /// </summary>
        public void Start() { }
        /// <summary>
        /// Update is called once per frame
        /// </summary>
        public void Update() { }
    }
}
```

## 4.ドキュメント生成
2.と3.の手順で作成した`.csproj`と`.cs`ファイルを、1.の手順で作成したディレクトリの`src/`下にコピーします。この時、Unityプロジェクトの階層を再現する必要があるので、`Assets/Scripts/`ディレクトリもコピーします。(.metaはあっても邪魔にはならないはずですが、不要です)
<img width="315" alt="スクリーンショット 2019-05-13 20.03.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274974/86a0d50c-0e92-8e5e-7bb8-83483c01d9ec.png">

これでお膳立ては済んだので、ドキュメントのディレクトに移動し、以下のコマンドでドキュメントを生成します。

```
$ cd <initで作成したディレクトリ>
$ docfx metadata
$ docfx build
```

そうすると、`_site/` というディレクトリが作られ、この配下にあるものがwebサイトの構築に必要なコンポーネントになります。その中の`api/`配下にAPIリファレンスのための`.html`が生成されます。
<img width="326" alt="スクリーンショット 2019-05-13 20.07.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274974/bd735e28-15be-70e4-747b-81a188c959da.png">


docfxSample.HogeComponent.html をダブルクリックすると

![スクリーンショット 2019-05-08 16.00.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274974/f1d64093-f6e2-586c-2e15-76820fdf863e.png)
　　~略~
![スクリーンショット 2019-05-08 16.01.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274974/f7cc8573-754f-cd11-bcd0-710aa0b3f58f.png)

のようなページが表示されると思います。

実際のwebサイトのように見たければ

```
$ docfx --serve
```
のコマンドを打って、http://localhost:8080 にブラウザからアクセスすれば見られます。

### 4.1 Inherited Members長すぎ問題
折角作られたページですが、継承を全て網羅しているため`MonoBehaviour`の派生クラスではInherited Membersがものすごく長いです。しかも折りたたんだりできません。これに対処するにはfilter機能を導入する必要があります。

[Filter inherited members?](https://github.com/dotnet/docfx/issues/1780)
リンク先のissueで説明してくれていますが、実際に使うには結構言葉足らずです。

**手順1** ドキュメント出力ディレクトリの直下に`filterConfig.yml`を作成します

```yml:filterConfig.ymlの例
apiRules:
- exclude:
    uidRegex: ^System\.Object
    type: Type
- exclude:
    uidRegex: ^UnityEngine\.Object
    type: Type
- exclude:
    uidRegex: ^UnityEngine\.Component
    type: Type
- exclude:
    uidRegex: ^UnityEngine\.Behaviour
    type: Type
- exclude:
    uidRegex: ^UnityEngine\.MonoBehaviour
    type: Type
```

**手順2** `docfx.json` に以下のようにfilterの記述を追加

```json-doc
{
  "metadata": [
    {
      "src": [
        {
          "files": [
            "src/**.csproj"
          ],
          "exclude": [
            "**/bin/**",
            "**/obj/**"
          ]
        }
      ],
      "dest": "obj/api",
      "filter": "filterConfig.yml" // この記述を追加
    }
  ]
}
```

**手順3** metadata作成時に`--filter`オプションを付与

```
$ docfx metadata --filter filterConfig.yml
```

(これ書くなら手順2は要らなくない?🤔)

こうして`docfx build` すればこんな感じにスッキリします。
![スクリーンショット 2019-05-08 16.40.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274974/17c0398a-b87a-1c05-f995-2bd2f1ea7919.png)

## 5.色々試す
Unityの特殊フォルダである`Plugin/`下に別のAssembly Definitionを追加したり、namespaceいじってみたり、2バイト文字やemojiを入れてみたりしました。

[Github Pagesで載せたのでサンプルをご覧ください](https://naninunenoy.github.io/UnityDocFXSample_site/)←ヘッダの[Api Documentation]から移動してください。
 - [大元のGitHubリポジトリ](https://github.com/naninunenoy/UnityDocFXSample)

試した結果以下のことがわかりました。

 * publicのフィールド/プロパティ/メソッドのみ反映される
 * namespaceが未設定で`global::`だと反映されない
 * namespaceごとに新たなページができる
 * 2バイト文字もemojiも表示できる
　　![スクリーンショット 2019-05-08 16.02.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274974/1a4d20b5-c259-aaa0-f203-2b429f595105.png)

しかし、毎回`.csproj`を更新したり、`.cs`ファイルを階層ごとにコピーするのは手間なので、shellやUnityのPostProcessで自動化を試みる工夫が欲しくなるでしょう。
あと、Assembly Definitionなしでも使える術をご存知の方がいれば是非教えてください。

### 5.1 .gitignore
なお、[gitignore/Unity.gitignore](https://github.com/github/gitignore/blob/master/Unity.gitignore)を使っている場合、`.csproj`がgit管理外になってしまうので、プロジェクトのソースコードとDocFXのドキュメントを一緒のリポジトリで管理したい場合はこの.gitignoreは最上段の階層に置かないように注意してください。

# 終わりに
ソースコードのコメントだけでモダンでいい感じのwebページが作成できました。また、サイトを作る機能も充実してそうなので、リッチなサイトも作れそうです。
自分の作ったUnityのアセットなどのライブラリのwebページを作ってみたい人は試してみて損はないと思います。👍

# 参考
* [DocFXを使ってC#のソースコードからAPIのドキュメントを作成](https://qiita.com/sukakako/items/072b6145f15683eb0add)