Puerts项目教程:在C#中调用JavaScript的完整指南
前言
在现代游戏开发中,C#和JavaScript的结合使用变得越来越普遍。Puerts作为一个强大的桥梁,让这两种语言能够无缝协作。本文将深入探讨如何在C#中调用JavaScript代码,帮助开发者更好地利用这两种语言的优势。
基础概念:委托(Delegate)机制
Puerts最核心的功能之一就是将JavaScript函数转换为C#委托。这种转换使得从C#端调用JavaScript成为可能。
基本使用示例
public class TestClass
{
Callback1 callback1;
public delegate void Callback1(string str);
public void AddEventCallback1(Callback1 callback1)
{
this.callback1 += callback1;
}
public void Trigger()
{
if (callback1 != null)
{
callback1("test");
}
}
}
void Start() {
Puerts.JsEnv env = new Puerts.JsEnv();
env.Eval(@"
const obj = new CS.TestClass();
obj.AddEventCallback1(i => console.log(i));
obj.Trigger();
");
}
在这个例子中,我们创建了一个C#类TestClass
,它包含一个委托类型的回调。通过Puerts,我们可以在JavaScript中实例化这个类,并将一个JavaScript函数赋值给回调。当C#端触发这个回调时,实际上执行的是JavaScript代码。
参数传递:从C#到JavaScript
Puerts不仅支持无参数的函数调用,还能处理带参数的委托。参数传递时的类型转换规则与从C#返回变量到JavaScript时的规则一致。
参数传递示例
void Start() {
Puerts.JsEnv env = new Puerts.JsEnv();
System.Action<int> LogInt = env.Eval<System.Action<int>>(@"
const func = function(a) {
console.log(a);
}
func;
");
LogInt(3); // 控制台输出3
}
重要提示:如果生成的委托包含值类型参数,需要添加UsingAction或UsingFunc声明。具体细节可以参考相关FAQ。
返回值处理:从JavaScript获取结果
与参数传递类似,我们也可以获取JavaScript函数的返回值。只需将Action委托改为Func委托即可。
返回值处理示例
void Start() {
Puerts.JsEnv env = new Puerts.JsEnv();
System.Func<int, int> Add3 = env.Eval<System.Func<int, int>>(@"
const func = function(a) {
return 3 + a;
}
func;
");
System.Console.WriteLine(Add3(1)); // 输出4
}
同样需要注意值类型参数的问题,确保添加了必要的声明。
高级应用:在JavaScript中实现MonoBehaviour
结合上述功能,我们可以在JavaScript中实现MonoBehaviour的功能,这为游戏开发带来了极大的灵活性。
实现方案
using System;
using Puerts;
using UnityEngine;
public class JsBehaviour : MonoBehaviour
{
public Action JsStart;
public Action JsUpdate;
public Action JsOnDestroy;
static JsEnv jsEnv;
void Awake()
{
if (jsEnv == null) jsEnv = new JsEnv(new DefaultLoader(), 9229);
var init = jsEnv.Eval<ModuleInit>(@"const m =
class Rotate {
constructor(bindTo) {
this.bindTo = bindTo;
this.bindTo.JsUpdate = () => this.onUpdate();
this.bindTo.JsOnDestroy = () => this.onDestroy();
}
onUpdate() {
console.log('update...')
}
onDestroy() {
console.log('onDestroy...');
}
}
(function(bindTo) {
new Rotate(bindTo);
})
");
if (init != null) init(this);
}
void Start()
{
if (JsStart != null) JsStart();
}
void Update()
{
jsEnv.Tick();
if (JsUpdate != null) JsUpdate();
}
void OnDestroy()
{
if (JsOnDestroy != null) JsOnDestroy();
JsStart = null;
JsUpdate = null;
JsOnDestroy = null;
}
}
这个实现展示了如何将Unity的生命周期方法委托给JavaScript处理。社区中已有许多开发者基于这个思路实现了更完善的方案,开发者可以根据需求选择合适的实现。
模块化开发
随着代码量的增长或需要将代码导入他人项目时,模块化变得至关重要。Puerts支持JavaScript模块系统,这将在后续教程中详细介绍。
最佳实践与注意事项
- 性能考虑:频繁的C#-JS互调会有性能开销,应尽量减少跨语言调用
- 类型安全:注意参数和返回值的类型匹配,避免运行时错误
- 内存管理:及时清理不再使用的委托引用,防止内存泄漏
- 调试技巧:利用console.log进行调试,可以输出到Unity控制台
结语
通过Puerts,C#和JavaScript的互操作变得简单而强大。无论是简单的函数调用还是复杂的游戏逻辑实现,Puerts都提供了完善的解决方案。掌握这些技术后,开发者可以更灵活地选择最适合当前任务的编程语言,充分发挥两种语言的优势。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考