コガネブログ

平日更新を目標に Unity や C#、Visual Studio、ReSharper などのゲーム開発アレコレを書いていきます

【Unity】CsprojModifier と BannedApiAnalyzers を使用して、特定の関数が使われていたら警告を表示線してみる

はじめに

CsprojModifier と BannedApiAnalyzers を使用することで

f:id:baba_s:20210716162633p:plain

特定の関数が使われていたら警告線を表示できるようになります

例えば、プロジェクトにおいてチームメンバーに
重たい Unity の API を使用してほしくない時などに役に立ちます

この記事では CsprojModifier と BannedApiAnalyzers を使用して
特定の関数が使用されていたら警告線を表示する設定の方法を紹介していきます

目次

検証環境

  • Unity 2020.3.13f1
  • Visual Studio Community 2019 Version 16.8.3
  • Microsoft.CodeAnalysis.BannedApiAnalyzers 3.3.2

CsprojModifier のインストール方法

f:id:baba_s:20210716142559p:plain

PackageManager を開いて「+ > Add package from git URL...」を押して

f:id:baba_s:20210716142602p:plain

https://github.com/Cysharp/CsprojModifier.git?path=src/CsprojModifier/Assets/CsprojModifier

と入力して「Add」を押します

f:id:baba_s:20210716142606p:plain

しばらくして PackageManager に「CsprojModifier」と表示されていれば
インストール完了です

Microsoft.CodeAnalysis.BannedApiAnalyzers の入手

上記のページにアクセスして「Download package」を押し、
「microsoft.codeanalysis.bannedapianalyzers.X.X.X.nupkg」をダウンロードしたら
ファイルの拡張子を「.nupkg」から「.zip」に変更してから展開します

f:id:baba_s:20210716143131p:plain

展開したら「analyzers\dotnet\cs」フォルダに格納されている2つの .dll を

f:id:baba_s:20210716151248p:plain

Unity プロジェクトの Editor フォルダに追加します

追加した .dll の設定変更

f:id:baba_s:20210716151631p:plain

追加した2つの .dll を Project ウィンドウで選択して
「Include Platforms」のチェックをすべて外して「Apply」を押します

f:id:baba_s:20210716151639p:plain

そして、2つの .dll を選択したまま Asset Labels のアイコンを押して

f:id:baba_s:20210716151644p:plain

RoslynAnalyzer と入力して Enter を押して

f:id:baba_s:20210716151650p:plain

「RoslynAnalyzer」というラベルを設定します

CsprojModifier の設定

f:id:baba_s:20210716144954p:plain

Project Settings を開いて「Editor > C# Project Modifier」を選択して
「Add Roslyn Analyzer references to .csproj」をオンにします

f:id:baba_s:20210716151819p:plain

そして、Unity プロジェクトに追加した2つの .dll のパスが表示されていれば
正しく設定できています

設定ファイルの追加

f:id:baba_s:20210716152134p:plain

Unity プロジェクト直下に以下の2つの名前のファイルを新規で作成します

  • BannedSymbols.txt
  • BannedSymbols.props
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Analyzer Include="Assets/Editor/Microsoft.CodeAnalysis.BannedApiAnalyzers.dll" />
    <Analyzer Include="Assets/Editor/Microsoft.CodeAnalysis.CSharp.BannedApiAnalyzers.dll" />
  </ItemGroup>
  <ItemGroup>
    <AdditionalFiles Include="$(ProjectDir)\BannedSymbols.txt" />
  </ItemGroup>
</Project>

「BannedSymbols.props」を開いて上記の内容を書き込んで保存します
「BannedSymbols.txt」にはまだ何も書き込まなくて問題ありません

f:id:baba_s:20210716152356p:plain

Unity の Project Settings に戻り、「Additional project imports」の「+」を押して

f:id:baba_s:20210716152402p:plain

「...」を押して

f:id:baba_s:20210716152406p:plain

先ほど新規作成した「BannedSymbols.props」を設定します

特定の関数が使われていたら警告を表示するように設定

