【HarmonyOS Next】Unity(团结引擎)与 HarmonyOS 通信

一、环境

  • Unity Tuanjie V1.2.3
  • DevEco Studio NEXT Developer Beta1 - Build Version: 5.0.3.402

二、官方资料参考

  1. Unity 鸿蒙https://docs.unity.cn/cn/tuanjiemanual/Manual/openharmony.html
  2. C# 调用鸿蒙 ArkTS https://docs.unity.cn/cn/tuanjiemanual/Manual/openharmony-plugins-typescript-code-from-c-sharp.html

三、对接流程

中国团结引擎团队针对纯血鸿蒙的语言层面调用做了很多封装,比如提供了C# 侧 OpenHarmonyJSClass 类映射到 ArkTS 类实例 ,OpenHarmonyJSObject 类映射到 ArkTS 对象实例。
ArkTS 是 Typescript 的超集 。而 Typescript 和 JavaScript 本身没有像 C# 或 Java 那样内置的完整反射机制。

因此,C# 在调用 ArkTS,需要依靠 ArkTS 侧类的自我注册,让 C# 或是 Unity 知道当前C#可以调用哪个类或是对象实例。

首先,声明你的 ArkTS 类并创建其实例,然后注册它。你的插件扩展名应为 .tslib、.ts 或 .ets。请注意,Tuanjie 只将位于 Plugins/OpenHarmony 目录中的 .ts 和 .ets 文件视为插件。注册函数的名称应匹配以下格式:“Register” + 你的插件名称。

C#侧 SDKProxy 代码示例:

using UnityEngine;

public class SDKProxy : MonoBehaviour
{
    private static OpenHarmonyJSClass openHarmony;

    private static readonly System.Lazy<SDKProxy> LazyInstance = new System.Lazy<SDKProxy>(() =>
    {
        // 定义一个gameobejct挂载脚本
        GameObject gameObject = new GameObject("SDKProxy");
        var instance = gameObject.AddComponent<SDKProxy>();
        // 因为我们在 HarmonyOS 那边调用的是类方法,所以这里需要定义 OpenHarmonyJSClass 类对象作为 C# 的调用入口
        openHarmony = new OpenHarmonyJSClass("SDKHMProxy");

        return instance;
    });

    public static SDKProxy GetInstance()
    {
        return LazyInstance.Value;
    }

    public void Init()
    {
        // 做一些环境初始化等工作。。。
        Debug.Log("SDKProxy Init");
    }

    //C# 层的登录
    public static void Login(string account = "", string pwd = "")
    {
        string userInfo = openHarmony.CallStatic<string>("Login", account, pwd);
        Debug.Log("SDKProxy Login result:" + userInfo);
    }

    //处理来自 HarmonyOS 侧 ArkTS 调用的回调处理
    void NativeBridgeCallback(string msg)
    {
        // 这里需要将 msg 字符串通过约定的json格式,解析成对象,再根据 func 即方法名进行处理,或是对 result 字段进行二次模型转换。处理完,继续C#的逻辑。
        Debug.Log("NativeBridgeCallback:" + msg);
    }
}

C# 调用侧代码示例:

using UnityEngine;

public class Main : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("Main Start and SDK init");

        SDKProxy.GetInstance().Init();

        SDKProxy.Login("1111","a123456");
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

ArkTS 侧 SDKHMProxy 代码示例:

import tuanjie from 'libtuanjie.so';

export class SDKHMProxy {
  static Login(account:string, pwd:string){
    console.log("SDKHMProxy account:" + account);
    //调用原生组件处理登录
    //.....

    //在登录成功或是失败的时候,可以异步返回结果 .  推荐是 json 格式
    SendMessageToUnity("{func:'Login',result:'{userId:'100001',userName:'test001'}'}");

    //可以通过直接return ,但这需要考虑主线程、多线程一些问题,以及等待、异步操作等因素
    return "{userId:'100001',userName:'test001'}";
  }
}

// 对发送给Unity团结引擎的接口进行二次封装
export function SendMessageToUnity(content:string){
  tuanjie.TuanjieSendMessage("SDKProxy","NativeBridgeCallback",content);
}

export function RegisterSDKHMProxy() {
  let register:object = new Object();
  register["SDKHMProxy"] = SDKHMProxy;
  return register;
}

如果我们导鸿蒙工程的话,需要注意的时候,我们得检查 TuanjieJSScriptRegister.ets 类,确保他注册了我们 RegisterSDKHMProxy的方法.

posted @ 2024-08-15 17:35  七夜i  阅读(922)  评论(0编辑  收藏  举报