騰訊云聯(lián)絡(luò)中心SDK:云聯(lián)絡(luò)中心 Web-SDK 開發(fā)指南-文檔中心-騰訊云 (tencent.com)
1 首先下載Demo
?
?1.1 對其進(jìn)行解壓
?
?1.2根據(jù)文檔操作
查看README.md,根據(jù)說明設(shè)置server下的dev.js里的相關(guān)參數(shù)。
然后打開電腦終端,cd到項目的路徑:
?
安裝依賴
??
運行
??
1.3 運行demo
復(fù)制http://127.0.0.1:5173/在瀏覽器里輸入,這時候會顯示如下畫面:
輸入電話號碼,點擊撥打就會把電話打出去。
??
?2 在Unity端的操作
2.1 創(chuàng)建Unity工程
?新建一個Unity工程,在Assets/Plugins/WebGl下創(chuàng)建一個后綴為jslib的文件,記事本打開編寫腳本如下:
mergeInto(LibraryManager.library, {
ReportReady: function () {
window.ReportReady()
},
TellPhone:function(typeName, phone){
SendPhone(UTF8ToString(typeName), UTF8ToString(phone))
}
});
?
?2.2 編寫掛載對象UIPanel上的腳本
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);
}
}
2.3 Unity的UI界面
?
2.4最后打包webgl的包
放在tccc-demo-vue\src\路徑下,如下圖所示:
??
2.5改寫index.html
打開index.html:
?
SendPhone是Unity發(fā)送給網(wǎng)頁的方法,sendMsgToUnity方法是網(wǎng)頁發(fā)送個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>
2.6 修改Container.vue腳本
增加和Unity交互的方法
?
?把原先顯示的界面代碼刪除掉<div class="container"> </div>
?
?style 部分也刪掉
對Vue不熟悉,我的理解是這樣的(理解不對請留言指正)
其中?
onMounted(()=>{
? ? ? ? window.addEventListener('message', unityWatch,true)
? ? })
是事件,對Unity發(fā)送來的消息進(jìn)行監(jiān)聽。
function ?vueSendToUnity(){
? ? ? console.log(statusMap[status.value])
? ? ? unityIframe.value.contentWindow.sendMsgToUnity({userId:'****',狀態(tài):status.value|| '加載中...'}) ?
}
是vue把消息發(fā)送到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部分進(jìn)行顯示(其中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: '網(wǎng)絡(luò)斷開,重連中',
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事件必須監(jiān)聽,否則容易發(fā)生tccc不存在的錯誤,所有呼入呼出的邏輯必須在ready事件觸發(fā)后才可以調(diào)用
window.tccc.on('ready', () => {
// 以下為Demo邏輯,非業(yè)務(wù)必須。業(yè)務(wù)代碼主要實現(xiàn)都在這個部分
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的方法必須在頁面初始化時第一優(yōu)先級調(diào)用
fetch('/loginTCCC')
.then((res) => res.json())
.then((res) => {
// 以下為Demo邏輯,需要替換為業(yè)務(wù)邏輯
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;
}
}
// 調(diào)用成功后才可以開始執(zhí)行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
// 調(diào)用呼出方法的核心代碼
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方法調(diào)用 e==' + e.data.guid + ' event=' + e.data.event)
if(e.data.event=='tellphone'){
handleCalloutByUnity(e.data.phone)
vueSendToUnity()
}
}
//Unity端調(diào)用vue里的打電話功能
const handleCalloutByUnity = async (phone) => {
if (loading.value) {
return
}
loading.value = true
// 調(diào)用呼出方法的核心代碼
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:'****',狀態(tài):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>
2.7 測試運行
測試運行時得保證終端npm run dev在運行中
?在Unity 的界面上輸入手機(jī)號點擊撥打,電話打了出去,同時Unity端收到了vue發(fā)送過來的消息。
2.8 網(wǎng)頁內(nèi)全屏
這時候如果需要Unity在網(wǎng)頁內(nèi)全屏,且不顯示滾動條,需要打開Unity的index.html進(jìn)行再次修改:
?
?
?
?
?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%;}
文章來源:http://www.zghlxwxcb.cn/news/detail-630970.html
?但是vue的這個右側(cè)還是有滾動條,還沒找到隱藏的方法,有知道的同學(xué)請留言,謝謝。文章來源地址http://www.zghlxwxcb.cn/news/detail-630970.html
到了這里,關(guān)于Unity之webgl端通過vue3接入騰訊云聯(lián)絡(luò)中心SDK的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!