赞
踩
腾讯云联络中心SDK:云联络中心 Web-SDK 开发指南-文档中心-腾讯云 (tencent.com)
查看README.md,根据说明设置server下的dev.js里的相关参数。
然后打开电脑终端,cd到项目的路径:
安装依赖
运行
复制http://127.0.0.1:5173/在浏览器里输入,这时候会显示如下画面:
输入电话号码,点击拨打就会把电话打出去。
新建一个Unity工程,在Assets/Plugins/WebGl下创建一个后缀为jslib的文件,记事本打开编写脚本如下:
- mergeInto(LibraryManager.library, {
- ReportReady: function () {
- window.ReportReady()
- },
-
- TellPhone:function(typeName, phone){
- SendPhone(UTF8ToString(typeName), UTF8ToString(phone))
- }
-
- });
- using System.Collections;
- using System.Collections.Generic;
- using System.Runtime.InteropServices;
- using UnityEngine;
- using UnityEngine.UI;
- using TMPro;
-
- public class UIPanel : MonoBehaviour
- {
- [DllImport("__Internal")]
- private static extern string ReportReady();
- [DllImport("__Internal")]
- private static extern string TellPhone(string type,string phone);
- public TextMeshProUGUI text;
- public TMP_InputField inputField;
- void Start()
- {
- ReportReady();//向vue报告脚本初始化完成
- }
- public void OpenPhone()
- {
- TellPhone("tellphone",inputField.text);
- }
- public void receiveMsgFromVue(string token) {
- text.text = token;
- Debug.Log("接受来自vue的消息 == " + token);
- }
- }
放在tccc-demo-vue\src\路径下,如下图所示:
打开index.html:
SendPhone是Unity发送给网页的方法,sendMsgToUnity方法是网页发送个Unity的方法。
index.html完整代码如下:
- <!DOCTYPE html>
- <html lang="en-us">
- <head>
- <meta charset="utf-8">
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <title>Unity WebGL Player | Web731</title>
- <link rel="shortcut icon" href="TemplateData/favicon.ico">
- <link rel="stylesheet" href="TemplateData/style.css">
- </head>
- <body>
- <div id="unity-container" class="unity-desktop">
- <canvas id="unity-canvas" width=1920 height=1080></canvas>
- <div id="unity-loading-bar">
- <div id="unity-logo"></div>
- <div id="unity-progress-bar-empty">
- <div id="unity-progress-bar-full"></div>
- </div>
- </div>
- <div id="unity-warning"> </div>
- <div id="unity-footer">
- <div id="unity-webgl-logo"></div>
- <div id="unity-fullscreen-button"></div>
- <div id="unity-build-title">Web731</div>
- </div>
- </div>
- <script>
- var container = document.querySelector("#unity-container");
- var canvas = document.querySelector("#unity-canvas");
- var loadingBar = document.querySelector("#unity-loading-bar");
- var progressBarFull = document.querySelector("#unity-progress-bar-full");
- var fullscreenButton = document.querySelector("#unity-fullscreen-button");
- var warningBanner = document.querySelector("#unity-warning");
-
- // Shows a temporary message banner/ribbon for a few seconds, or
- // a permanent error message on top of the canvas if type=='error'.
- // If type=='warning', a yellow highlight color is used.
- // Modify or remove this function to customize the visually presented
- // way that non-critical warnings and error messages are presented to the
- // user.
- function unityShowBanner(msg, type) {
- function updateBannerVisibility() {
- warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
- }
- var div = document.createElement('div');
- div.innerHTML = msg;
- warningBanner.appendChild(div);
- if (type == 'error') div.style = 'background: red; padding: 10px;';
- else {
- if (type == 'warning') div.style = 'background: yellow; padding: 10px;';
- setTimeout(function() {
- warningBanner.removeChild(div);
- updateBannerVisibility();
- }, 5000);
- }
- updateBannerVisibility();
- }
-
- var buildUrl = "Build";
- var loaderUrl = buildUrl + "/web0803.loader.js";
- var config = {
- dataUrl: buildUrl + "/web0803.data.unityweb",
- frameworkUrl: buildUrl + "/web0803.framework.js.unityweb",
- codeUrl: buildUrl + "/web0803.wasm.unityweb",
- streamingAssetsUrl: "StreamingAssets",
- companyName: "DefaultCompany",
- productName: "Web731",
- productVersion: "0.1",
- showBanner: unityShowBanner,
- };
-
- // By default Unity keeps WebGL canvas render target size matched with
- // the DOM size of the canvas element (scaled by window.devicePixelRatio)
- // Set this to false if you want to decouple this synchronization from
- // happening inside the engine, and you would instead like to size up
- // the canvas DOM size and WebGL render target sizes yourself.
- // config.matchWebGLToCanvasSize = false;
-
- if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
- container.className = "unity-mobile";
- // Avoid draining fillrate performance on mobile devices,
- // and default/override low DPI mode on mobile browsers.
- config.devicePixelRatio = 1;
- unityShowBanner('WebGL builds are not supported on mobile devices.');
- } else {
- canvas.style.width = "1920px";
- canvas.style.height = "1080px";
- }
- loadingBar.style.display = "block";
-
- var script = document.createElement("script");
- script.src = loaderUrl;
- script.onload = () => {
- createUnityInstance(canvas, config, (progress) => {
- progressBarFull.style.width = 100 * progress + "%";
- }).then((unityInstance) => {
- loadingBar.style.display = "none";
- fullscreenButton.onclick = () => {
- unityInstance.SetFullscreen(1);
- };
- unityInstanceV = unityInstance;
- }).catch((message) => {
- alert(message);
- });
- };
- document.body.appendChild(script);
-
- var unityInstanceV;
- function ReportReady() {
- window.parent.postMessage({guid:"",event:"ReportReady"}, "*");
- }
- function SendPhone(_type,_phone)
- {
- // alert(s);
- if (_type == "tellphone"){
- window.parent.postMessage({guid:"",event:_type,phone:_phone}, "*");
- }else {
- window.parent.postMessage({guid:_type,event:"guid"}, "*");
- }
- }
-
- function sendMsgToUnity(obj) {
- unityInstanceV.SendMessage('UIPanel','receiveMsgFromVue',JSON.stringify(obj))
- }
-
- </script>
- </body>
- </html>
增加和Unity交互的方法
把原先显示的界面代码删除掉<div class="container"> </div>
style 部分也删掉
对Vue不熟悉,我的理解是这样的(理解不对请留言指正)
其中
- onMounted(()=>{
- window.addEventListener('message', unityWatch,true)
- })
是事件,对Unity发送来的消息进行监听。
- function vueSendToUnity(){
- console.log(statusMap[status.value])
- unityIframe.value.contentWindow.sendMsgToUnity({userId:'****',状态:status.value|| '加载中...'})
- }
是vue把消息发送到Unity端。
- <template>
- <div >
- <iframe id="iframe" ref="unityIframe" src="/src/unity/index.html" style="width:100%;height:100vh" frameborder="0" scrolling="auto" />
- </div>
- </template>
是Unity部分进行显示(其中stytle的height:100% 不起作用,有知道的请留言,谢谢,所以我改为了height:100vh)。
Container.vue修改后代码如下:
- <script setup>
- import { ref, onMounted } from 'vue'
- const wechatGroupImg = 'https://tccc.qcloud.com/assets/wechatGroup.png';
- const arrowImg = 'https://tccc.qcloud.com/assets/arrow.png';
-
- const seat = ref('')
- const status = ref('')
- const number = ref('')
- const loading = ref(false)
- const isError = ref(false)
- const errorField = ref('')
-
- const statusMap = {
- offline: '已下线',
- disconnect: '网络断开,重连中',
- free: '空闲中',
- busy: '忙碌中',
- rest: '小休中',
- countdown: '话后倒计时',
- arrange: '话后整理中',
- notReady: '示忙中',
- }
-
- const errorFieldMap = {
- 'InvalidParameterValue.InstanceNotExist': 'sdkAppId',
- 'InvalidParameterValue.AccountNotExist': 'userId',
- 'AuthFailure.SignatureFailure': 'secretKey或secretId',
- 'AuthFailure.SecretIdNotFound': 'secretId',
- };
-
- const injectTCCC = ({ token, sdkAppId, userId, sdkUrl }) => {
- const scriptDom = document.createElement('script')
- scriptDom.setAttribute('crossorigin', 'anonymous')
- scriptDom.dataset.token = token
- scriptDom.dataset.sdkAppId = sdkAppId
- scriptDom.dataset.userid = userId
- scriptDom.src = sdkUrl
- document.body.appendChild(scriptDom)
- scriptDom.addEventListener('load', () => {
- // ready事件必须监听,否则容易发生tccc不存在的错误,所有呼入呼出的逻辑必须在ready事件触发后才可以调用
- window.tccc.on('ready', () => {
- // 以下为Demo逻辑,非业务必须。业务代码主要实现都在这个部分
- const statusVal = window.tccc.Agent.getStatus()
- status.value = statusVal;
- seat.value = userId;
- })
- // 以下为Demo逻辑,非接入必须
- setInterval(() => {
- const statusVal = window.tccc.Agent.getStatus()
- status.value = statusVal;
- }, 200)
- })
- }
-
- onMounted(() => {
- // 获取Token的方法必须在页面初始化时第一优先级调用
- fetch('/loginTCCC')
- .then((res) => res.json())
- .then((res) => {
- // 以下为Demo逻辑,需要替换为业务逻辑
- if (res.code) {
- if (res.type) {
- isError.value = true;
- errorField.value = errorFieldMap[res.code]
- } else {
- isError.value = true;
- if (errorFieldMap[res.code]) {
- errorField.value = errorFieldMap[res.code]
- } else {
- alert(res.errMsg);
- }
- return;
- }
- }
- // 调用成功后才可以开始执行TCCC的注入
- injectTCCC({
- token: res.token,
- userId: res.userId,
- sdkUrl: res.sdkUrl,
- sdkAppId: res.sdkAppId,
- })
- })
- .catch((error) => {
- console.error(`获取Token失败:${error.message}`)
- })
- })
-
- const handleCallout = async () => {
- if (loading.value) {
- return
- }
- loading.value = true
- // 调用呼出方法的核心代码
- try {
- await window.tccc.Call.startOutboundCall({ phoneNumber: number.value })
- } catch (error) {
- console.error(`呼出失败:${error.message}`)
- } finally {
- loading.value = false
- }
- }
-
-
- onMounted(()=>{
- window.addEventListener('message', unityWatch,true)
- })
- function unityWatch(e){
- console.log('unityWatch方法调用 e==' + e.data.guid + ' event=' + e.data.event)
- if(e.data.event=='tellphone'){
- handleCalloutByUnity(e.data.phone)
- vueSendToUnity()
- }
- }
- //Unity端调用vue里的打电话功能
- const handleCalloutByUnity = async (phone) => {
- if (loading.value) {
- return
- }
- loading.value = true
- // 调用呼出方法的核心代码
- try {
- await window.tccc.Call.startOutboundCall({ phoneNumber: phone })
- } catch (error) {
- console.error(`呼出失败:${error.message}`)
- } finally {
- loading.value = false
- }
- }
-
- const unityIframe = ref('unityIframe')
- function vueSendToUnity(){
- console.log(statusMap[status.value])
- unityIframe.value.contentWindow.sendMsgToUnity({userId:'****',状态:status.value|| '加载中...'})
- }
-
- </script>
-
- <template>
- <div >
- <iframe id="iframe" ref="unityIframe" src="/src/unity/index.html" style="width:100%;height:100vh" frameborder="0" scrolling="auto" />
- </div>
- </template>
-
测试运行时得保证终端npm run dev在运行中
在Unity 的界面上输入手机号点击拨打,电话打了出去,同时Unity端收到了vue发送过来的消息。
这时候如果需要Unity在网页内全屏,且不显示滚动条,需要打开Unity的index.html进行再次修改:
index.html的修改后如下:
- <!DOCTYPE html>
- <html lang="en-us">
- <head>
- <meta charset="utf-8">
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <title>Unity WebGL Player | Web731</title>
- <link rel="shortcut icon" href="TemplateData/favicon.ico">
- <link rel="stylesheet" href="TemplateData/style.css">
- </head>
- <body>
- <div id="unity-container" style="width: 100%;height:100%">
- <canvas id="unity-canvas" width=auto height=auto></canvas>
- <div id="unity-loading-bar">
- <div id="unity-logo"></div>
- <div id="unity-progress-bar-empty">
- <div id="unity-progress-bar-full"></div>
- </div>
- </div>
- <div id="unity-warning"> </div>
-
- </div>
- <script>
- var container = document.querySelector("#unity-container");
- var canvas = document.querySelector("#unity-canvas");
- var loadingBar = document.querySelector("#unity-loading-bar");
- var progressBarFull = document.querySelector("#unity-progress-bar-full");
- //var fullscreenButton = document.querySelector("#unity-fullscreen-button");
- var warningBanner = document.querySelector("#unity-warning");
-
- // Shows a temporary message banner/ribbon for a few seconds, or
- // a permanent error message on top of the canvas if type=='error'.
- // If type=='warning', a yellow highlight color is used.
- // Modify or remove this function to customize the visually presented
- // way that non-critical warnings and error messages are presented to the
- // user.
- function unityShowBanner(msg, type) {
- function updateBannerVisibility() {
- warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
- }
- var div = document.createElement('div');
- div.innerHTML = msg;
- warningBanner.appendChild(div);
- if (type == 'error') div.style = 'background: red; padding: 10px;';
- else {
- if (type == 'warning') div.style = 'background: yellow; padding: 10px;';
- setTimeout(function() {
- warningBanner.removeChild(div);
- updateBannerVisibility();
- }, 5000);
- }
- updateBannerVisibility();
- }
-
- var buildUrl = "Build";
- var loaderUrl = buildUrl + "/web0803.loader.js";
- var config = {
- dataUrl: buildUrl + "/web0803.data.unityweb",
- frameworkUrl: buildUrl + "/web0803.framework.js.unityweb",
- codeUrl: buildUrl + "/web0803.wasm.unityweb",
- streamingAssetsUrl: "StreamingAssets",
- companyName: "DefaultCompany",
- productName: "Web731",
- productVersion: "0.1",
- showBanner: unityShowBanner,
- };
-
- // By default Unity keeps WebGL canvas render target size matched with
- // the DOM size of the canvas element (scaled by window.devicePixelRatio)
- // Set this to false if you want to decouple this synchronization from
- // happening inside the engine, and you would instead like to size up
- // the canvas DOM size and WebGL render target sizes yourself.
- // config.matchWebGLToCanvasSize = false;
-
- if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
- var meta = document.createElement('meta');
- meta.name = 'viewport';
- meta.content = 'width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, shrink-to-fit=yes';
- document.getElementsByTagName('head')[0].appendChild(meta);
- container.className = "unity-mobile";
-
- canvas.style.width = window.innerWidth + 'px';
- canvas.style.height = window.innerHeight + 'px';
-
-
- unityShowBanner('暂不支持移动端...');
- } else {
- canvas.style.height= document.documentElement.clientHeight+"px";
- canvas.style.width = document.documentElement.clientWidth+"px";
- }
- loadingBar.style.display = "block";
-
- var script = document.createElement("script");
- script.src = loaderUrl;
- script.onload = () => {
- createUnityInstance(canvas, config, (progress) => {
- progressBarFull.style.width = 100 * progress + "%";
- }).then((unityInstance) => {
- loadingBar.style.display = "none";
- //fullscreenButton.onclick = () => {
- // unityInstance.SetFullscreen(1);
- //};
- unityInstanceV = unityInstance;
- }).catch((message) => {
- alert(message);
- });
- };
- document.body.appendChild(script);
-
- var unityInstanceV;
- function ReportReady() {
- window.parent.postMessage({guid:"",event:"ReportReady"}, "*");
- }
- function SendPhone(_type,_phone)
- {
- // alert(s);
- if (_type == "tellphone"){
- window.parent.postMessage({guid:"",event:_type,phone:_phone}, "*");
- }else {
- window.parent.postMessage({guid:_type,event:"guid"}, "*");
- }
- }
-
- function sendMsgToUnity(obj) {
- unityInstanceV.SendMessage('UIPanel','receiveMsgFromVue',JSON.stringify(obj))
- }
-
- </script>
- </body>
- </html>
打开Unity\TemplateData路径下的style.css增加:
- html,body{width:100%;height:100%;margin:0;padding:0;overflow:hidden;}
- .webgl-content{width: 100%; height: 100%;}
- .unityContainer{width: 100%; height: 100%;}
style.css完整脚本如下:
- body { padding: 0; margin: 0 }
- #unity-container { position: absolute }
- #unity-container.unity-desktop { left: 50%; top: 50%; transform: translate(-50%, -50%) }
- #unity-container.unity-mobile { width: 100%; height: 100% }
- #unity-canvas { background: #231F20 }
- .unity-mobile #unity-canvas { width: 100%; height: 100% }
- #unity-loading-bar { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); display: none }
- #unity-logo { width: 154px; height: 130px; background: url('unity-logo-dark.png') no-repeat center }
- #unity-progress-bar-empty { width: 141px; height: 18px; margin-top: 10px; background: url('progress-bar-empty-dark.png') no-repeat center }
- #unity-progress-bar-full { width: 0%; height: 18px; margin-top: 10px; background: url('progress-bar-full-dark.png') no-repeat center }
- #unity-footer { position: relative }
- .unity-mobile #unity-footer { display: none }
- #unity-webgl-logo { float:left; width: 204px; height: 38px; background: url('webgl-logo.png') no-repeat center }
- #unity-build-title { float: right; margin-right: 10px; line-height: 38px; font-family: arial; font-size: 18px }
- #unity-fullscreen-button { float: right; width: 38px; height: 38px; background: url('fullscreen-button.png') no-repeat center }
- #unity-warning { position: absolute; left: 50%; top: 5%; transform: translate(-50%); background: white; padding: 10px; display: none }
-
-
- html,body{width:100%;height:100%;margin:0;padding:0;overflow:hidden;}
- .webgl-content{width: 100%; height: 100%;}
- .unityContainer{width: 100%; height: 100%;}
但是vue的这个右侧还是有滚动条,还没找到隐藏的方法,有知道的同学请留言,谢谢。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。