f:id:baba_s:20210716153453p:plain

Unity プロジェクトに適当な C# スクリプトを追加して Visual Studio で開きます

using UnityEngine;

public class Example : MonoBehaviour
{
    private void Awake()
    {
        Debug.Log( "ピカチュウ" );
    }
}

そして、Debug.Log を呼び出すだけの上記のコードを貼り付けます

f:id:baba_s:20210716153654p:plain

この状態で、「BannedSymbols.txt」を開いて

M:UnityEngine.Debug.Log(System.Object);Debug.Log は使用しないでください

このように書き込んで保存します

f:id:baba_s:20210716153949p:plain

すると、Debug.Log を呼び出している箇所に警告線が表示されるようになり

f:id:baba_s:20210716153957p:plain

カーソルを合わせると
「Debug.Log は使用しないでください」と表示されていることが確認できます

このように、CsprojModifier と BannedApiAnalyzers を使用することで
特定の関数が使われていたら警告線を表示できるようになります

設定例

重たい Unity の API を使用したら警告線表示

M:UnityEngine.Component.SendMessage(System.String);重たい処理なので使用しないでください
M:UnityEngine.Component.SendMessage(System.String,System.Object);重たい処理なので使用しないでください
M:UnityEngine.Component.SendMessage(System.String,System.Object,UnityEngine.SendMessageOptions);重たい処理なので使用しないでください
M:UnityEngine.Component.SendMessage(System.String,UnityEngine.SendMessageOptions);重たい処理なので使用しないでください
M:UnityEngine.GameObject.SendMessage(System.String);重たい処理なので使用しないでください
M:UnityEngine.GameObject.SendMessage(System.String,System.Object);重たい処理なので使用しないでください
M:UnityEngine.GameObject.SendMessage(System.String,System.Object,UnityEngine.SendMessageOptions);重たい処理なので使用しないでください
M:UnityEngine.GameObject.SendMessage(System.String,UnityEngine.SendMessageOptions);重たい処理なので使用しないでください
M:UnityEngine.GameObject.Find(System.String);重たい処理なので使用しないでください
M:UnityEngine.Object.FindObjectOfType``1();重たい処理なので使用しないでください
M:UnityEngine.Object.FindObjectOfType``1(System.Boolean);重たい処理なので使用しないでください
M:UnityEngine.Object.FindObjectOfType(System.Type);重たい処理なので使用しないでください
M:UnityEngine.Object.FindObjectOfType(System.Type,System.Boolean);重たい処理なので使用しないでください
M:UnityEngine.Object.FindObjectsOfType``1();重たい処理なので使用しないでください
M:UnityEngine.Object.FindObjectsOfType``1(System.Boolean);重たい処理なので使用しないでください
M:UnityEngine.Object.FindObjectsOfType(System.Type);重たい処理なので使用しないでください
M:UnityEngine.Object.FindObjectsOfType(System.Type,System.Boolean);重たい処理なので使用しないでください

「BannedSymbols.txt」に上記のように書き込んで保存すると

f:id:baba_s:20210716162541p:plain

重たい Unity の API が使用されたら警告線が表示されるようになります
プロジェクトではこれらの API を使ってほしくない時に活用できます

Debug.Log 系を使用したら警告線表示

