参考:https://developer.unity.cn/projects/66545214edbc2a001ddb2a0b
【1】嵌套html
一、在unity导出webgl格式,方法见上
二、新建html作为嵌套的父级,在子级html(webgl自带的index.html)实例化对象。
三、在index.html中script标签中添加函数并暴露给外部html
function whe() {
if (TestInstance) {
TestInstance.SendMessage('fffw', 'RandomPos');
}
}
function wht(x,y){
if (TestInstance) {
const data=x+","+y;
TestInstance.SendMessage('fffw', 'ChangePos',data);
}
}
window.whe=whe;
window.wht=wht;
其中:‘fffw’是unity物体对象名称,RandomPos和ChangePos是unity C Sharp中写的公共函数,作用是改变物体的位置和随机改变物体的位置。
四、编译父级html主体框架样式并嵌套。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nested Unity WebGL with Button</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-s1swLUYcLBqAXHj7nWZcBD03oDfaVT4TaOQEaQGnSa65SsyckDHTlfGcB8+LOLkz" crossorigin="anonymous"></script>
<style>
body, html {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
iframe {
width: 80%;
height: 80%;
border: none;
}
button {
margin-top: 20px;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}
</style>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.min.js"></script>
<!-- 嵌入 Unity 的 index.html -->
<iframe id="unity-iframe" src="index.html" allowfullscreen></iframe>
<!-- 创建按钮 -->
<div class="d-flex">
<div class="form-floating me-3">
<input type="text" class="form-control" id="x" placeholder="x坐标">
<label for="x">x坐标</label>
</div>
<div class="form-floating">
<input type="text" class="form-control" id="y" placeholder="y坐标">
<label for="y">y坐标</label>
</div>
</div>
<div class="d-flex">
<button onclick="runWht()" class="btn btn-primary d-inline me-2">执行 输入跳转</button>
<button onclick="runWhe()" class="btn btn-success d-inline">执行 随机跳转</button>
</div>
<script>
// 获取 iframe 元素
const iframe = document.getElementById('unity-iframe');
// 定义按钮点击事件
function runWhe() {
// 通过 iframe 的 contentWindow 访问 Unity 的 whe 函数
if (iframe.contentWindow && typeof iframe.contentWindow.whe === 'function') {
iframe.contentWindow.whe(); // 调用 whe 函数
} else {
console.error('无法访问 whe 函数,请确保 Unity 已加载完成。');
}
}
function runWht(){
let x = parseFloat(document.getElementById('x').value);
let y = parseFloat(document.getElementById('y').value);
// 检查输入是否有效
if (!x || !y) {
console.error('请输入有效的 x 和 y 值。');
return;
}
if (iframe.contentWindow && typeof iframe.contentWindow.wht === 'function') {
iframe.contentWindow.wht(x,y); // 调用 wht 函数
} else {
console.error('无法访问 wht 函数,请确保 Unity 已加载完成。');
}
}
</script>
</body>
</html>
其中:runwhe runwht用于执行暴露的函数,if用于:
iframe.contentWindow
是否存在:iframe.contentWindow
是 iframe 元素的一个属性,它返回 iframe 内部窗口的window
对象。如果 iframe 已经加载完成并且可以访问,iframe.contentWindow
会返回一个有效的window
对象;否则,它可能是null
或undefined
。
iframe.contentWindow.whe
是否是一个函数:typeof iframe.contentWindow.whe === 'function'
用于检查whe
是否是一个函数。如果whe
是 iframe 内部窗口中的一个函数,那么这个条件为true
;否则为false
。
注意:由于SendMessage只能传递一个参数,但是有的时候需要函数有两个参数或者多个参数比如这里需要传入xy轴两个坐标的值,我们在C sharp中和index.html写函数时要么以json格式传入,要么先合并字符串再在两个文件中解成两个参数。
tips:这里调用的函数都是从iframe窗口中调用的,要先获取窗口,再调用windows暴露函数(使用 iframe.contentWindow.wht(x,y); // 调用 wht 函数)
【2】应用到django框架
将main.html放在templates模板文件夹里,将webgl自带的文件放在static文件夹里。
在settings.py中配置base 静态文件目录
修改main.html打开iframe的路径
开头加上加载静态文件load static
效果:
2025-03-12 11-34-27