Unity开发过程中的解决方案(自用)
Gitee仓库相关问题克隆远程仓库失败问题仓库中包含 Git LFS 对象但你的 Gitee 免费账户无法下载它们可以通过禁用LFS解决# 1. 先删除这个克隆失败的目录 # 2. 配置 Git 禁用 LFS关键步骤 git config --global filter.lfs.smudge git-lfs smudge --skip git config --global filter.lfs.process git-lfs filter-process --skip git config --global filter.lfs.required false # 3. 重新克隆 git clone gitgitee.com:*********.git自定义类排序将自定义类继承接口 IComparable自定义泛型随后在自定义类中写入比较逻辑public int CompareTo(自定义类 other){if(this.比较的属性 other.比较的属性){return 1;}else{return -1;}}随后使用List泛型进行排序List自定义类 list new List自定义类();list.Sort();相机跟随在package manager中搜索cinemachine选择较高版本安装(如2.10.3)安装成功后在场景右键可看到出现了新的选项cinemachine选择virtual camera(过程中不要选择其他相机否则可能会让主相机多一些组件让virtual camera异常)将跟随目标放入follow中切换body的模式transposer(跟随目标) - framing transposer(将目标作为视觉中心并跟随目标)切换aim模式pov用于控制相机的旋转将水平和竖直的speed选项从max speed切换为input value gain自定义速度并将速度调整(建议为10)垂直旋转的范围可以选择0-80(防止视角进入地下)使用 Cinemachine Collider 扩展可以实现相机避开障碍物在Virtual Camera的Inspector中点击 Add Extension 按钮选择 Cinemachine Collide。选中所有会遮挡相机的墙壁、柱子等物体在Inspector顶部将它们的Layer设为“Obstacle”。在Collider组件的 Collide Against 属性中只勾选你刚刚创建的“Obstacle”层。角色移动角色移动的常用方法角色移动的制作方式有多种如直接修改物体position、使用刚体组件中的矢量velocity属性、addforce等。使用矢量velocity作为移动方式角色移动代码要写在fixedupdate(每0.02s调用)中若在update中(每帧调用)会因为设备问题导致多人情况下移速有差距moveDirection (mainCamare.transform.forward * moveZ) (mainCamare.transform.right * moveX);//当使用主相机视角作为正反向时可以使用该代码rb.velocity new Vector3(moveDirection.x * speed, rb.velocity.y, moveDirection.z * speed);//改变矢量移动要考虑全面如考虑受重力影响所以矢量的y轴依然不变角色移动的常见误区第三人称相机视角由于相机仰俯角度会对向量长度产生影响导致仰俯角的速度不同需要排除相机角度对移动的干扰。代码可以优化为if (moveDirection.magnitude 0.1f){moveDirection new Vector3(moveDirection.x, 0, moveDirection.z).normalized;}rb.velocity new Vector3(moveDirection.x * speed, rb.velocity.y, moveDirection.z * speed);角色跳跃使用刚体velocity制作跳跃时注意跳跃过程中取消角色移动中对矢量的控制rb.velocity new Vector3(rb.velocity.x, 0f, rb.velocity.z);//保证每次跳跃时初速一致rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);跳跃检测isGrounded Physics.Raycast(transform.position, Vector3.down, groundCheckDistance, groundLayer);if (Input.GetKeyDown(KeyCode.Space) isGrounded){Jump();}else if (!isGrounded){isJumping true;}else if(isGrounded){isJumping false;}地面检测与斜坡问题使用了盒子碰撞检测确定是否碰撞地面使用了多个射线检测确定脚下坡度给角色脚下设置一个有物理摩擦材质的碰撞体专门与斜坡交互遇到较大斜坡设置摩擦力为0并将角色状态设置为下坠状态(有限状态机)。这样既能做到碰撞墙体不会因为摩擦力而移动异常又能专门针对斜坡坡度表现不同状态。FootFlag.cs · 蓝色大鸭鸭/ToolSet - Gitee.com角色面朝方向改变void Turn(Vector3 moveDir){Quaternion targetRotation Quaternion.LookRotation(moveDir);float step rotateSpeed * Time.fixedDeltaTime;Quaternion newRotation Quaternion.RotateTowards(rb.rotation, targetRotation, step);rb.MoveRotation(newRotation);}if (moveDirection.magnitude 0.1f)//调用位置{Turn(moveDirection);}角色移动优化加速度减速度平滑移动该方法需要移动方向void SmoothMove(){targetVelocity moveDirection * moveSpeed;Vector3 currentHorizontalVel new Vector3(rb.velocity.x, 0, rb.velocity.z);float targetSpeed targetVelocity.magnitude;if (targetSpeed 0.1f) // 有输入{// 方案A保持当前方向的动量逐渐转向目标方向if (currentHorizontalVel.magnitude 0.1f){// 逐渐旋转当前速度方向到目标方向Vector3 newDirection Vector3.RotateTowards(currentHorizontalVel.normalized,targetVelocity.normalized,turnSmoothness * Time.fixedDeltaTime,1f);// 逐渐加速到目标速度float newSpeed Mathf.MoveTowards(currentHorizontalVel.magnitude,targetSpeed,acceleration * Time.fixedDeltaTime);rb.velocity new Vector3(newDirection.x * newSpeed,rb.velocity.y,newDirection.z * newSpeed);}else{// 从静止启动直接设置小速度避免突变rb.velocity new Vector3(targetVelocity.x * 0.3f, // 从30%速度开始rb.velocity.y,targetVelocity.z * 0.3f);}}else // 无输入{// 缓慢减速而不是立即停止if (currentHorizontalVel.magnitude 0.01f){// 保持当前方向缓慢减速float newSpeed Mathf.MoveTowards(currentHorizontalVel.magnitude,0f,deceleration * Time.fixedDeltaTime);rb.velocity new Vector3(currentHorizontalVel.normalized.x * newSpeed,rb.velocity.y,currentHorizontalVel.normalized.z * newSpeed);}}}动画系统animator组件该组件是动画的放映器它通过获取animator controller动画控制器和avatar骨骼映射让对应的模型动起来该组件的其他参数设置也极为重要animator controller文件动画的核心控制器用于集合各个动画动作并建立动画之间的联系是控制动画逻辑的核心。animation-animator窗口用于编辑animator controller形式为有限状态机单个translation的关联条件需要同时满足才能切换动画想要达成or的效果可以再制作一个translation物理跳跃 动画位移 双重跳跃1. 在Project窗口中找到你的角色模型FBX文件 2. 点击展开找到Jump动画剪辑 3. 选中Jump动画剪辑 4. 在Inspector中找到 Animations 选项卡 5. 找到 Root Transform 部分 6. 设置 - ✅ Root Transform Rotation: 根据你的需求 - ❌ Root Transform Position (Y): 取消勾选 Bake Into PoseAnyState重复进入动画问题anystate的每个translation都需要三个参数才能正常应用1、确认自身状态参数(int)根据不同状态选择进入对应的状态2、优先级参数(int)anystate应用的优先级参数各不相同如idle、walk参数为最低受击参数较高3、触发器参数(trigger)防止当前两个参数满足时不断循环进入一个动画导致抽搐战斗系统近战武器攻击检测给武器创造一个碰撞体或者设置角色的攻击范围作为碰撞体将其设置为触发器用于检测敌人给武器创建一个碰撞检测脚本使用OnTriggerEnter检测other.tag用于对攻击到的敌人进行处理当角色处于攻击状态时将碰撞体的enabled设置为true其余情况设置为false避免已经接触到敌人但并未攻击导致的攻击不触发情况敌人AI敌人寻路常用有两种寻路分别是A星寻路和unity中的NavMesh插件A星寻路适用于2D游戏且不可动态避障NavMesh适用于3D且能够动态避障2022以下版本可以在window-ai中直接找到22以上版本想要在package manager中下载NavMesh包括导航网格NavMesh(数据文件存放地形数据)导航网格代理NavMesh Agent(用于导航目标起点的组件)网格外链接Off-Mesh Link(用于特殊路径的组件如传送点、桥梁)导航网格障碍物Nav Mesh Obstacle(用于障碍物的组件)NavMesh基本属性Object用于管理场景上的对象mesh renderers用于筛选对象的网格navigation static用于控制对象是否是静态的(勾选之后才可烘焙)generate offmeshlinks用于生成网格连接点开关(如传送点、跳跃点、可掉落点)navigation area区域选择配合areas页签使用bake用于烘焙当前状态下的场景烘焙的文件默认在sence文件夹中。agent radius控制烘焙边缘的精确度值越小烘焙越精确损耗也更改。agent height控制烘焙高度的精确度值越小烘焙范围越大适用于控制拱桥场景。max slope控制可行走斜坡的最大度数。step height控制能行走楼梯的最大高度。drop height决定可以掉落的高度需勾选object-generate offmeshlinks使用。jump distance决定两个平台间可以跳跃的高度也需勾选object-generate offmeshlinks使用。manual voxel size表示生成网格的像素大小值越小越精确但内存和构建时间也会增加一般不建议修改。min region area表示最小可烘焙的区域大小。height mesh用于精确控制楼梯烘焙一般不勾选。决定寻路的优先级数字越小优先级越高NavMesh Agent官方手册导航网格代理 (NavMesh Agent) - Unity 手册部分重要属性Radius代理的半径用于计算障碍物与其他代理之间的碰撞。Stopping distance当靠近目标位置的距离达到此值时代理将停止。Auto Braking启用此属性后代理在到达目标时将减速。对于巡逻等行为这种情况下代理应在多个点之间平滑移动应禁用此属性寻路制作//生成随机位置Vector3 GetRandomPosition(){do{virtualPosition new Vector3(Random.Range(startingPosition.x - moveScope, startingPosition.x moveScope),startingPosition.y,Random.Range(startingPosition.z - moveScope, startingPosition.z moveScope));} while (Vector3.Distance(virtualPosition, transform.position) minDistance);return virtualPosition;}//更新目标点void EnemyWander(){if (WanderingPosition null){WanderingPosition GetRandomPosition();}if (meshAgent.remainingDistance 1f){WanderingPosition GetRandomPosition();meshAgent.destination WanderingPosition;}}敌人索敌追击当玩家处于敌人一定范围且在敌人前方时触发战斗状态给敌人一个子物体并添加一个圆的碰撞体并设置为触发器用于范围检测玩家给layer添加两个层级一个是player一个是EnemySensor分别给两个物体替换layer。在Physics设置中将EnemySensor的目标只设置为player如下设置Fov(float)为敌人检测视野angle为进入检测范围的玩家与敌人正前方的夹角float angle Vector3.Angle(currentEnemyAI.transform.forward, (playerPositon - currentEnemyAI.transform.position));当angle currentEnemyAI.Fov / 2且玩家在追击范围内时进入战斗状态currentEnemyAI.meshAgent.stoppingDistance设置盘旋距离让敌人不会与角色贴脸将战斗状态分为几个小状态如追击状态、盘旋状态、站立状态触发器检测玩家进入追击状态后将寻路目标设为玩家靠近玩家后进入盘旋状态远离玩家后进入归位状态相机切换unity中使用cinemachine相机切换有多种解决方案如激活目标相机禁用当前相机、设置修改Cinemachine Brain相机权重、使用Cinemachine State Driven Camera管理相机等。以下介绍Cinemachine State Driven Camera使用。