• Unity Render Streaming通过Js与Unity自定义通讯


    Unity Render Streaming通过Js与Unity自定义通讯


    Js通讯发送示例在WebApp\client\public\videoplayer;
    对应C#接收端案例Unity Render Streaming插件的WebBrowserInput

    JS发送部分

    videoplayer/js/main.js按钮通讯示例

        const elementBlueButton = document.createElement('button');
        elementBlueButton.id = "blueButton";
        elementBlueButton.innerHTML = "Light on";
        playerDiv.appendChild(elementBlueButton);
        elementBlueButton.addEventListener("click", function () {
          sendClickEvent(videoPlayer, 1);
        });
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    案例只能发送一个按钮Number ID
    往上溯源,在js/register-events.js文件中的sendClickEvent函数

    export function sendClickEvent(videoPlayer, elementId) {
      let data = new DataView(new ArrayBuffer(3));
      data.setUint8(0, InputEvent.ButtonClick);
      data.setInt16(1, elementId, true);
      videoPlayer && videoPlayer.sendMsg(data.buffer);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    核心代码

    videoPlayer.sendMsg(data.buffer); // 这是一个二进制数组发送函数,理论上可以发送任意数据。
    
    • 1
    data.setUint8(0, InputEvent.ButtonClick); // 二进制数组的第一个字段是1个字节的类型标记
    data.setInt16(1, elementId, true); // 第一个字节之后的数据由标签类型定义不同而解释不同,这里转为2字节的short类型,代表按钮id
    
    • 1
    • 2

    查看案例已经定义的所有通讯类型

    const InputEvent = {
      Keyboard: 0,
      Mouse: 1,
      MouseWheel: 2,
      Touch: 3,
      ButtonClick: 4,
      Gamepad: 5,// 案例定义了0-5标记,分别对应鼠标键盘游戏手柄,和按钮通讯
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    我们新增加一个发送字符串的通讯类型,定义标签为 6

      function sendMessage(videoPlayer, message) {
        function utf8FromStr(str) {
          var strUtf8 = unescape(encodeURIComponent(str)); // UTF8编码文本到二进制
          var arr = new Uint8Array(strUtf8.length);
          for (var i = 0; i < strUtf8.length; ++i) {
            arr[i] = strUtf8.charCodeAt(i);
          }
          return arr;
        }
        message = " " + message; // 预留空格作为第一个字节,存放类型标签6
        var buf = utf8FromStr(message);
        let data = new DataView(buf.buffer);
        data.setUint8(0, 6); // 自定义标签6顶替掉第一个预留的空格字符
    
        videoPlayer && videoPlayer.sendMsg(data.buffer); // 发送二进制数据串
      }
      function sendJson(videoPlayer, json) { // 也可以发送自定义Json格式化文本数据
        sendMessage(videoPlayer, JSON.stringify(json));
      }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    C#接收部分

    Unity Streaming Render示例的WebBrowserInputChannelReceiver是接收webRtc数据通讯的通道(channel),继承自InputChannelReceiverBase类。WebBrowserInputChannelReceiver通过消息注册获取标签类型为4的ButtonClick事件
    我们的目标是自定义字符串(JSON)通讯,默认基类不会处理自定义类型。
    从派生一个新类,直接继承OnMessage接收二进制数据流函数,OnMessage收到的字节流就是JS中sendMsg发送的二进制原始数据
    代码如下:

      public class DBBrowserInputChannelReceiver : WebBrowserInputChannelReceiver
      {
        public GameObject[] targets;
        protected override void OnMessage(byte[] bytes)
        {
          if (bytes.Length > 0)
          {
            int code = bytes[0]; // 第一个字节为通讯类型标记
            if (code == 6) // 我们自定义的字符串通讯类型标记
            {
              string message = System.Text.UTF8Encoding.UTF8.GetString(bytes, 1, bytes.Length - 1); // 去掉数据流第一个标记字节,剩余字节通过UTF8编码转化回字符串,对应JS的UTF8编码函数unescape(encodeURIComponent(str))
              foreach (GameObject go in targets)
              {
                go.SendMessage("OnNetMessage", message); // 将数据通过Unity的SendMessage发送给处理节点
              }
              if (code <= 5)
              {
                base.OnMessage(bytes); // 通过基类处理默认类型消息
              }
            }
          }
        }
      }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 相关阅读:
    酷开系统更多惊喜,尽享畅快观影之旅
    spark性能调优 | 内存优化
    Java-Scanner用法
    [附源码]计算机毕业设计Springboot电影推荐网站
    springboot基于Java的电影院售票与管理系统毕业设计源码011449
    超强的纯 CSS 鼠标点击拖拽效果
    冥想第五百五十七天
    图解字符串匹配算法:从Brute-Force到KMP,一下子就整明白了
    R语言时间序列数据可视化: 使用plot函数可视化单序列时间序列数据、多序列时间序列数据并指定不同时间序列的线条类型(lty)
    深度学习-nlp系列(3)文本分类(Bert+TextCNN)pytorch
  • 原文地址:https://blog.csdn.net/qq_31042143/article/details/125551233