Unity 使用 Unity 直接编译外部 DLL

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/akof1314/article/details/78396130

原因

Unity 集成了 Mono 编译器,所以在 Unity 里面新建 C# 脚本的时候,会自动进行编译。那么,思考可以不可以借助 Unity 的编译接口,来编译外部 DLL 文件。查找 Unity 编辑器的接口,发现有个 API:  
 C# Code 
1
2
3
4
     public  static  string[] CompileCSharp( string[] sources,  string[] references,  string[] defines,  string outputFile)
    {
       return MonoCSharpCompiler.Compile(sources, references, defines, outputFile);
    }
那么,来测试下这个接口。

测试准备

新建两个文件夹,一个放 Unity 测试工程,一个放外部 DLL 的源码文件,如下所示:

其中,C# 文件 MyUtilities.cs 代码如下:
 C# Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System;

namespace DLLTest {

     public  class MyUtilities {
    
         public  int c;

         public  void AddValues( int a,  int b) {
            c = a + b;  
        }
    
         public  static  int GenerateRandom( int min,  int max) {
            System.Random rand =  new System.Random();
             return rand.Next(min, max);
        }
    }
}
编辑器脚本文件  MyCompile.cs 代码如下:
 C# Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System.IO;
using UnityEditor;
using UnityEngine;

public  class MyCompile
{
    [MenuItem( "Tool/My Compile")]
     private  static  void DoMyCompile()
    {
         string srcPath = Path.Combine(Application.dataPath,  "../../TestDLL");
         string[] sources =  new[] {Path.Combine(srcPath,  "MyUtilities.cs")};
         string[] references =  new  string[ 0];
         string[] defines =  new  string[ 0];
         string outputFile = Path.Combine(Application.dataPath,  "TestDLL.dll");

         string[] msgs = EditorUtility.CompileCSharp(sources, references, defines, outputFile);
         foreach (var msg  in msgs)
        {
            Debug.Log(msg);
        }

         string dllFile =  "Assets/TestDLL.dll";
         if (File.Exists(dllFile))
        {
            AssetDatabase.ImportAsset(dllFile, ImportAssetOptions.ForceUpdate);
        }
    }
}
测试运行
点击菜单栏 "Tool/My Compile",等待执行完毕,可以看到如下:

可以看到已经生成了 DLL,并且其对应的 mdb 文件,也自动生成了。

新建个 Unity 脚本文件,来测试是否调用正常,代码如下:
 C# Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using UnityEngine;
using DLLTest;

public  class Test : MonoBehaviour
{
     void Start()
    {
        MyUtilities utils =  new MyUtilities();
        utils.AddValues( 23);
        print( "2 + 3 = " + utils.c);
    }

     void Update()
    {
        print(MyUtilities.GenerateRandom( 0100));
    }
}
挂载到场景物体上,运行显示如下:

证明可以调用正确。

测试错误

接下去测试外部 DLL 源码错误的情况下,会不会报告所在的错误。更改 MyUtilities.cs 里的 AddValues 方法,让其参数变量错误,更改为如下:
 C# Code 
1
2
3
         public  void AddValues( int d,  int b) {
            c = a + b;  
        }
再次运行编译,可以看到报告了如下错误:

更改回去,继续下面的测试。

测试自定义脚本

在外部创建脚本文件 MyBehaviour.cs,代码如下:
 C# Code 
1
2
3
4
5
6
7
8
9
10
11
12
using UnityEngine;

namespace DLLTest 
{
     public  class MyBehaviour : MonoBehaviour
    {
         void Start()
        {
            Debug.Log( "MyBehaviour");
        }
    }
}
编译脚本里,将这个文件也加入编译,代码更改为:
 C# Code 
1
string[] sources =  new[] {Path.Combine(srcPath,  "MyUtilities.cs"), Path.Combine(srcPath,  "MyBehaviour.cs") };
运行编译,可以看到报告缺少引用,如下所示:

那么将引用到的 DLL 文件路径也加入进去,更改编译脚本的代码,更改为:
 C# Code 
1
string[] references =  new []{ Path.Combine(EditorApplication.applicationContentsPath,  "Managed/UnityEngine.dll") };
再次运行编译,可以看到不再报错,挂载 MyBehaviour 脚本到物体上,运行,可以看到日志输出如下:

测试 Mac平台

可以看到在 Mac 平台也是支持编译外部 DLL,并且也会自动生成 mdb文件。

测试工程


猜你喜欢

转载自blog.csdn.net/akof1314/article/details/78396130