您的位置:首页 > 移动开发 > Unity3D

Unity 使用 Unity 直接编译外部 DLL

2017-10-30 19:06 1326 查看

原因

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(2, 3);

        print("2 + 3 = " + utils.c);

    }

    void Update()

    {

        print(MyUtilities.GenerateRandom(0, 100));

    }

}
挂载到场景物体上,运行显示如下:



证明可以调用正确。


测试错误

接下去测试外部 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文件。



测试工程

工程地址:https://coding.net/u/wuhuan/p/UnityCompileDLL/git
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: