Puerts项目教程:在C中调用JavaScript的完整指南

Puerts项目教程:在C#中调用JavaScript的完整指南

puerts PUER(普洱) Typescript. Let's write your game in UE or Unity with TypeScript. puerts 项目地址: https://gitcode.com/gh_mirrors/pu/puerts

前言

在现代游戏开发中,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模块系统,这将在后续教程中详细介绍。

最佳实践与注意事项

  1. 性能考虑:频繁的C#-JS互调会有性能开销,应尽量减少跨语言调用
  2. 类型安全:注意参数和返回值的类型匹配,避免运行时错误
  3. 内存管理:及时清理不再使用的委托引用,防止内存泄漏
  4. 调试技巧:利用console.log进行调试,可以输出到Unity控制台

结语

通过Puerts,C#和JavaScript的互操作变得简单而强大。无论是简单的函数调用还是复杂的游戏逻辑实现,Puerts都提供了完善的解决方案。掌握这些技术后,开发者可以更灵活地选择最适合当前任务的编程语言,充分发挥两种语言的优势。

puerts PUER(普洱) Typescript. Let's write your game in UE or Unity with TypeScript. puerts 项目地址: https://gitcode.com/gh_mirrors/pu/puerts

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姬忆慈Loveable

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值