Unityで書いたソースコードを.NETプロジェクトでRoslynを使って解析する方法です。
Unity 2022.3.28f1
やりたいこと
Roslynを使うとC#のコードの構文解析やセマンティック解析をすることができます。
この方法については、以下の記事にまとめています。
上の記事では簡単なプロジェクトの解析にとどめていますが、本記事では、Unityで書いたソースコードを、.NETプロジェクトで、Roslynを使って分析する方法についてまとめます。
プロジェクトを作る
まず準備として、Rider などで .NETのコンソールアプリケーションプロジェクトを作成し、 NuGetから Microsoft.CodeAnalysis.CSharp パッケージをインストールしておきます。
解析用のコードを書く
次に解析用のコードを書きます。
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; internal class Program { private static void Main(string[] args) { // Unityプロジェクトのパス var unityProjectPath = "/Users/User Name/Your/Project"; var assetPath = Path.Combine(unityProjectPath, "Assets"); // .cs ファイルの収集(プロジェクト内のスクリプトを全て追加) var csFiles = Directory.GetFiles(assetPath, "*.cs", SearchOption.AllDirectories); var syntaxTrees = csFiles.Select(file => { var code = File.ReadAllText(file); return CSharpSyntaxTree.ParseText(code, path: file); }) .ToArray(); // 関連DLLの収集(Unityのバージョンにより異なるかも) var beeDlls = Directory.GetFiles( Path.Combine(unityProjectPath, "Library", "Bee", "artifacts"), "*.dll", SearchOption.AllDirectories); var metadataReferences = beeDlls .Select(path => MetadataReference.CreateFromFile(path)) .ToArray(); // コンパイル作成 var compilation = CSharpCompilation.Create( "UnityAnalysis", syntaxTrees, metadataReferences, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) ); // クラス名とそのベースクラスの表示 foreach (var tree in syntaxTrees) { var semanticModel = compilation.GetSemanticModel(tree); var root = tree.GetRoot(); var classes = root.DescendantNodes().OfType<ClassDeclarationSyntax>(); foreach (var cls in classes) { var symbol = semanticModel.GetDeclaredSymbol(cls); var baseType = symbol?.BaseType?.ToString() ?? "(none)"; Console.WriteLine($"Class: {symbol?.Name}, BaseType: {baseType}"); } } } }
解説はコメントとして記述しました。
Unityプロジェクトのスクリプトファイルを収集してシンタックスツリーを構築する点、また関連するDLLをライブラリフォルダから集める点がポイントです。