M:UnityEngine.Debug.Log(System.Object);Debug.Log は使用しないでください
M:UnityEngine.Debug.Log(System.Object,UnityEngine.Object);Debug.Log は使用しないでください
M:UnityEngine.Debug.LogWarning(System.Object);Debug.LogWarning は使用しないでください
M:UnityEngine.Debug.LogWarning(System.Object,UnityEngine.Object);Debug.LogWarning は使用しないでください
M:UnityEngine.Debug.LogError(System.Object);Debug.LogError は使用しないでください
M:UnityEngine.Debug.LogError(System.Object,UnityEngine.Object);Debug.LogError は使用しないでください
M:UnityEngine.Debug.LogFormat(UnityEngine.Object,System.String,System.Object[]);Debug.LogFormat は使用しないでください
M:UnityEngine.Debug.LogFormat(System.String,System.Object[]);Debug.LogFormat は使用しないでください
M:UnityEngine.Debug.LogWarningFormat(UnityEngine.Object,System.String,System.Object[]);Debug.LogWarningFormat は使用しないでください
M:UnityEngine.Debug.LogWarningFormat(System.String,System.Object[]);Debug.LogWarningFormat は使用しないでください
M:UnityEngine.Debug.LogErrorFormat(UnityEngine.Object,System.String,System.Object[]);Debug.LogErrorFormat は使用しないでください
M:UnityEngine.Debug.LogErrorFormat(System.String,System.Object[]);Debug.LogErrorFormat は使用しないでください

「BannedSymbols.txt」に上記のように書き込んで保存すると

f:id:baba_s:20210716155058p:plain

Debug.Log 系の関数を使用したら警告線が表示されるようになります

例えばプロジェクトでは専用のログ出力関数を使用する必要があり、
通常の Debug.Log 系の関数は使ってほしくない時に活用できます

Enum クラスの関数を使用したら警告線表示

M:System.Enum.GetValues(System.Type);Enum.GetValues の代わりに FastEnum.GetValues を使用してください
M:System.Enum.GetNames(System.Type);Enum.GetNames の代わりに FastEnum.GetNames を使用してください
M:System.Enum.TryParse``1(System.String,System.Boolean,``0@);Enum.TryParse の代わりに FastEnum.TryParse を使用してください
M:System.Enum.TryParse``1(System.String,``0@);Enum.TryParse の代わりに FastEnum.TryParse を使用してください
M:System.Enum.Parse(System.Type,System.String);Enum.Parse の代わりに FastEnum.Parse を使用してください
M:System.Enum.Parse(System.Type,System.String,System.Boolean);Enum.Parse の代わりに FastEnum.Parse を使用してください

「BannedSymbols.txt」に上記のように書き込んで保存すると

f:id:baba_s:20210716155956p:plain

Enum クラスの関数を使用したら警告線が表示されるようになります

例えば Enum クラスは遅いので
プロジェクトでは FastEnum を使用してほしい時に活用できます

ジェネリックではない GetComponent を使用したら警告線表示

M:UnityEngine.Component.GetComponent(System.Type);ジェネリックメソッド版を使用してください
M:UnityEngine.Component.GetComponent(System.String);ジェネリックメソッド版を使用してください
M:UnityEngine.Component.GetComponentInChildren(System.Type);ジェネリックメソッド版を使用してください
M:UnityEngine.Component.GetComponentInChildren(System.Type,System.Boolean);ジェネリックメソッド版を使用してください
M:UnityEngine.Component.GetComponentInParent(System.Type);ジェネリックメソッド版を使用してください
M:UnityEngine.Component.GetComponents(System.Type);ジェネリックメソッド版を使用してください
M:UnityEngine.Component.GetComponents(System.Type,System.Collections.Generic.List{UnityEngine.Component});ジェネリックメソッド版を使用してください
M:UnityEngine.Component.GetComponentsInChildren(System.Type);ジェネリックメソッド版を使用してください
M:UnityEngine.Component.GetComponentsInChildren(System.Type,System.Boolean);ジェネリックメソッド版を使用してください
M:UnityEngine.Component.GetComponentsInParent(System.Type);ジェネリックメソッド版を使用してください
M:UnityEngine.Component.GetComponentsInParent(System.Type,System.Boolean);ジェネリックメソッド版を使用してください
M:UnityEngine.Component.TryGetComponent(System.Type,UnityEngine.Component@);ジェネリックメソッド版を使用してください

「BannedSymbols.txt」に上記のように書き込んで保存すると

f:id:baba_s:20210716161555p:plain

System.Type を引数に受け取る GetComponent 系の関数を使用したら
警告線が表示されるようになります

基本的にジェネリック版の GetComponent 系の関数を使用してほしい時に活用できます

参考サイト様