| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- <template>
- <div class="main-container">
- <!-- Unity Canvas 容器 -->
- <div id="unity-container" class="unity-desktop">
- <canvas id="unity-canvas" ref="unityCanvas"></canvas>
- <div id="unity-loading-bar">
- <div id="unity-logo"></div>
- <div id="unity-progress-bar-empty">
- <div id="unity-progress-bar-full" :style="{ width: progress + '%' }"></div>
- </div>
- </div>
- <div id="unity-warning"></div>
- <div id="unity-footer">
- <div id="unity-webgl-logo"></div>
- <div id="unity-fullscreen-button" @click="setFullscreen">⛶</div>
- </div>
- </div>
- <!-- 控制面板 -->
- <div class="controls">
- <h2>模型控制器</h2>
- <!-- 创建 / 销毁模块 -->
- <div class="control-group">
- <h3>创建 / 销毁</h3>
- <label>模型ID:
- <input v-model="create.modelId" type="text" />
- </label>
- <label>模型类型:
- <select v-model="create.modelType">
- <option value="red">red</option>
- <option value="green">green</option>
- <option value="blue">blue</option>
- </select>
- </label>
- <label>位置 (x,y,z):
- <input v-model="create.position" type="text" />
- </label>
- <label>旋转 (x,y,z):
- <input v-model="create.rotation" type="text" />
- </label>
- <button @click="createModel">创建模型</button>
- <button @click="destroyModel">销毁模型</button>
- </div>
- <!-- 控制模块 -->
- <div class="control-group">
- <h3>控制指定ID的模型</h3>
- <label>目标ID:
- <input v-model="control.modelId" type="text" />
- </label>
- <hr />
- <label>新位置:
- <input v-model="control.position" type="text" />
- </label>
- <label>新旋转:
- <input v-model="control.rotation" type="text" />
- </label>
- <button @click="setModelTransform">设置变换</button>
- <hr />
- <label>颜色:
- <input v-model="control.color" type="color" />
- </label>
- <button @click="changeModelColor">改变颜色</button>
- </div>
- </div>
- </div>
- </template>
- <script>
- export default {
- name: 'UnityController',
- data() {
- return {
- unityInstance: null, // 存储 Unity 实例
- progress: 0, // 加载进度
- // 创建表单数据
- create: {
- modelId: 'my_web_cube_1',
- modelType: 'red',
- position: '0,0.5,0',
- rotation: '0,0,0'
- },
- // 控制表单数据
- control: {
- modelId: 'my_web_cube_1',
- position: '2,1,0',
- rotation: '0,90,0',
- color: '#ff0000'
- }
- }
- },
- mounted() {
- this.loadUnity()
- },
- methods: {
- loadUnity() {
- const container = document.getElementById('unity-container')
- const canvas = this.$refs.unityCanvas
- const loadingBar = document.getElementById('unity-loading-bar')
- const progressBarFull = document.getElementById('unity-progress-bar-full')
- const fullscreenButton = document.getElementById('unity-fullscreen-button')
- const warningBanner = document.getElementById('unity-warning')
- function unityShowBanner(msg, type) {
- const div = document.createElement('div')
- div.innerHTML = msg
- warningBanner.appendChild(div)
- if (type === 'error') {
- div.style = 'background: red; padding: 10px; color: white;'
- } else {
- if (type === 'warning') div.style = 'background: yellow; padding: 10px;'
- setTimeout(() => {
- warningBanner.removeChild(div)
- }, 5000)
- }
- }
- // 假设 Unity 文件放在 public/unity 下
- const buildUrl = '/3DModel/Build'
- const config = {
- dataUrl: `${buildUrl}/Build.data`,
- frameworkUrl: `${buildUrl}/Build.framework.js`,
- codeUrl: `${buildUrl}/Build.wasm`,
- streamingAssetsUrl: 'StreamingAssets',
- companyName: 'DefaultCompany',
- productName: 'My project',
- productVersion: '0.1',
- showBanner: unityShowBanner
- }
- // 移动端适配
- if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
- container.className = 'unity-mobile'
- canvas.className = 'unity-mobile'
- } else {
- canvas.style.width = '960px'
- canvas.style.height = '600px'
- }
- loadingBar.style.display = 'block'
- const script = document.createElement('script')
- script.src = '/3DModel/Build/Build.loader.js' // 路径需匹配
- script.onload = () => {
- createUnityInstance(canvas, config, (progress) => {
- this.progress = 100 * progress
- progressBarFull.style.width = this.progress + '%'
- })
- .then((instance) => {
- this.unityInstance = instance
- loadingBar.style.display = 'none'
- })
- .catch((message) => {
- alert(message)
- })
- }
- document.body.appendChild(script)
- },
- // 发送消息到 Unity 的通用方法
- sendMessage(methodName, data) {
- if (!this.unityInstance) {
- alert('Unity 实例尚未加载完成!')
- return
- }
- this.unityInstance.SendMessage('WebGLBridgeManager', methodName, JSON.stringify(data))
- },
- createModel() {
- this.sendMessage('CreateModel', {
- modelId: this.create.modelId,
- modelType: this.create.modelType,
- position: this.create.position,
- rotation: this.create.rotation
- })
- },
- destroyModel() {
- this.sendMessage('DestroyModel', {
- modelId: this.create.modelId
- })
- },
- setModelTransform() {
- this.sendMessage('SetModelTransform', {
- modelId: this.control.modelId,
- position: this.control.position,
- rotation: this.control.rotation
- })
- },
- changeModelColor() {
- const hex = this.control.color
- const r = parseInt(hex.slice(1, 3), 16) / 255
- const g = parseInt(hex.slice(3, 5), 16) / 255
- const b = parseInt(hex.slice(5, 7), 16) / 255
- this.sendMessage('ChangeModelColor', {
- modelId: this.control.modelId,
- r, g, b
- })
- },
- setFullscreen() {
- if (this.unityInstance) {
- this.unityInstance.SetFullscreen(1)
- }
- }
- }
- }
- </script>
- <style scoped>
- .main-container {
- display: flex;
- align-items: flex-start;
- gap: 20px;
- padding: 20px;
- font-family: Arial, sans-serif;
- }
- /* Unity 容器样式 */
- #unity-container {
- flex: 1;
- min-width: 900px;
- border: 1px solid #ccc;
- border-radius: 8px;
- background: #000;
- position: relative;
- }
- #unity-canvas {
- width: 100%;
- height: 700px;
- display: block;
- }
- #unity-loading-bar {
- display: none;
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- width: 200px;
- height: 20px;
- background: rgba(0, 0, 0, 0.8);
- border-radius: 10px;
- padding: 4px;
- }
- #unity-progress-bar-empty {
- width: 100%;
- height: 100%;
- background: #444;
- border-radius: 8px;
- overflow: hidden;
- }
- #unity-progress-bar-full {
- height: 100%;
- background: #0078d4;
- width: 0;
- transition: width 0.2s;
- }
- /* 控制面板样式 */
- .controls {
- width: 300px;
- }
- .control-group {
- border: 1px solid #ccc;
- padding: 15px;
- border-radius: 8px;
- background-color: #f9f9f9;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
- }
- h3 {
- margin-top: 0;
- color: #333;
- }
- label {
- display: block;
- margin-bottom: 5px;
- font-size: 14px;
- color: #555;
- }
- input[type="text"], select, input[type="color"] {
- width: 100%;
- padding: 8px;
- margin-bottom: 10px;
- border: 1px solid #ccc;
- border-radius: 4px;
- box-sizing: border-box;
- }
- button {
- width: 100%;
- padding: 10px;
- background-color: #0078d4;
- color: white;
- border: none;
- border-radius: 4px;
- cursor: pointer;
- font-weight: bold;
- margin-bottom: 10px;
- }
- button:hover {
- background-color: #005a9e;
- }
- hr {
- border: 0;
- border-top: 1px solid #eee;
- margin: 15px 0;
- }
- </style>
|