目录
一、动态语言
二、创建C#dll
1.VS中创建一个C#语言的库工程
2.添加UnityEngine.dll的依赖
3.编写代码,生成dll
三、Unity使用dll
一、动态语言
计算机编程语言可以根据它们如何将源代码转换为可以执行的代码来分类为静态语言和动态语言。
- 静态语言(也称为编译型语言)通常需要在程序运行之前将源代码编译成机器码。这个过程是通过编译器完成的,编译器会检查源代码中的错误并将其转换成目标平台的机器码。静态语言的例子包括C、C++、Rust和Go等。静态语言的优势在于它们通常能够生成更高效的机器码,因此它们的执行速度往往更快。另外,由于编译时会进行类型检查,因此它们在类型安全方面也更为严格。
- 动态语言(也称为解释型语言或者脚本)不需要预先编译。它们在程序执行时由解释器逐行读取源代码,然后转换成可以执行的操作。这种语言的例子包括Lua、Python、JavaScript和PHP等。动态语言的优势在于它们的灵活性和开发速度,因为开发者可以快速编写和测试代码,而不需要长时间的编译过程。但这种灵活性可能会以性能为代价,因为解释执行通常比直接执行编译后的代码要慢。
- 值得注意的是,有些语言如Java和C#,它们通常被认为是静态类型语言,但它们采用了一种中间方式。这些语言的代码首先被编译成中间语言(比如Java的字节码),然后在运行时通过虚拟机(如JVM和CLR)解释执行或即时编译(JIT编译)成机器码。这种方式结合了编译型语言的一些优势和解释型语言的某些便利。
使用动态语言的最大优势是不需要重新编译即可实现对程序的修改。Unity的底层是使用的C++语言,应用层面主要是使用的C#,使用C#的反射功能一定程度上可以实现对发布后的程序进行修改,但其使用并不容易,而且受到很多限制,比如苹果App就对反射功能有诸多限制,因此如果对游戏内容进行了改动,使用C#还是要重新编译整个程序。所以热更新使用的比较多的技术是Lua语言。
使用Lua主要包括两部分,一部分是在Lua的宿主语言中创建接口读取、执行Lua脚本;另一部分是在宿主语言中编写接口供Lua脚本调用。(下一篇记录)
Lua 的动态类型系统意味着变量不需要在编译时声明其类型;类型会在运行时根据赋予变量的值自动确定。这提供了极大的灵活性,使得编写和修改代码变得更加快捷。同时,Lua 的解释器可以直接执行源代码,或者将源代码预编译为字节码,以提高执行效率。
二、创建C#dll
在Unity或C#程序中,可以动态调用编译好的程序集(也就是.dll文件),这样在程序发布后,只需要更新.dll文件,即可实现对程序内容的更新,而不用重新编译整个程序。之前已经实现了Unity调用C++封装的dll。本文记录C#封装dll(超级简单)。
1.VS中创建一个C#语言的库工程
注意版本选择的是.Net Framework3.5。
2.添加UnityEngine.dll的依赖
然后在工程中选择【Dependencies】→【Add Reference】,引用Unity安装目录下Editor/Data/Managed中的UnityEngine.dll。
3.编写代码,生成dll
因为引用了UnityEngine.dll,所以可以在代码中引用Unity引擎的功能。
using UnityEngine;
namespace ClassLibrary1CanDelete
{
public class MyPlugin:MonoBehaviour
{
void Start() {
Debug.Log("This is my c# plugin");
}
}
}
编译工程,生成***.dll文件。
三、Unity使用dll
将***.dll复制到Unity工程的Plugins目录内。
- MyPlugin可作为组件直接拖到物体身上。
- 也可用代码添加MyPlugin组件
this.AddComponent<ClassLibrary1CanDelete.MyPlugin>();
在Unity中做热更新,通常会将需要更新的内容放到Unity的StreamingAssets(PC端可读写,移动端只读)路径下,如果将***.dll文件放到StreamingAssets路径下,则必须使用文件读取的方式读取.dll文件,然后通过反射执行.dll文件提供的功能。
void AddDll()
{
//this.AddComponent<ClassLibrary1CanDelete.MyPlugin>();
byte[] bytes = System.IO.File.ReadAllBytes(System.IO.Path.Combine(Application.streamingAssetsPath, "ClassLibrary1CanDelete.dll"));
Assembly assembly = Assembly.Load(bytes);
System.Type type = assembly.GetType("ClassLibrary1CanDelete.MyPlugin");
this.gameObject.AddComponent(type);
}
在Unity中实现热更新主要是通过网络下载需要更新的文件,并保存到Unity API中Aplication.dataPath指向的路径(一个可写的路径)。程序首先访问Application.dataPath指向的路径,如果目标文件不存在,便进行网络下载,如果服务器端不存在更新的文件,最后再到StreamingAssets读取默认的文件。