# VFS 美术资源对接与场景配置指南 > 给你的美术和场景搭建同学看这份文档,他们就知道要做什么、怎么做、命名规则是什么。 > 你作为项目负责人,拿到美术交付物后,按本文逐项检查即可。 --- ## 一、你需要交付的美术资源清单 ### 1.1 场景模型 | 资源 | 格式 | 要求 | |------|------|------| | 室内田径馆 | FBX/GLB | 包含跑道、看台、跳高架、跳高垫。比例正确(真人 1.7m 对应 Unity 1.7 单位)。Pivot 在地面中心。 | | 跳高架 | FBX/GLB | 可独立放置,带横杆 | | 跳高垫 | FBX/GLB | 软材质效果,1m × 3m × 0.5m | ### 1.2 角色模型 | 资源 | 格式 | 骨骼 | 备注 | |------|------|------|------| | 伤者(男性、运动装) | FBX + 骨骼绑定 | Humanoid,65 根骨骼以内 | Mixamo 自动绑骨亦可,必须带 Humanoid Avatar | | 施救者(女性、急救员装束) | FBX + 骨骼绑定 | Humanoid,65 根骨骼以内 | 同上 | ### 1.3 道具模型 | 资源 | 格式 | 数量 | 备注 | |------|------|------|------| | 急救箱(带红十字) | FBX/GLB | 1 | 可放场景角落,静态物件 | | 绷带/绑带(蓝色) | FBX/GLB | 4 条 | 分段模型,每条独立,绑定到腿时可缩放/旋转 | | 三角巾 | FBX/GLB | 1 | | | 夹板(木板) | FBX/GLB | 2 块 | 内侧夹板 80cm,外侧夹板 120cm | | 衬垫(白色软垫) | FBX/GLB | 2 块 | 放关节和骨突处用 | | 左鞋(运动鞋) | FBX/GLB | 1 | 独立于角色,可被脱掉/隐藏 | | 右鞋(运动鞋) | FBX/GLB | 1 | 同上 | | 8 字绑带(脚踝用) | FBX/GLB | 1 | | ### 1.4 动画(如果做) | 资源 | 时长 | 循环 | 备注 | |------|------|------|------| | 伤者_跑步 | 1s | 是 | | | 伤者_跳高起跳 | 1.5s | 否 | | | 伤者_空中姿态 | 0.8s | 否 | | | 伤者_落地摔倒 | 2s | 否 | 落地→倒地→静止 | | 伤者_躺地(受伤) | 2s | 是 | 最终 Idle | | 施救者_站立 | 1s | 是 | | | 施救者_蹲下 | 1s | 否 | | | 施救者_检查伤情 | 2s | 否 | 手部触摸伤腿 | | 施救者_脱鞋 | 2s | 否 | 手伸向鞋子 | | 施救者_包扎(手部特写) | 3s | 否 | | > 没有动捕可以用 Mixamo 下载基础动画拼接。 ### 1.5 视频 | 资源 | 分辨率 | 时长 | 文件名 | |------|--------|------|--------| | 真人演示·放置衬带 | 1080p | 30s | `bandage_demo.mp4` | | 真人演示·夹板固定 | 1080p | 30s | `splint_demo.mp4` | 放到 `StreamingAssets/Videos/` 下。 ### 1.6 音频(可选) | 资源 | 格式 | 文件名示例 | |------|------|-----------| | 背景音乐 | MP3 320kbps | `bgm_experiment.mp3` | | 语音_环境安全 | WAV 16bit | `voice_01_safe.wav` | | 语音_伤情检查 | WAV 16bit | `voice_02_injury.wav` | | ... | ... | ... | 放到 `StreamingAssets/Voice/` 下。 ### 1.7 UI 素材 | 资源 | 尺寸 | 格式 | 备注 | |------|------|------|------| | 图标_心肺复苏 | 128×128 | PNG 透明 | | | 图标_骨折固定 | 128×128 | PNG 透明 | | | 图标_扭伤包扎 | 128×128 | PNG 透明 | | | 图标_出血包扎 | 128×128 | PNG 透明 | | | 图标_伤员搬运 | 128×128 | PNG 透明 | | | 按钮_全屏 | 64×64 | PNG/SVG | | | 按钮_上一步 | 64×64 | PNG/SVG | | | 按钮_下一步 | 64×64 | PNG/SVG | | | 按钮_返回 | 64×64 | PNG/SVG | | | 按钮_确定 | 200×60 | PNG 含文字 | | | 面板_半透明底 | 可拉伸 9-slice | PNG | | | 提示框背景 | 可拉伸 9-slice | PNG | | --- ## 二、Unity 场景搭建步骤 拿到所有资源后,按以下顺序操作。 ### 2.1 导入资产 1. 将模型 FBX 拖入 `Assets/Models/` 文件夹 2. 将贴图拖入 `Assets/Textures/`(如有) 3. 将视频拖入 `StreamingAssets/Videos/` 4. 将音频拖入 `StreamingAssets/Voice/` 5. 将 UI 图片拖入 `Assets/UI/Sprites/` 6. 将动画 FBX 拖入 `Assets/Animations/` ### 2.2 创建 Experiment 场景 File → New Scene → 命名为 `Experiment` → 保存到 `Assets/Scenes/` ### 2.3 设置光照 - Directional Light:模拟室内顶灯,Intensity 0.8,Color 暖白 (#FFF5E6) - 可选:Light Probe Group 放在场景四角和中心 ### 2.4 放置场景 1. 把田径馆模型拖入 Hierarchy → Position (0, 0, 0) 2. 把跳高架放在跑道区域 → Position 根据模型调整 3. 把跳高垫放在跳高架落地区 ### 2.5 放置角色 1. 伤者 → Hierarchy → Position:躺在跑道上(大致 X:2, Y:0, Z:5) - 初始姿态:仰卧位,身体平放,头朝跑道方向 - 挂 `CharacterAnimController.cs` → Role 选 `Patient` - 挂 `Animator` 组件,配置好动画状态机 2. 施救者 → Position:站在伤者右侧(X:3, Y:0, Z:5) - 挂 `CharacterAnimController.cs` → Role 选 `Rescuer` - 挂 `Animator` 组件 ### 2.6 放置道具 | 道具 | 位置 | 说明 | |------|------|------| | 急救箱 | 伤者身旁地面 (X:3.5, Y:0, Z:4.5) | 静态,无交互 | | 左鞋 | 伤者左脚位置 | 初始穿在脚上,可被隐藏/移动 | | 右鞋 | 伤者右脚位置 | 同上 | | 绑带 ×4 | 急救箱旁 | 之后拖到腿上 | | 衬垫 ×2 | 急救箱旁 | | | 夹板 ×2 | 急救箱旁 | 夹板固定模式用 | | 8 字绑带 | 急救箱旁 | 踝关节固定用 | ### 2.7 最关键:给物体加 Collider 和 Tag **这是代码能找到物体的唯一方式,必须做对。** | GameObject | Collider 类型 | Tag 名称 | 说明 | |------------|-------------|----------|------| | 伤者左大腿 | Box Collider(包裹股骨区域) | `InjuryLeg` | 初始伤情检查点击区域 | | 伤者左大腿·视觉检查区 | Box Collider | `InjuryVisual` | 伤情检查子项 1:肿胀变形 | | 伤者左大腿·肿胀触摸区 | Box Collider | `InjurySwelling` | 伤情检查子项 2:肿胀畸形 | | 伤者胸口 | Box Collider | `InjuryPain` | 伤情检查子项 3:疼痛评估(模拟听诊/询问) | | 伤者手腕 | Box Collider | `InjuryVitalSigns` | 伤情检查子项 4:生命体征(模拟测脉搏) | | 伤者头部 | Box Collider | `InjuryNeuro` | 伤情检查子项 5:神经评估 | | 左鞋 | Box Collider | `Shoe` | 脱鞋步骤 | | 右鞋 | Box Collider | `Shoe` | 同上 | | 绑带位置 1(近心端·大腿上部) | Box Collider | `BandagePos1` | 绑带固定位置 | | 绑带位置 2(远心端·大腿下部) | Box Collider | `BandagePos2` | | | 绑带位置 3(膝关节下) | Box Collider | `BandagePos3` | | | 衬垫位置(两腿间) | Box Collider | `PaddingPos` | 拖拽衬垫吸附目标 | | 踝关节 | Sphere Collider | `Ankle` | 8 字固定 | | 夹板左侧位置 | Box Collider | `SplintLeft` | 夹板拖拽吸附 | | 夹板右侧位置 | Box Collider | `SplintRight` | 夹板拖拽吸附 | | 场景地面 | Box Collider(大面积) | `Ground` | ClickAnywhere 用 | > **Tag 名称必须完全一致**,包括大小写。代码用 `tag == "InjuryLeg"` 匹配。 ### 2.8 给可交互物体加脚本组件 | GameObject | 挂载脚本 | 关键设置 | |------------|---------|---------| | 绑带物件 ×4 | `DraggableObject.cs` | `SnapTarget` 拖入对应的 BandagePos 空物体 | | 衬垫 | `DraggableObject.cs` | `SnapTarget` 拖入 PaddingPos | | 夹板 ×2 | `DraggableObject.cs` | `SnapTarget` 拖入对应夹板位置 | | 伤者左大腿 | `HighlightEffect.cs` | 考核模式可设 AlwaysHighlighted = true | | 所有带 Collider 的交互物体 | `HighlightEffect.cs`(可选) | 悬停时会变色,方便用户找到 | ### 2.9 创建管理器空物体 Hierarchy → Create Empty → 命名为 `[Managers]` 在 `[Managers]` 上依次 Add Component: 1. `GameManager.cs` — 无需配置,Awake 时自动挂载 2. `StepManager.cs` — 后续在 Inspector 拖入 Config 3. `ExperimentFlowCoordinator.cs` — 后续拖入各子系统引用 4. `AudioManager.cs` — 拖入 BGMClip ### 2.10 配置相机 1. 主相机(Main Camera)→ 挂在 `[Managers]` 下或独立 - Position:面对伤者,俯角 30°,距离约 3 米 - 挂载 `InteractionSystem.cs` - `Interactable Mask` 选包含所有交互物体的 Layer 2. 特写相机(可选):用于包扎特写,放在 `ExperimentFlowCoordinator` 里管理 ### 2.11 搭建 UI Canvas Hierarchy → UI → Canvas(命名为 `UICanvas`) **内部结构(父子关系):** ``` UICanvas ├── [挂 UIManager.cs] │ ├── TipPanel(顶部提示栏) │ └── TipText(TMP_Text) │ ├── DetailPanel(详细操作说明面板 · 学习模式) │ └── DetailText(TMP_Text,多行可滚动) │ ├── DialogueBubble(对话气泡) │ └── DialogueText(TMP_Text) │ ├── VideoPanel(画中画视频) │ ├── RawImage(挂 VideoController.cs) │ └── VideoPlayer(子物体或被 VideoController 引用) │ ├── RightButtons(右侧功能按钮栏) │ ├── BtnFullScreen(Button) │ ├── BtnPrevious(Button) │ ├── BtnNext(Button) │ ├── BtnSwitchMode(Button + TMP_Text 标签) │ └── BtnReturn(Button) │ ├── ProgressBar(底部进度条) │ ├── Slider │ └── ProgressText(TMP_Text 显示 "3/8") │ ├── ExamPopup(考核弹窗 · 挂 ExamPopup.cs) │ ├── QuestionText(TMP_Text) │ ├── OptionToggles(Toggle × 4) │ ├── OptionLabels(TMP_Text × 4) │ ├── FeedbackText(TMP_Text 红色) │ ├── OperationPanel(操作题提示) │ │ └── OperationHint(TMP_Text) │ └── ConfirmButton(Button) │ ├── ScoreDisplay(成绩面板 · 挂 ScoreDisplay.cs) │ ├── ExamResultRoot │ │ ├── ScoreTitle(TMP_Text) │ │ ├── ScoreValue(TMP_Text) │ │ └── AnalysisListParent(Scroll View → Content) │ │ └── AnalysisItemPrefab(预制体:TMP_Text) │ ├── NotesRoot(注意事项面板) │ │ └── NotesText(TMP_Text) │ └── ConfirmButton │ └── BottomIcons(底部图标栏) ├── BtnCPR ├── BtnFracture ├── BtnSprain ├── BtnBleeding └── BtnTransport ``` ### 2.12 Inspector 连线 打开 `[Managers]` → `ExperimentFlowCoordinator`,拖入: | 字段 | 拖入对象 | |------|---------| | Step Manager | `[Managers]`(自身的 StepManager) | | Interaction System | Main Camera(自身的 InteractionSystem) | | UI Manager | `UICanvas`(自身的 UIManager) | | Step Animation Handler | `StepAnimationHandler` 所在物体 | | Audio Manager | `[Managers]`(自身的 AudioManager) | 打开 `UICanvas` → `UIManager`,拖入所有子面板引用。 --- ## 三、创建 MainMenu 场景 File → New Scene → 命名为 `MainMenu` → 保存。 ### 3.1 结构 ``` UICanvas ├── [挂 MainMenu.cs] ├── TitleText(TMP_Text:"运动伤害现场急救处理虚拟仿真实验") ├── TipText(TMP_Text:"Tip:请选择实验模式") ├── ExperimentButtons │ ├── BtnCPR(Button + 图标) │ ├── BtnFracture(Button + 图标) │ ├── BtnSprain(Button + 图标) │ ├── BtnBleeding(Button + 图标) │ └── BtnTransport(Button + 图标) ├── ModePanel │ ├── BtnLearnMode(Button) │ ├── BtnExamMode(Button) │ └── SelectedModeLabel(TMP_Text) ├── FixationPanel(骨折固定专属) │ ├── BtnLimbFixation(Button) │ ├── BtnSplintFixation(Button) │ └── SelectedFixationLabel(TMP_Text) └── BtnStart(Button "开始实验") ``` ### 3.2 空物体 Create Empty → 命名 `[GameManager]` → 挂 `GameManager.cs` ### 3.3 连线 MainMenu.cs 的 Inspector 中拖入对应的 Button 和 TMP_Text 引用。 --- ## 四、检查清单(交付前逐项打勾) ### 模型 - [ ] 田径馆模型比例正确 - [ ] 伤者 Humanoid Avatar 配置完成(Inspector → Rig → Animation Type = Humanoid) - [ ] 施救者 Humanoid Avatar 配置完成 - [ ] 所有道具 FBX 正确导入,材质不丢失 ### Collider & Tag - [ ] 伤者左大腿 Collider 覆盖正确区域,Tag = `InjuryLeg` - [ ] 5 个伤情检查子项 Collider 各覆盖正确部位,Tag 正确 - [ ] 鞋子 Collider + Tag = `Shoe` - [ ] 绑带位置 1 2 3 空物体有 Collider + Tag = `BandagePos1/2/3` - [ ] 衬垫位置空物体 Collider + Tag = `PaddingPos` - [ ] 踝关节 Collider + Tag = `Ankle` - [ ] 夹板位置 Collider + Tag = `SplintLeft` / `SplintRight` - [ ] 场景地面 Collider + Tag = `Ground` - [ ] 所有交互物体的 Layer 在 `InteractionSystem.InteractableMask` 范围内 ### 脚本挂载 - [ ] `[Managers]` 挂 GameManager + StepManager + ExperimentFlowCoordinator + AudioManager - [ ] Main Camera 挂 InteractionSystem - [ ] UICanvas 挂 UIManager - [ ] ExamPopup 面板挂 ExamPopup.cs - [ ] ScoreDisplay 面板挂 ScoreDisplay.cs - [ ] VideoPanel 挂 VideoController.cs - [ ] 绑带/衬垫/夹板挂 DraggableObject.cs,SnapTarget 已拖入 ### 连线 - [ ] ExperimentFlowCoordinator 所有字段已拖入 - [ ] UIManager 所有字段已拖入 - [ ] MainMenu 所有字段已拖入 ### ScriptableObject - [ ] `Create → VFS → Step Data` 创建了 8 个步骤(肢体固定)或更多 - [ ] 每个 StepData 的 ScoreWeight 已按评分标准填入(5, 20, 10, 10, 10, 20, 15, 10) - [ ] 每个 StepData 的 DetailedContent 已填入(至少 CheckInjury 步骤) - [ ] `Create → VFS → Experiment Config` 创建了配置 - [ ] LearnStepsLimb / LearnStepsSplint / ExamStepsLimb / ExamStepsSplint 四个数组已填入 - [ ] StepManager.Config 已拖入 ExperimentConfig ### 验证 - [ ] Play 进入 Experiment 场景,UIManager 能显示第一步 Tip 文案 - [ ] 点击伤者大腿 → InteractionSystem 输出 Debug.Log 包含 `Tag=InjuryLeg` - [ ] 考核模式下弹窗正常弹出 - [ ] 答题后 ScoreDisplay 正常显示 --- ## 五、常见问题 **Q:FBX 导入后材质是紫色的?** A:材质丢失。在 FBX 的 Import Settings → Materials → Extract Textures 重新提取。 **Q:骨骼动画播放时角色扭曲?** A:Avatar 未正确配置。Inspector → Rig → Configure Avatar,检查骨骼映射是否正确。 **Q:点击 3D 物体没反应?** A:检查 (1) Collider 是否勾选了 `Is Trigger`(不要勾),(2) Layer 是否在主相机的 Culling Mask 和 InteractionSystem 的 InteractableMask 范围内,(3) Tag 是否正确。 **Q:Canvas 上的 UI 遮挡了 3D 点击?** A:InteractionSystem 已内置 `IsPointerOverGameObject()` 检测,不会同时触发。确保 Canvas 的 Graphic Raycaster 正常工作。 **Q:成绩显示 0 分?** A:检查 StepData 的 ScoreWeight 是否已填入非 0 值,考核模式下 `RecordExamResult` 的 proportion 参数是否传了 1f。