YAMADA TAISHI’s diary

ゲームについてとか私の日記とか。このブログのあらゆるコードは好きにどうぞ。利用規約があるものは記事内のGitHubのRepositoryのリンクで貼られていると思うので、そちらを参照ください。

UnityでRoslyn触ってみた

こんにちは、やまだたいし( やまだ たいし (@OrotiYamatano) / Twitter )です。
先日GitLabをつかってCIを走らせるようにしたのですが、さらに便利にしたいと思い
Roslynを触ってみることにしました。
本記事はその内容の備忘録です。

目次


そもそもRoslynとは?


NETコンパイラープラットフォーム(.NET Compiler Platform)のことです。
コード名および通称は「Roslyn(ロズリン)」。(以下、Roslynと表記)
簡単にいうとRoslynはIDEコンパイル時の情報を提供してくれるAPIみたいなものらしいです。
もらえる情報は構文解析・意味解析を行った情報っぽい?
ツールとエンド ユーザーが豊富な情報コンパイラを共有するためにある様子。

具体的にそれを通じて何が出来るようになるのかというと "アナライザー" と "コード修正機能" を構築できるようです。
後、ソース生成も。

UnityでRoslynを使うメリット


Unityを開いた時などにコードの違反を見つけたりが出来ます。
例えば、「UniRxを使ったときは必ずSubscribeにAddToをつける!」というプロジェクトルールを作りたい場合などに適しています。

初心者にわかりやすく、追加する意義を解説をします。

リーダブルコードを読んだことありますでしょうか?
いってしまえば読みやすく良いコード書こうぜ!って話なのですが。
なぜ可読性を良くする必要があるのかというと可読性の悪いコードはソースコード品質が悪くなりがちだからです。

品質の悪いコードはコードスメル(コードの臭い)と言われ嫌われます。
ヤツ(コードスメル)は駆逐しなきゃぁいけません。

とはいえ、ゲーム業界は好き勝手につくりたい人が多く、
コードスタイルの統一を極度に嫌う人が居ます。

また、コードレビューでさえ嫌う人がいます。
「コードの指摘」は「コードを作成した本人の否定」ではないにも関わらず、
混同し「意地悪されている」と勘違いしてしまう人が一定数いるようです。

特に「コードフォーマットの指摘の重要性を理解していない人」は
「コードフォーマットの指摘をする人」を「プレゼン資料の荒探してる人」と同じように見てしまう。

「コード指摘する側」は「キレイなコードを書いて欲しいと思うのに書いてくれない」と思い
「コードを指摘される側」は「好きにコード書きたいのにちょっとしたことで指摘されコードを好きに書かせてくれない」と
思うことになります。
そのようになってしまうと、対人的な衝突を生み、互いが辛い思いする羽目になってしまいます。

そのため、コード規約は大事だと理解していながら
コード指摘によって対人的な衝突を生んでしまうことを忌避し
コードスタイルが悪くても放置されてしまうことが多々あります。

これではコード品質が落ちてしまいます。ジレンマ。

であれば、どうすれば良いのか。
コードフォーマットの指摘は機械(CI)にやって貰えば良いんです。

また、晒されるようにSlackで通知が飛ぶようになれば、必然的に皆、治すようになると思います。

そういったことをするために、このRoslynは有効なのです。

もちろんUnity上だけでなくIDE上でも利用可能ですがUnityのビルド機能を使ってCIで通知を出すならRoslynを使うのが便利です。
(Unity上でつかうならUnity 2020.2以上)

Roslynの基礎的な使い方はコチラが参考になるかも?
swet.dena.com

コード指摘について熱く語っておきながら、残念。今回はSource Generatorを試します。
(コード指摘させるのは本記事のまとめにも軽く触れていますが、他の方が記事を作ってらっしゃったりするのでソチラを読んだほうが良いです)

使い込めばゲーム中に動的にコード生成が出来るのでDIのような挙動が作ろうと思えば作れるはずです。
かなりFrameworkライクな機能だと思いました。

そもそも今回触るSource Generatorが
アップルさんが「動的コード生成駄目」って言うんもんだからRoslynチームが開発したものだそう
なかなかどうしていい感じ。

実際に入れてみる


環境:
Unity2021.3.11f1
Rider:2022.2.3

今回はUnity公式で紹介されているCodeAnalysisを使ってみようと思います。

docs.unity3d.com

今回はJetBrains商品のRiderで入れてみます。
Riderの新規作成(New Solution)でプロジェクトを作成します。

ヘッダメニューのTools>NuGet >Hide Nuget Tool Windowを選択(フッタにあるならソレ選択でもOK)

CodeAnalysis.CSharpを検索します。
Unity2021.3で使えるアナライザーのVersionは3.8のようですので、3.8を選択します。
そして+を選択します。

Unity公式に載っている、ExampleSourceGenerator.csを作成。

そしてリリースを選びBuildを行います。

次にUnityでCodeAnalysisを使えるようにするためにdllをUnityに追加します。

JetBrainsで追加した場合は以下にdllファイルが出来ていると思うので、ソチラを Unity プロジェクトの Assets フォルダー内にコピーします。

dllが出来る場所:(Project名)\bin\Release\netstandard2.0

コピーしたらUnity上でコピーしたdllファイルを選択しInspectorにて各プラットフォームのチェックを外します。
そしてApply

AssetLabelsをクリックして、ラベルマークよりRoslynAnalyzerタグを追加。

↑でエンター

Unity公式に載っている、HelloFromSourceGenerator.csをAsset配下に作成。

で、適当なGameObjectにスクリプトを貼り付けて再生。

できた

他にもライブラリがたくさん


今回使ったソースジェネレーターだけでもいくつかライブラリがあります。
(全部Unityで使えるとは限らないけれど)
↓ライブラリまとめ
github.com

Roslynベースでも色々あります。
↓ライブラリまとめ
github.com

まとめ


今回はRoslynについては以上にします。
本当はRoslynとUnityでStyleCopを触るところまでやったのですが、
Unityは現在EditorConfigやAdditionalFilesをいい感じに処理してくれず思った通りな挙動をしなかったので割愛です。
(デフォルト設定で動かすぐらいなら難なくできます)

厳密に言うとAdditionalFilesは コチラ などで導入すればある程度は処理されるのですが、
「StyleCopで特定ディレクトリのファイルのみ検査させるように」&「AdditionalFilesの設定を適切に読み込む」という2つの条件を満たそうとすると上手く動かない。
特定のディレクトリだけで動かす方法は現在 こちら で紹介しているasmdefの方法がありますが、
前述の拡張の挙動との兼ね合いを考えると無理なのである……。残念。

私個人としてはUnityのエディタスクリプトでRoslynのAdditionalFilesを指定できる部分があったので
「そのへんを頑張れば、なんとか出来る可能性があるかも」とは思いましたが、
そこまでやる気にならなかったので、後はやる気がある人に任せます……。

後、触ってみた所感、
今後SourceGeneratorを使ったUnityでいい感じのゲームFrameworkが出てきそうだと思いました。
私はFrameworkを作る側の人間じゃないのでガッツリは触らないと思いますが、
なにかおもしろい利用方法を浮かんだ人は是非教えてほしいです。

以上、UnityでRoslyn触ってみたでした。