Unity 虚拟美术馆漫游系统

Unity 虚拟美术馆漫游系统 ​虚拟美术馆项目在Virtual art space Volume下Demo是场景展示Player脚本在脚本中通过chracter controller 控制移动​​​​​​​​​​​​​​​​​​​​​代码依靠CharacterController 相机朝向实现跟着镜头方向走WASD 前后左右。1. 获取输入方向floathorizontalInput.GetAxis(Horizontal);// A/D、左右箭头-1 ~ 1floatverticalInput.GetAxis(Vertical);// W/S、上下箭头-1 ~ 1Horizontal左右轴A-1、D1、无按键0Vertical前后轴W1、S-1、无按键0这一步拿到玩家按键的偏移值。2. 对齐相机方向关键跟着镜头走Vector3cameraForwardcameraTransform.forward;cameraForward.y0f;// 去掉上下俯仰只保留水平方向cameraForward.Normalize();// 单位化保证移动速度均匀Vector3cameraRightcameraTransform.right;cameraRight.y0f;cameraRight.Normalize();cameraTransform.forward相机正前方把y置0 忽略高低只算水平面不会往天上/地下走Normalize()把方向向量长度固定为1避免斜着走速度变快。3. 合成最终移动方向Vector3movecameraForward*verticalcameraRight*horizontal;公式理解相机前方向 × 前后按键(W/S) 相对镜头前后相机右方向 × 左右按键(A/D) 相对镜头左右两者相加得到基于相机视角的整体移动方向。4. 执行移动核心运动函数controller.SimpleMove(move*moveSpeed);move * moveSpeed方向 × 移动速度算出最终移动矢量CharacterController.SimpleMove()自带重力、碰撞检测直接让角色沿目标方向移动不用自己算位移。usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;// 相机控制脚本实现第三人称跟随、鼠标旋转视角、滚轮缩放、点击交互publicclassPlayerCamera:MonoBehaviour{[Header( 相机跟随目标 )]publicTransformplayerTarget;// 要跟随的玩家对象[Header( 鼠标视角控制 )]publicfloatmouseSensitivity2f;// 鼠标灵敏度publicfloatminYAngle-20f;// 视角向下最大俯角publicfloatmaxYAngle80f;// 视角向上最大仰角publicfloattargetHeight1.5f;// 相机看向玩家的高度头顶/胸口privatefloatmouseX;// 存储鼠标左右旋转值水平privatefloatmouseY;// 存储鼠标上下旋转值垂直[Header( 相机距离缩放)]publicfloatcurrentDistance3f;// 当前相机与玩家的距离privatefloatzoomSpeed2f;// 滚轮缩放速度privatefloatminDistance1f;// 最近缩放距离privatefloatmaxDistance5f;// 最远缩放距离[Header( UI 交互对象 )]publicGameObjectQuestionsCanvas;// 问题UI面板publicGameObjectDeepSeekCanvas;// 对话UI面板publicGameObjectDrawCanvas;// 绘画UI面板privateCanvasShowArtMessageartUI;// 显示艺术信息的UI脚本引用voidStart(){// 1. 如果没有手动指定玩家自动通过标签寻找Playerif(playerTargetnull){GameObjectplayerGameObject.FindGameObjectWithTag(Player);if(player!null){playerTargetplayer.transform;}}// 2. 游戏开始时锁定鼠标隐藏光标FPS/第三人称常用Cursor.lockStateCursorLockMode.Locked;Cursor.visiblefalse;// 3. 找到场景中的艺术信息UI脚本artUIFindObjectOfTypeCanvasShowArtMessage();}// LateUpdate所有Update执行完后再执行保证相机跟随更平滑不卡顿voidLateUpdate(){// 没有跟随目标直接退出防止报错if(playerTargetnull)return;// 处理鼠标显示/隐藏LeftAlt切换HandleCursorLock();// 只有在光标隐藏时才允许旋转视角if(!Cursor.visible){HandleMouseInput();}// 鼠标左键点击交互HandleClick();// 鼠标滚轮缩放HandleZoom();// 更新相机位置和角度UpdateCameraPosition();}// 功能鼠标左键点击物体触发UI显示voidHandleClick(){// 检测鼠标左键按下if(Input.GetMouseButtonDown(0)){// 从相机发射一条射线到鼠标点击的位置RayrayCamera.main.ScreenPointToRay(Input.mousePosition);RaycastHithit;// 如果射线碰到了物体if(Physics.Raycast(ray,outhit)){if(artUI!null){// 根据点击物体的名称打开对应的UI面板if(hit.collider.gameObject.nameWorldQuestionsCanvas){QuestionsCanvas.SetActive(true);}elseif(hit.collider.gameObject.nameWorldDeepSeekCanvas){DeepSeekCanvas.SetActive(true);}elseif(hit.collider.gameObject.nameWorldDrawCanvas){DrawCanvas.SetActive(true);}// 点击其他物体 → 显示对应的艺术介绍else{artUI.ShowArtByName(hit.collider.gameObject.nameArt);}}}}}// 功能按 Left Alt 键 切换鼠标显示/隐藏voidHandleCursorLock(){if(Input.GetKeyDown(KeyCode.LeftAlt)){if(Cursor.visible){// 隐藏光标 锁定到屏幕中心Cursor.lockStateCursorLockMode.Locked;Cursor.visiblefalse;}else{// 显示光标 解锁Cursor.lockStateCursorLockMode.Locked;Cursor.visibletrue;}}}// 功能获取鼠标输入计算旋转角度voidHandleMouseInput(){// 水平旋转鼠标左右移动 累加mouseXInput.GetAxis(Mouse X)*mouseSensitivity;// 垂直旋转鼠标上下移动 累加减号反转Y轴符合正常操作习惯mouseY-Input.GetAxis(Mouse Y)*mouseSensitivity;// 限制垂直视角角度防止相机翻到角色底下或天上mouseYMathf.Clamp(mouseY,minYAngle,maxYAngle);}// 功能鼠标滚轮控制相机远近缩放voidHandleZoom(){// 获取滚轮输入floatscrollInput.GetAxis(Mouse ScrollWheel);// 调整相机距离currentDistance-scroll*zoomSpeed;// 限制距离在最大/最小范围内currentDistanceMathf.Clamp(currentDistance,minDistance,maxDistance);}// 核心功能计算相机最终位置 旋转让相机环绕玩家voidUpdateCameraPosition(){// 相机跟随的目标点玩家位置 向上偏移高度Vector3targetPositionplayerTarget.positionVector3.up*targetHeight;// 将鼠标的X、Y值转为旋转角度QuaternionrotationQuaternion.Euler(mouseY,mouseX,0);// 相机向后移动的距离沿着相机自身的Z轴后退Vector3negDistancenewVector3(0.0f,0.0f,-currentDistance);// 计算相机最终位置目标点 旋转后的后退位置Vector3desiredPositiontargetPositionrotation*negDistance;// 应用旋转和位置 → 相机完成跟随视角旋转transform.rotationrotation;transform.positiondesiredPosition;}}game这里固定为1920*1080 。角色动画Player中有了角色动画资源如何使用播放行走动作在Player脚本中使用角色动画资源定义动画组件privateAnimationanimation1;这是 Unity旧版动画系统 Animation 组件角色身上已经挂载了这个组件并放入走路动画名字叫walk待机动画名字叫wait代码在哪里初始化动画让脚本找到角色身上的 Animation 组件以后可以用代码控制它。voidStart(){animation1GetComponentAnimation();}核心如何判断播放什么动画代码用move移动量(move前面已经解释过是一个Vector3方向向量) 来判断角色是在走还是站着, magnitude是模长if(move.magnitude0.1f)// 如果正在移动{animation1.Play(walk);// 播放走路动画}else// 如果没移动{animation1.Play(wait);// 播放待机动画}最关键的一句动画是怎么播放的播放 Animation 组件里名字叫 walk 的动画片段。animation1.Play(walk);同理播放名字叫wait的动画。animation1.Play(wait);当游戏运行时按住左ALT键可以显示鼠标。