用于Unity的REPL工具:
- 支持在编辑器内使用
- 支持在IL2CPP打包版本中使用(需要集成HybridCLR)
- 支持直接访问非公有的类、方法、属性、字段,不需要使用反射
如果想了解实现细节,可以看这篇博客
- 执行src\GShell\publish_win64.bat
- 用Unity打开demo工程
- 打开场景:Scenes\main.unity
- 进入Play Mode
- 在Unity中打开Shell Launcher:MODX -> Shell Launcher,配置选择EditorShellSettings
- 点击“启动”
- 执行src\GShell\publish_win64.bat
- 用Unity打开demo工程
- 安装HybridCLR:HybridCLR -> Installer
- 构建Player:Build -> Win64
- 运行Player:demo\Release-Win64\HybridCLRTrial.exe
- 在Unity中打开Shell Launcher:MODX -> Shell Launcher,配置选择PlayerShellSettings
- 点击“启动”
> 1+2 // 执行表达式,输出值
3
> var x = 2 + 3; // 定义变量
> x // 输出之前定义的变量的值
5
> int Add(int a, int b) // 定义函数,支持多行输入
* {
* return a + b;
* }
> Add(3, 1) // 调用前面定义的函数
4
> Entry.Run_AOTGeneric(); // 调用HotUpdate.dll中的方法,但dll没有引用
(1,1): error CS0103: The name 'Entry' does not exist in the current context
> #r "HotUpdate.dll" // 引用HotUpdate.dll(推荐在配置中填上常用的dll,避免每次启动都需要手动引用)
> Entry.Run_AOTGeneric(); // Run_AOTGeneric是私有方法,可以直接调用
> using UnityEngine.SceneManagement; // 导入命名空间
> SceneManager.GetActiveScene().name // 访问先前导入的命名空间中的类型
main
> var transform = GameObject.Find("LoadDll").transform;
> transform.localPosition = Vector3.zero; // 修改属性
> var list = new List<int>() { 1, 2, 3 }; // 创建List
> var s = "";
> foreach (var item in list) // 循环语句,支持多行输入
* s += item + ",";
> s
1,2,3,
> #load "test.cs" // 加载当前目录(demo)下的test.cs文件,并执行其中的代码
> #reset // 重置状态
> s // 之前声明的变量不存在了
(1,1): error CS0103: The name 's' does not exist in the current context
demo工程的配置在Assets\Editor\*ShellSettings.asset
- 编译程序集的配置
- 用于生成一份指定平台的dll,供GShell编译动态代码时引用
- 在编辑器中使用时,需要将Build Target设置为
No Target
- 编译动态代码的配置
- Search Paths:搜索引用的dll的路径列表,越前面的目录优先级越高
- 在编辑器中使用时,需要添加Library\ScriptAssemblies
- 工具会自动在最前面添加编译程序集的输出目录
- 工具会自动在最后面添加mscorlib.dll、UnityEngine.CoreModule.dll所在的目录
- References:编译动态代码时引用的dll,下面是一些常用的dll:
- mscorlib.dll
- System.Core.dll
- UnityEngine.CoreModule.dll
- Usings:编译动态代码时自动导入的命名空间,下面是一些常用的命名空间:
- System
- System.Collections.Generic
- System.Linq
- UnityEngine
- Script Class Name:编译动态代码时,自动创建的类型名,一般不需要修改
- Search Paths:搜索引用的dll的路径列表,越前面的目录优先级越高
- Runtime:编辑器中使用选择Mono,IL2CPP打包版本中使用选择IL2CPP
- Tool Path:GShell的可执行的文件的路径
- Execute URL:GShell编译代码后,将发送给这个URL执行
- Extra Datas:GShell发送给Execute URL的额外数据。比如可以添加玩家ID,让游戏服务器通过它将GShell请求转发给指定的客户端执行
工具使用HTTP协议和外部通信。项目可以在服务端接收GShell发送的数据,将其转发给指定的客户端执行。客户端执行之后,通过游戏服务器转发回GShell
demo工程中提供了集成的示例,代码在 demo\Assets\HotUpdate\TestShell.cs
GShell中的每个输入(比如一个表达式、一条语句或者一个函数定义)都会编译为一个单独的dll,而HybridCLR支持加载最多338个dll(文档)
- 使用经过裁剪的mscorlib.dll(比如在使用HybridCLR DHE的项目中,用快照dll的目录作为搜索路径)时,可能因为代码裁剪,导致动态代码无法编译:
> 1+2
(1,1): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AwaitOnCompleted'
这种情况需要在项目的Assets目录(或者其子目录)添加link.xml,重新打包,并将新生成的dll的所在目录设置为搜索路径:
<?xml version="1.0" encoding="utf-8"?>
<linker>
<assembly fullname="mscorlib">
<type fullname="System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1" preserve="all" />
</assembly>
</linker>
- 在Unity 2022中使用默认的mscorlib.dll(在Unity的安装目录内)时,有一些动态代码无法编译:
> using UnityEngine.SceneManagement;
> SceneManager.GetActiveScene().name
(1,14): error CS0012: The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.
(1,1): error CS0012: The type 'ValueType' is defined in an assembly that is not referenced. You must add a reference to assembly 'netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.
这种情况下需要添加引用netstandard.dll