跳到主要内容

C# 调用 JS

TsAppDomain.GetFunction<T> 按模块 specifier 与 named export 取得绑定好的 Delegate,再调用。Editor 与 Player API 相同

Canonical:zts-demo 中的 Bootstrap / AppAdd 样例。

基本用法

TsAppDomain.Initialize(LoadJsModule);

var main = TsAppDomain.GetFunction<Action>("app", "main");
main();

var add = TsAppDomain.GetFunction<Func<int, int, int>>("app", "add");
int sum = add(10, 20); // 30
// JsScripts/app.js — canonical 名:app(不含 .js)
export function main() {
console.log("js main start");
}

export function add(a, b) {
return a + b;
}
规则说明
Initialize否则抛异常
T : MulticastDelegate具体 Action / Func / 自定义委托
jsModule / jsExportName"app","add"export function add
仅 named export自动映射 export default
缓存热路径自行保存;不保证同实例
时机须在 Initialize 之后;勿放在与 RuntimeInitializeOnLoadMethod 同类型的 static 字段初始化器

Delegate 类型 T 决定参数与返回值的 Marshal(见 委托与函数)。

模块加载

GetFunction("app", …) 要求 loader 对 "app" 能返回源码。

环境典型路径
Editor(纯 JS){ProjectRoot}/JsScripts/app.js
Editor(TS)TsProject/out/app.js(canonical 仍是 "app"
PlayerStreamingAssets/Js/app.jsStreamingAssets/ZTS/app.js
private static object LoadJsModule(string module)
{
#if UNITY_EDITOR
string path = Path.Combine(Application.dataPath, "..", "JsScripts", module + ".js");
#else
string path = Path.Combine(Application.streamingAssetsPath, "Js", module + ".js");
#endif
return File.Exists(path) ? File.ReadAllText(path, Encoding.UTF8) : null;
}

要点:

  • canonical 不含 .js / .tsGetFunction("game/logic", "OnTick"),不是 "game/logic.js"
  • 进入 loader 前,相对导入带来的 .js 尾缀会被规范掉;磁盘文件可以是 out/game/logic.js
  • 子路径用 POSIX 风格:"game/logic"…/game/logic.js
  • csharp: 不是业务入口:其 named export 是类型对象;误用 GetFunction 会因「非 callable」抛 C# 异常
  • Player 构建前须 Sync / 拷贝 emit 产物,见 构建
  • 热更用 TsAppDomain.Reset(loader)(EndOfFrame 生效;旧 GetFunction 委托作废,须重新绑定)。已初始化时再次 Initialize 会抛异常,不能「只换 loader」

多模块

var appMain = TsAppDomain.GetFunction<Action>("app", "main");
var onTick = TsAppDomain.GetFunction<Action<float>>("game/logic", "OnTick");
// game/logic.js
export function OnTick(dt) {
// ...
}

与「形参里的 function」对照

场景做法
C# 主动调某个 JS 导出函数GetFunction<T>(module, exportName)
C# 形参是 Action/Func,JS 传入 function隐式 marshal,见 委托与函数
Event 订阅JS 侧 add_ / remove_,见 JS 调用 C#

常见错误

现象处理
module not found / loader 失败Editor/Player 路径;是否 Sync;canonical 是否带了 .js
export 不是 callable导出名拼写;是否只有 export default
GetFunction 结果无效 / 调用无效果未 Initialize;T 签名与 JS 不一致
旧脚本仍在跑Player 未重新 Sync / 未重新 emit
Reset 后委托异常重新 GetFunction,丢弃缓存字段
再次 Initialize 抛异常改用 Reset(loader)

学习路径

上一篇JS 调用 C#
下一篇TypeScript 工作流

相关文档