@zeewain/3d-avatar-sdk 1.2.1 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -4
- package/dist/assets/Build/webgl.data.unityweb +0 -0
- package/dist/assets/Build/webgl.framework.js.unityweb +0 -0
- package/dist/assets/Build/webgl.wasm.unityweb +0 -0
- package/dist/examples/test-umd/index.html +762 -0
- package/dist/examples/test-vue2/.eslintignore +45 -0
- package/dist/examples/test-vue2/.eslintrc.js +174 -0
- package/dist/examples/test-vue2/.stylelintignore +50 -0
- package/dist/examples/test-vue2/.stylelintrc.js +79 -0
- package/dist/examples/test-vue2/README.md +139 -0
- package/dist/examples/test-vue2/babel.config.js +14 -0
- package/dist/examples/test-vue2/package.json +53 -0
- package/dist/examples/test-vue2/pnpm-lock.yaml +8776 -0
- package/dist/examples/test-vue2/public/index.html +19 -0
- package/dist/examples/test-vue2/setup.js +170 -0
- package/dist/examples/test-vue2/src/App.vue +943 -0
- package/dist/examples/test-vue2/src/components/BroadcastAPI.vue +666 -0
- package/dist/examples/test-vue2/src/components/CameraAPI.vue +414 -0
- package/dist/examples/test-vue2/src/components/GlobalConfig.vue +200 -0
- package/dist/examples/test-vue2/src/components/InfoCards.vue +294 -0
- package/dist/examples/test-vue2/src/components/InitAPI.vue +334 -0
- package/dist/examples/test-vue2/src/components/LogPanel.vue +249 -0
- package/dist/examples/test-vue2/src/components/MotionControlAPI.vue +400 -0
- package/dist/examples/test-vue2/src/components/UnityPreview.vue +201 -0
- package/dist/examples/test-vue2/src/main.js +16 -0
- package/dist/examples/test-vue2/vue.config.js +41 -0
- package/dist/examples/test-vue3/.eslintrc +3 -0
- package/dist/examples/test-vue3/.stylelintignore +3 -0
- package/dist/examples/test-vue3/.stylelintrc +48 -0
- package/dist/examples/test-vue3/README.md +236 -0
- package/dist/examples/test-vue3/env.d.ts +8 -0
- package/dist/examples/test-vue3/index.html +95 -0
- package/dist/examples/test-vue3/package.json +55 -0
- package/dist/examples/test-vue3/pnpm-lock.yaml +4636 -0
- package/dist/examples/test-vue3/setup.js +167 -0
- package/dist/examples/test-vue3/src/App.vue +962 -0
- package/dist/examples/test-vue3/src/components/BroadcastAPI.vue +636 -0
- package/dist/examples/test-vue3/src/components/CameraAPI.vue +376 -0
- package/dist/examples/test-vue3/src/components/GlobalConfig.vue +213 -0
- package/dist/examples/test-vue3/src/components/InfoCards.vue +288 -0
- package/dist/examples/test-vue3/src/components/InitAPI.vue +339 -0
- package/dist/examples/test-vue3/src/components/LogPanel.vue +236 -0
- package/dist/examples/test-vue3/src/components/MotionControlAPI.vue +373 -0
- package/dist/examples/test-vue3/src/components/UnityPreview.vue +189 -0
- package/dist/examples/test-vue3/src/main.ts +12 -0
- package/dist/examples/test-vue3/src/types.ts +9 -0
- package/dist/examples/test-vue3/tsconfig.json +44 -0
- package/dist/examples/test-vue3/tsconfig.node.json +14 -0
- package/dist/examples/test-vue3/vite.config.ts +75 -0
- package/dist/index.d.ts +15 -9
- package/dist/index.es5.js +75 -27
- package/dist/index.es5.umd.js +75 -27
- package/dist/index.esm.js +78 -22
- package/dist/index.umd.cjs +78 -22
- package/package.json +4 -3
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-card class="unity-preview" shadow="hover">
|
|
3
|
+
<div slot="header" class="card-header">
|
|
4
|
+
<span>Unity 预览</span>
|
|
5
|
+
<el-tag v-if="sdkStatus.unityLoaded" type="success" size="mini">已加载</el-tag>
|
|
6
|
+
<el-tag v-else type="info" size="mini">未加载</el-tag>
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
<div class="unity-container-wrapper">
|
|
10
|
+
<div id="unity-container" class="unity-container">
|
|
11
|
+
<div v-if="!sdkStatus.unityLoaded" class="unity-tip">
|
|
12
|
+
<i class="el-icon-monitor"></i>
|
|
13
|
+
<p>Unity 内容将在此处加载...</p>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<div class="unity-controls">
|
|
19
|
+
<el-button-group>
|
|
20
|
+
<el-button
|
|
21
|
+
type="warning"
|
|
22
|
+
size="small"
|
|
23
|
+
icon="el-icon-close"
|
|
24
|
+
:disabled="!sdkStatus.avatarLoaded"
|
|
25
|
+
@click="handleUnloadAvatar"
|
|
26
|
+
>
|
|
27
|
+
卸载Avatar
|
|
28
|
+
</el-button>
|
|
29
|
+
<el-button
|
|
30
|
+
type="danger"
|
|
31
|
+
size="small"
|
|
32
|
+
icon="el-icon-delete"
|
|
33
|
+
:disabled="!sdkStatus.unityLoaded"
|
|
34
|
+
@click="handleDestroySDK"
|
|
35
|
+
>
|
|
36
|
+
销毁实例
|
|
37
|
+
</el-button>
|
|
38
|
+
</el-button-group>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<!-- 加载进度显示 -->
|
|
42
|
+
<div v-if="loadingProgress > 0 && loadingProgress < 1" class="loading-progress">
|
|
43
|
+
<el-progress
|
|
44
|
+
:percentage="Math.round(loadingProgress * 100)"
|
|
45
|
+
:stroke-width="6"
|
|
46
|
+
text-inside
|
|
47
|
+
/>
|
|
48
|
+
<p class="progress-text">Unity 加载中,请稍候...</p>
|
|
49
|
+
</div>
|
|
50
|
+
</el-card>
|
|
51
|
+
</template>
|
|
52
|
+
|
|
53
|
+
<script>
|
|
54
|
+
export default {
|
|
55
|
+
name: 'UnityPreview',
|
|
56
|
+
props: {
|
|
57
|
+
sdkStatus: {
|
|
58
|
+
type: Object,
|
|
59
|
+
required: true,
|
|
60
|
+
default: () => ({
|
|
61
|
+
unityLoaded: false,
|
|
62
|
+
avatarLoaded: false
|
|
63
|
+
})
|
|
64
|
+
},
|
|
65
|
+
loadingProgress: {
|
|
66
|
+
type: Number,
|
|
67
|
+
default: 0
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
methods: {
|
|
71
|
+
handleUnloadAvatar () {
|
|
72
|
+
this.$emit('unload-avatar')
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
handleDestroySDK () {
|
|
76
|
+
this.$emit('destroy-sdk')
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
</script>
|
|
81
|
+
|
|
82
|
+
<style lang="scss" scoped>
|
|
83
|
+
// Unity预览
|
|
84
|
+
.unity-preview {
|
|
85
|
+
position: relative;
|
|
86
|
+
display: flex;
|
|
87
|
+
width: 100%;
|
|
88
|
+
height: 100%;
|
|
89
|
+
overflow: hidden;
|
|
90
|
+
flex-direction: column;
|
|
91
|
+
|
|
92
|
+
.card-header {
|
|
93
|
+
display: flex;
|
|
94
|
+
justify-content: space-between;
|
|
95
|
+
align-items: center;
|
|
96
|
+
font-weight: 600;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
:deep(.el-card__body) {
|
|
100
|
+
display: flex;
|
|
101
|
+
width: 100%;
|
|
102
|
+
height: 100%;
|
|
103
|
+
flex-direction: column;
|
|
104
|
+
box-sizing: border-box;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.unity-container-wrapper {
|
|
108
|
+
position: relative;
|
|
109
|
+
width: 100%;
|
|
110
|
+
max-height: 600px; // 添加最大高度限制
|
|
111
|
+
margin-bottom: 15px;
|
|
112
|
+
overflow: hidden; // 防止内容溢出
|
|
113
|
+
flex: 1;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.unity-container {
|
|
117
|
+
position: relative;
|
|
118
|
+
width: 100%;
|
|
119
|
+
height: 100%;
|
|
120
|
+
max-height: 100%; // 确保不超过父容器
|
|
121
|
+
overflow: hidden;
|
|
122
|
+
background-color: #000;
|
|
123
|
+
border-radius: 4px;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.unity-tip {
|
|
127
|
+
position: absolute;
|
|
128
|
+
top: 50%;
|
|
129
|
+
left: 50%;
|
|
130
|
+
color: white; // 确保在黑色背景上文字可见
|
|
131
|
+
text-align: center;
|
|
132
|
+
transform: translate(-50%, -50%);
|
|
133
|
+
|
|
134
|
+
i {
|
|
135
|
+
margin-bottom: 10px;
|
|
136
|
+
font-size: 48px;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
p {
|
|
140
|
+
margin: 0;
|
|
141
|
+
font-size: 14px;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.unity-controls {
|
|
146
|
+
display: flex;
|
|
147
|
+
justify-content: center;
|
|
148
|
+
padding-top: 10px;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.loading-progress {
|
|
152
|
+
position: absolute;
|
|
153
|
+
top: 50%;
|
|
154
|
+
left: 50%;
|
|
155
|
+
width: 80%;
|
|
156
|
+
transform: translate(-50%, -50%);
|
|
157
|
+
text-align: center;
|
|
158
|
+
z-index: 10;
|
|
159
|
+
|
|
160
|
+
.progress-text {
|
|
161
|
+
color: white;
|
|
162
|
+
margin-top: 10px;
|
|
163
|
+
font-size: 14px;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// 移动端优化
|
|
169
|
+
@media screen and (width <= 768px) {
|
|
170
|
+
.unity-preview {
|
|
171
|
+
.unity-container-wrapper {
|
|
172
|
+
height: 250px;
|
|
173
|
+
max-height: 250px; // 确保移动端不会超过设定高度
|
|
174
|
+
flex: none;
|
|
175
|
+
overflow: hidden; // 防止内容溢出
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.unity-controls {
|
|
179
|
+
.el-button-group {
|
|
180
|
+
display: flex;
|
|
181
|
+
flex-direction: column;
|
|
182
|
+
|
|
183
|
+
.el-button {
|
|
184
|
+
margin: 2px 0;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// 平板端优化
|
|
192
|
+
@media screen and (width <= 992px) and (width > 768px) {
|
|
193
|
+
.unity-preview {
|
|
194
|
+
.unity-container-wrapper {
|
|
195
|
+
height: 300px; // 平板端适中高度
|
|
196
|
+
max-height: 300px; // 确保平板端不会超过设定高度
|
|
197
|
+
overflow: hidden; // 防止内容溢出
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
</style>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import Vue from 'vue'
|
|
2
|
+
import App from './App.vue'
|
|
3
|
+
|
|
4
|
+
// 引入Element-UI
|
|
5
|
+
import ElementUI from 'element-ui'
|
|
6
|
+
import 'element-ui/lib/theme-chalk/index.css'
|
|
7
|
+
|
|
8
|
+
// 使用Element-UI
|
|
9
|
+
Vue.use(ElementUI)
|
|
10
|
+
|
|
11
|
+
// 关闭生产提示
|
|
12
|
+
Vue.config.productionTip = false
|
|
13
|
+
|
|
14
|
+
new Vue({
|
|
15
|
+
render: h => h(App)
|
|
16
|
+
}).$mount('#app')
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Vue CLI 配置文件
|
|
3
|
+
* @description 支持本地开发和npm包两种模式的动态配置
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { defineConfig } = require('@vue/cli-service')
|
|
7
|
+
const path = require('path')
|
|
8
|
+
|
|
9
|
+
// 检查是否使用本地开发版本(通过环境变量控制)
|
|
10
|
+
const useLocalSDK = process.env.VUE_APP_USE_LOCAL_SDK === 'true'
|
|
11
|
+
const localSDKPath = path.resolve(__dirname, '../../dist')
|
|
12
|
+
|
|
13
|
+
console.log('🔧 Vue 配置信息:')
|
|
14
|
+
console.log(` - 使用本地 SDK: ${useLocalSDK ? '✅ 是' : '❌ 否'}`)
|
|
15
|
+
if (useLocalSDK) {
|
|
16
|
+
console.log(` - 本地 SDK 路径: ${localSDKPath}`)
|
|
17
|
+
console.log(' - 运行模式: 开发模式')
|
|
18
|
+
} else {
|
|
19
|
+
console.log(' - 运行模式: npm包模式')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = defineConfig({
|
|
23
|
+
transpileDependencies: true,
|
|
24
|
+
publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
|
|
25
|
+
devServer: {
|
|
26
|
+
port: 8080,
|
|
27
|
+
host: 'localhost',
|
|
28
|
+
open: true
|
|
29
|
+
},
|
|
30
|
+
configureWebpack: {
|
|
31
|
+
resolve: {
|
|
32
|
+
alias: {
|
|
33
|
+
'@': require('path').resolve(__dirname, 'src'),
|
|
34
|
+
// 如果启用本地开发模式,将 SDK 指向本地构建版本
|
|
35
|
+
...(useLocalSDK && {
|
|
36
|
+
'@zeewain/3d-avatar-sdk': path.resolve(localSDKPath, 'index.esm.js')
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
})
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": [
|
|
3
|
+
"stylelint-config-standard",
|
|
4
|
+
"stylelint-config-standard-scss",
|
|
5
|
+
"stylelint-config-standard-vue/scss"
|
|
6
|
+
],
|
|
7
|
+
"plugins": [
|
|
8
|
+
"stylelint-scss"
|
|
9
|
+
],
|
|
10
|
+
"customSyntax": "postcss-html",
|
|
11
|
+
"rules": {
|
|
12
|
+
"indentation": 2,
|
|
13
|
+
"rule-empty-line-before": "never",
|
|
14
|
+
"at-rule-empty-line-before": "never",
|
|
15
|
+
"at-rule-no-unknown": null,
|
|
16
|
+
"no-descending-specificity": null,
|
|
17
|
+
"selector-pseudo-class-no-unknown": null,
|
|
18
|
+
"property-no-unknown": null,
|
|
19
|
+
"font-family-no-missing-generic-family-keyword": null,
|
|
20
|
+
"selector-id-pattern": null,
|
|
21
|
+
"selector-class-pattern": null,
|
|
22
|
+
"scss/no-global-function-names": null,
|
|
23
|
+
"scss/at-import-partial-extension": null,
|
|
24
|
+
"function-no-unknown": [
|
|
25
|
+
true,
|
|
26
|
+
{
|
|
27
|
+
"ignoreFunctions": [
|
|
28
|
+
"v-bind",
|
|
29
|
+
"map-get",
|
|
30
|
+
"lighten",
|
|
31
|
+
"darken",
|
|
32
|
+
"themed"
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"property-no-vendor-prefix": [
|
|
37
|
+
true,
|
|
38
|
+
{
|
|
39
|
+
"ignoreProperties": [
|
|
40
|
+
"mask-image"
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"max-line-length": null,
|
|
45
|
+
"no-empty-source": null,
|
|
46
|
+
"color-function-notation": null
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# ZEE 3D Avatar SDK - Vue3 测试项目
|
|
2
|
+
|
|
3
|
+
## 📋 项目概述
|
|
4
|
+
|
|
5
|
+
这是一个基于 Vue3 + TypeScript + Vite + Element Plus 技术栈的 ZEE 3D Avatar SDK 测试项目,展示了如何在现代 Vue3 应用中集成和使用最新的统一架构 SDK。
|
|
6
|
+
|
|
7
|
+
## ✨ 技术栈
|
|
8
|
+
|
|
9
|
+
- **Vue 3.4+** - 渐进式 JavaScript 框架
|
|
10
|
+
- **TypeScript** - JavaScript 的超集,提供类型安全
|
|
11
|
+
- **Vite 5.0+** - 下一代前端构建工具
|
|
12
|
+
- **Element Plus** - 基于 Vue3 的组件库
|
|
13
|
+
- **Sass/SCSS** - CSS 预处理器
|
|
14
|
+
- **ESLint + Prettier** - 代码规范和格式化
|
|
15
|
+
- **Stylelint** - CSS 代码规范
|
|
16
|
+
|
|
17
|
+
## 🚀 核心特性
|
|
18
|
+
|
|
19
|
+
### SDK 统一架构
|
|
20
|
+
- **单一入口**:使用 `ZEEAvatarSDK` 统一类管理所有功能
|
|
21
|
+
- **一步初始化**:`initializeAvatar()` 方法统一完成 Unity 初始化和数字人加载
|
|
22
|
+
- **多实例支持**:支持同页面多个独立 SDK 实例
|
|
23
|
+
- **完整类型支持**:TypeScript 类型定义,智能提示
|
|
24
|
+
|
|
25
|
+
### 功能模块
|
|
26
|
+
- **全局配置管理** - Token 和 Avatar 编码配置
|
|
27
|
+
- **Avatar 初始化** - 统一的数字人初始化流程
|
|
28
|
+
- **动作控制** - 播放动作、获取当前动作信息
|
|
29
|
+
- **智能播报** - 文本转语音、音频播报、播报控制
|
|
30
|
+
- **镜头控制** - 全身、半身、面部镜头切换
|
|
31
|
+
- **实时日志** - 操作日志记录和显示
|
|
32
|
+
- **响应式布局** - 支持 PC 和移动端适配
|
|
33
|
+
|
|
34
|
+
## 📦 安装和运行
|
|
35
|
+
|
|
36
|
+
### 环境要求
|
|
37
|
+
- Node.js 18.0+
|
|
38
|
+
- pnpm 8.0+
|
|
39
|
+
|
|
40
|
+
### 安装依赖
|
|
41
|
+
```bash
|
|
42
|
+
cd examples/test-vue3
|
|
43
|
+
pnpm install
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 开发模式
|
|
47
|
+
```bash
|
|
48
|
+
# 使用本地 SDK 源码(推荐)
|
|
49
|
+
pnpm run dev
|
|
50
|
+
|
|
51
|
+
# 使用 npm 包版本
|
|
52
|
+
pnpm run dev:npm
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 构建项目
|
|
56
|
+
```bash
|
|
57
|
+
pnpm run build
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 预览构建结果
|
|
61
|
+
```bash
|
|
62
|
+
pnpm run preview
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 🛠️ 开发命令
|
|
66
|
+
|
|
67
|
+
### 代码检查和格式化
|
|
68
|
+
```bash
|
|
69
|
+
# ESLint 检查
|
|
70
|
+
pnpm run lint:js
|
|
71
|
+
|
|
72
|
+
# Stylelint 检查
|
|
73
|
+
pnpm run lint:css
|
|
74
|
+
|
|
75
|
+
# 修复 ESLint 问题
|
|
76
|
+
pnpm run lint:fix
|
|
77
|
+
|
|
78
|
+
# 修复 Stylelint 问题
|
|
79
|
+
pnpm run lint:css-fix
|
|
80
|
+
|
|
81
|
+
# 检查和修复所有问题
|
|
82
|
+
pnpm run lint:all-fix
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### TypeScript 类型检查
|
|
86
|
+
```bash
|
|
87
|
+
pnpm run type-check
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## 📁 项目结构
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
examples/test-vue3/
|
|
94
|
+
├── public/ # 静态资源
|
|
95
|
+
│ ├── index.html # HTML 模板
|
|
96
|
+
│ └── assets/ # Unity 构建文件(自动复制)
|
|
97
|
+
├── src/ # 源代码
|
|
98
|
+
│ ├── components/ # Vue 组件
|
|
99
|
+
│ │ ├── GlobalConfig.vue # 全局配置组件
|
|
100
|
+
│ │ ├── InitApi.vue # 初始化 API 组件
|
|
101
|
+
│ │ ├── MotionControlApi.vue # 动作控制 API 组件
|
|
102
|
+
│ │ ├── BroadcastApi.vue # 播报 API 组件
|
|
103
|
+
│ │ ├── CameraApi.vue # 镜头控制 API 组件
|
|
104
|
+
│ │ ├── UnityPreview.vue # Unity 预览组件
|
|
105
|
+
│ │ ├── LogPanel.vue # 日志面板组件
|
|
106
|
+
│ │ └── InfoCards.vue # 信息卡片组件
|
|
107
|
+
│ ├── styles/ # 样式文件
|
|
108
|
+
│ │ └── global.scss # 全局样式
|
|
109
|
+
│ ├── types/ # TypeScript 类型定义
|
|
110
|
+
│ │ └── index.ts # 类型定义文件
|
|
111
|
+
│ ├── App.vue # 根组件
|
|
112
|
+
│ └── main.ts # 应用入口
|
|
113
|
+
├── setup.js # 项目设置脚本
|
|
114
|
+
├── vite.config.ts # Vite 配置
|
|
115
|
+
├── tsconfig.json # TypeScript 配置
|
|
116
|
+
├── package.json # 项目配置
|
|
117
|
+
└── README.md # 项目说明
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## 🔧 核心组件说明
|
|
121
|
+
|
|
122
|
+
### App.vue
|
|
123
|
+
主应用组件,使用 Vue3 Composition API 和 TypeScript:
|
|
124
|
+
- 统一的 SDK 实例管理
|
|
125
|
+
- 响应式布局适配
|
|
126
|
+
- 全局状态管理
|
|
127
|
+
- 事件处理和错误管理
|
|
128
|
+
|
|
129
|
+
### GlobalConfig.vue
|
|
130
|
+
全局配置组件:
|
|
131
|
+
- Token 和 Avatar 编码配置
|
|
132
|
+
- 本地存储管理
|
|
133
|
+
- 配置验证和应用
|
|
134
|
+
|
|
135
|
+
### InitApi.vue
|
|
136
|
+
初始化 API 组件:
|
|
137
|
+
- 使用统一的 `initializeAvatar()` 方法
|
|
138
|
+
- 自动完成 Unity 初始化和数字人加载
|
|
139
|
+
- 进度显示和状态管理
|
|
140
|
+
|
|
141
|
+
### MotionControlApi.vue
|
|
142
|
+
动作控制 API 组件:
|
|
143
|
+
- 播放指定动作
|
|
144
|
+
- 获取当前动作信息
|
|
145
|
+
- 动作状态管理
|
|
146
|
+
|
|
147
|
+
### BroadcastApi.vue
|
|
148
|
+
播报 API 组件:
|
|
149
|
+
- 文本转语音播报
|
|
150
|
+
- 音频文件播报
|
|
151
|
+
- 播报控制(暂停、恢复、停止)
|
|
152
|
+
|
|
153
|
+
### CameraApi.vue
|
|
154
|
+
镜头控制 API 组件:
|
|
155
|
+
- 全身、半身、面部镜头切换
|
|
156
|
+
- 实时镜头状态显示
|
|
157
|
+
|
|
158
|
+
### UnityPreview.vue
|
|
159
|
+
Unity 预览组件:
|
|
160
|
+
- Unity 容器管理
|
|
161
|
+
- 加载进度显示
|
|
162
|
+
- 资源管理操作
|
|
163
|
+
|
|
164
|
+
### LogPanel.vue
|
|
165
|
+
日志面板组件:
|
|
166
|
+
- 实时日志显示
|
|
167
|
+
- 日志类型区分
|
|
168
|
+
- 日志清理功能
|
|
169
|
+
|
|
170
|
+
## 🎯 使用示例
|
|
171
|
+
|
|
172
|
+
### 基础使用
|
|
173
|
+
```typescript
|
|
174
|
+
import { ZEEAvatarSDK, AvatarCameraType, BroadcastType } from '@zeewain/3d-avatar-sdk'
|
|
175
|
+
|
|
176
|
+
// 创建 SDK 实例
|
|
177
|
+
const sdk = new ZEEAvatarSDK({
|
|
178
|
+
loaderUrl: './assets/Build/webgl.loader.js',
|
|
179
|
+
dataUrl: './assets/Build/webgl.data.unityweb',
|
|
180
|
+
frameworkUrl: './assets/Build/webgl.framework.js.unityweb',
|
|
181
|
+
codeUrl: './assets/Build/webgl.wasm.unityweb',
|
|
182
|
+
containerId: 'unity-container',
|
|
183
|
+
token: 'your-token',
|
|
184
|
+
env: 'prod'
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
// 初始化数字人
|
|
188
|
+
await sdk.initializeAvatar('avatar001', AvatarCameraType.WHOLE)
|
|
189
|
+
|
|
190
|
+
// 播放动作
|
|
191
|
+
await sdk.playMotion('wave_hand')
|
|
192
|
+
|
|
193
|
+
// 文本播报
|
|
194
|
+
await sdk.startBroadcast({
|
|
195
|
+
type: BroadcastType.TEXT,
|
|
196
|
+
humanCode: 'avatar001',
|
|
197
|
+
text: '欢迎使用 ZEE 3D Avatar SDK',
|
|
198
|
+
voiceCode: 'VOICE001',
|
|
199
|
+
volume: 1.0,
|
|
200
|
+
speed: 1.0,
|
|
201
|
+
isSubtitle: false
|
|
202
|
+
})
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### 错误处理
|
|
206
|
+
```typescript
|
|
207
|
+
try {
|
|
208
|
+
await sdk.initializeAvatar('avatar001')
|
|
209
|
+
} catch (error) {
|
|
210
|
+
if (error instanceof SDKError) {
|
|
211
|
+
console.error('SDK错误:', error.message, '错误码:', error.code)
|
|
212
|
+
} else {
|
|
213
|
+
console.error('系统错误:', error)
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## 🔍 开发调试
|
|
219
|
+
|
|
220
|
+
### 浏览器开发者工具
|
|
221
|
+
- 打开浏览器开发者工具
|
|
222
|
+
- 查看 Console 面板的日志输出
|
|
223
|
+
- 检查 Network 面板的网络请求
|
|
224
|
+
- 使用 Vue DevTools 调试组件状态
|
|
225
|
+
|
|
226
|
+
### 日志系统
|
|
227
|
+
项目内置了完整的日志系统:
|
|
228
|
+
- 实时显示操作日志
|
|
229
|
+
- 按类型区分日志级别
|
|
230
|
+
- 支持日志清理和导出
|
|
231
|
+
|
|
232
|
+
### 常见问题
|
|
233
|
+
1. **Unity 无法加载**:检查 assets 目录是否包含 Unity 构建文件
|
|
234
|
+
2. **Token 认证失败**:确认 Token 配置正确且有效
|
|
235
|
+
3. **播报无声音**:检查音量设置和浏览器音频策略
|
|
236
|
+
4. **类型错误**:确保使用正确的 TypeScript 类型定义
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>ZEE 3D Avatar SDK - Vue3 测试项目</title>
|
|
7
|
+
<meta name="description" content="ZEE 3D Avatar SDK Vue3 + TypeScript + Vite 测试项目" />
|
|
8
|
+
<meta name="keywords" content="ZEE, 3D, Avatar, SDK, Vue3, TypeScript, Vite" />
|
|
9
|
+
<meta name="author" content="ZEEWain" />
|
|
10
|
+
<!-- 样式重置 -->
|
|
11
|
+
<style>
|
|
12
|
+
* {
|
|
13
|
+
margin: 0;
|
|
14
|
+
padding: 0;
|
|
15
|
+
box-sizing: border-box;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
html, body {
|
|
19
|
+
height: 100%;
|
|
20
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
|
21
|
+
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
|
22
|
+
sans-serif;
|
|
23
|
+
-webkit-font-smoothing: antialiased;
|
|
24
|
+
-moz-osx-font-smoothing: grayscale;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
#app {
|
|
28
|
+
height: 100%;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* 加载动画 */
|
|
32
|
+
.loading-container {
|
|
33
|
+
position: fixed;
|
|
34
|
+
top: 0;
|
|
35
|
+
left: 0;
|
|
36
|
+
width: 100%;
|
|
37
|
+
height: 100%;
|
|
38
|
+
background: #f5f5f5;
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
justify-content: center;
|
|
42
|
+
z-index: 9999;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.loading-spinner {
|
|
46
|
+
width: 40px;
|
|
47
|
+
height: 40px;
|
|
48
|
+
border: 4px solid #e0e0e0;
|
|
49
|
+
border-top: 4px solid #409eff;
|
|
50
|
+
border-radius: 50%;
|
|
51
|
+
animation: spin 1s linear infinite;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@keyframes spin {
|
|
55
|
+
0% { transform: rotate(0deg); }
|
|
56
|
+
100% { transform: rotate(360deg); }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.loading-text {
|
|
60
|
+
margin-top: 16px;
|
|
61
|
+
color: #666;
|
|
62
|
+
font-size: 14px;
|
|
63
|
+
}
|
|
64
|
+
</style>
|
|
65
|
+
</head>
|
|
66
|
+
<body>
|
|
67
|
+
<div id="app">
|
|
68
|
+
<!-- 初始加载动画 -->
|
|
69
|
+
<div class="loading-container" id="initial-loading">
|
|
70
|
+
<div>
|
|
71
|
+
<div class="loading-spinner"></div>
|
|
72
|
+
<div class="loading-text">加载中...</div>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
<script type="module" src="/src/main.ts"></script>
|
|
78
|
+
|
|
79
|
+
<!-- 移除初始加载动画 -->
|
|
80
|
+
<script>
|
|
81
|
+
window.addEventListener('load', () => {
|
|
82
|
+
setTimeout(() => {
|
|
83
|
+
const loading = document.getElementById('initial-loading');
|
|
84
|
+
if (loading) {
|
|
85
|
+
loading.style.opacity = '0';
|
|
86
|
+
loading.style.transition = 'opacity 0.3s ease';
|
|
87
|
+
setTimeout(() => {
|
|
88
|
+
loading.remove();
|
|
89
|
+
}, 300);
|
|
90
|
+
}
|
|
91
|
+
}, 500);
|
|
92
|
+
});
|
|
93
|
+
</script>
|
|
94
|
+
</body>
|
|
95
|
+
</html>
|