
U3DWEBGL 技术总结
2025年3月15日...大约 3 分钟
U3DWEBGL 技术总结
问题一:WEBGL 嵌入到 VUE3 中出现 VUE 组件面板无法输入数字问题
// MessageManager.cs
private void Start()
{
#if UNITY_WEBGL && !UNITY_EDITOR
WebGLInput.captureAllKeyboardInput = false;
#endif
}
// UnityGame.vue
onMounted(() => {
// 设置z-index 在最底层
const unityCanvas = document.querySelector("canvas");
console.log("unityCanvas:", unityCanvas);
if (unityCanvas) {
unityCanvas.style.zIndex = "-1";
unityCanvas.style.position = "absolute";
}
// Unity WebGL 默认会让 Canvas 接管全局键盘,需要在其加载后移除其 focus
const canvas = document.querySelector("#unity-canvas");
if (canvas) {
canvas.addEventListener("focus", (e) => {
canvas.setAttribute("tabindex", "-1"); // 禁用 tab focus
canvas.addEventListener("focus", (e) => {
e.preventDefault();
canvas.blur();
});
});
}
// 移动端
if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
const 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.head.appendChild(meta);
}
});
提示
Unity 版本:6.0.40f1
Unity WebGL 和 Vue3 通信功能
// SendMessage.jslib
mergeInto(LibraryManager.library, {
SendToVue: function (message) {
// 调用全局Vue处理函数
if (typeof window.unityToVue === "function") {
window.unityToVue(UTF8ToString(message));
}
},
});
// MessageManager.cs
using System.Runtime.InteropServices;
using UnityEngine;
/// <summary>
/// Unity-Vue消息管理脚本
/// </summary>
public class MessageManager : MonoBehaviour
{
private void Start()
{
#if UNITY_WEBGL && !UNITY_EDITOR
WebGLInput.captureAllKeyboardInput = false;
#endif
}
/// <summary>
/// vue设置物体显隐
/// </summary>
/// <param name="visible"></param>
public void Vue_SetVisible(string visible)
{
this.transform.localScale = visible == "0" ? Vector3.zero : Vector3.one;
}
/// <summary>
/// vue设置颜色
/// </summary>
/// <param name="htmlColor"></param>
public void Vue_SetColor(string htmlColor)
{
if (ColorUtility.TryParseHtmlString(htmlColor, out Color color))
{
this.GetComponent<MeshRenderer>().material.color = color;
}
}
// 声明JavaScript函数(通过WebGL调用)
[DllImport("__Internal")]
private static extern void SendToVue(string message);
private void OnMouseDown()
{
#if UNITY_WEBGL && !UNITY_EDITOR
Debug.Log("发送到Vue的消息: " + this.gameObject.name);
SendToVue(this.gameObject.name);
#endif
}
// private void Update()
// {
// if (Input.GetKeyDown(KeyCode.Space))
// {
//#if UNITY_WEBGL && !UNITY_EDITOR
// SendToVue("Clicked:" + this.gameObject.name);
//#endif
// }
// }
}
// UnityGame.vue
<template>
<div id="unity-container">
<VueUnity :unity="unityContext" class="unity-view"></VueUnity>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import VueUnity from 'unity-webgl/vue';
import UnityWebgl from 'unity-webgl';
const unityContext = new UnityWebgl({
loaderUrl: '/Unity/UnityVue.loader.js',
dataUrl: '/Unity/UnityVue.data',
frameworkUrl: '/Unity/UnityVue.framework.js',
codeUrl: '/Unity/UnityVue.wasm',
})
unityContext.on('mounted', () => console.log('Unity加载完成...'))
onMounted(() => {
const unityCanvas = document.querySelector('canvas')
console.log('unityCanvas:', unityCanvas);
if (unityCanvas) {
unityCanvas.style.zIndex = '-1'
unityCanvas.style.position = 'absolute'
}
const canvas = document.querySelector('#unity-canvas')
if (canvas) {
canvas.addEventListener('focus', (e) => {
canvas.setAttribute('tabindex', '-1') // 禁用 tab focus
canvas.addEventListener('focus', (e) => {
e.preventDefault()
canvas.blur()
})
})
}
if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
const 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.head.appendChild(meta)
}
});
defineExpose({ unityContext })
</script>
<style scoped>
#unity-container {
position: absolute !important;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: 0 !important;
overflow: hidden;
pointer-events: auto !important;
}
.unity-view {
width: 100% !important;
height: 100% !important;
display: block;
}
@media (max-width: 768px) {
#unity-container {
position: fixed !important;
}
}
</style>
// 接收UnityToVue消息的组件里实现的代码
onMounted(() => {
window.unityToVue = function (msg) {
console.log("Unity 发送到 Vue 的消息:", msg);
if (msg === "MessageManager") {
showUpload();
} else {
}
};
});