引言在Unity3D中实现3D角色移动与跳跃有多种实现方式，以下是三种基础的主要实现方式的对比分析和推荐方案：一、组件对比分析1. Transform组件特点：直接修改坐标位置，无物理模拟优点：完全可控的位移，适合简单机制缺点：需要手动处理碰撞，无法与物理系统互动适用场景：2D游戏或不需要物理交互的简单移动2. Rigidbody组件特点：基于物理引擎的刚体模拟优点：自动处理碰撞和重力支持力和速度控制（AddForce）可实现真实的物理效果（如斜坡滑落）缺点：需要调节质量/阻力参数可能出现"滑冰感"适用场景：需要物理交互的3D游戏（如被爆炸冲击波影响）3. Character Controller特点：专为角色设计的非物理移动组件优点：内置斜坡/台阶处理精确控制移动（Move方法）自带碰撞检测（isGrounded）缺点：需要手动处理重力与跳跃逻辑适用场景：平台跳跃类游戏或需要精细控制角色的场景二、推荐方案通常来讲，对于无需玩家操控的物体使用Rigidbody，对于要配合动画进行玩家操作的角色，推荐组合使用 Character Controller1. 移动控制选择// 使用Character Controller示例代码 public class PlayerController : MonoBehaviour { private CharacterController controller; private float verticalVelocity; private bool isJumping; void Start() { controller = GetComponent<CharacterController>(); } void Update() { // 水平移动 Vector3 moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")); moveDirection = transform.TransformDirection(moveDirection); moveDirection *= moveSpeed; // 跳跃逻辑 if (controller.isGrounded) { verticalVelocity = -1f; // 微小向下的力保证接地检测 if (Input.GetButtonDown("Jump")) { verticalVelocity = jumpForce; isJumping = true; animator.SetTrigger("Jump"); // 触发跳跃动画 } } else { verticalVelocity -= gravity * Time.deltaTime; isJumping = false; } moveDirection.y = verticalVelocity; controller.Move(moveDirection * Time.deltaTime); } }2. 动画系统实现Animator Controller设置：创建状态机包含：Idle/Run/Jump/Fall等状态使用混合树(Blend Tree)处理不同移动速度的动画过渡添加参数：Speed（Float）、IsGrounded（Bool）、Jump（Trigger）动画参数更新：// 在Update中更新动画参数 animator.SetFloat("Speed", controller.velocity.magnitude); animator.SetBool("IsGrounded", controller.isGrounded);3. 扩展性设计模块化设计：将移动、跳跃、动画控制拆分为独立脚本动作扩展：// 后续可添加新动作（如翻滚） public void PlayRollAnimation() { animator.SetTrigger("Roll"); // 添加位移逻辑... }使用动画层：通过Animator Layer实现不同身体部位的独立动画（如上半身持枪，下半身奔跑）三、Rigidbody与Character Controller最好只择其一一、为什么建议「二选一」？底层冲突机制：CharacterController 通过Move()方法直接修改坐标Rigidbody 通过物理引擎计算位置同时使用会导致两套系统争夺控制权（例如角色卡顿、穿墙）典型冲突表现：// 错误用法示例：同时操作两种组件 void Update() { controller.Move(moveDir); // 直接修改坐标 rigidbody.AddForce(force); // 物理引擎修改坐标 }可能出现：角色移动抽搐/碰撞失效/重力异常官方文档建议："CharacterController does not require a Rigidbody. In fact, having both may cause undefined behavior."—— Unity官方文档二、是否完全不能组合使用？在特定需求下可以有限组合，但需要遵循以下原则：方案1：Rigidbody作为物理接收器// 组件配置： - CharacterController (主移动) - Rigidbody (IsKinematic = true) // 关闭物理位置计算 // 脚本示例： void OnCollisionEnter(Collision other) { if (other.gameObject.CompareTag("Explosion")) { Vector3 force = CalculateExplosionForce(); rigidbody.isKinematic = false; // 临时启用物理 rigidbody.AddForce(force, ForceMode.Impulse); StartCoroutine(ResetKinematic()); } } IEnumerator ResetKinematic() { yield return new WaitForSeconds(1f); rigidbody.isKinematic = true; // 恢复控制器主导 }适用场景：需要临时受外力影响的剧情事件方案2：物理驱动为主// 组件配置： - Rigidbody (约束Rotation) - CustomMovementScript // 通过AddForce实现移动 void FixedUpdate() { if (isGrounded) { rigidbody.AddForce(moveDir * acceleration); } rigidbody.velocity = Vector3.ClampMagnitude(rigidbody.velocity, maxSpeed); }优势：可实现真实的物理交互（如被车撞飞）代价：需要处理惯性带来的"滑冰感"三、CharacterController如何实现重力？完全不需要Rigidbody，通过手动计算实现：public class GravityHandler : MonoBehaviour { private float verticalSpeed; private const float GRAVITY = 9.81f; void Update() { if (controller.isGrounded) { verticalSpeed = -0.5f; // 微小向下力维持接地状态 } else { verticalSpeed -= GRAVITY * Time.deltaTime; } Vector3 move = new Vector3(0, verticalSpeed, 0); controller.Move(move * Time.deltaTime); } }关键点：接地检测依赖controller.isGrounded重力加速度需手动模拟（建议值：2倍真实重力）四、方案选型决策树graph TD A[是否需要与物理对象互动?] --> |是| B[是否要求精确控制?] A --> |否| C[使用纯CharacterController] B --> |是| D[CharacterController + 事件触发物理] B --> |否| E[纯Rigidbody方案] D --> F[如爆炸时临时启用Rigidbody] E --> G[处理惯性/摩擦力参数]五、最佳实践建议基础移动架构：CharacterControllerAnimatorCustomMovementScript (无Rigidbody)// 移动逻辑：void Update() { HandleMovement(); // 使用Move() HandleGravity(); // 手动重力 HandleJump(); // 自定义跳跃}物理交互实现技巧：方案A：通过CharacterController.Move()模拟受力// 受击退效果示例 public void ApplyKnockback(Vector3 force) { StartCoroutine(KnockbackRoutine(force)); } IEnumerator KnockbackRoutine(Vector3 force) { float duration = 0.5f; while (duration > 0) { controller.Move(force * Time.deltaTime); force = Vector3.Lerp(force, Vector3.zero, 0.1f); duration -= Time.deltaTime; yield return null; } }方案B：临时切换物理控制器private bool isPhysicsActive; void Update() { if (!isPhysicsActive) { // 正常CharacterController移动 } } void ActivatePhysics(Vector3 force) { isPhysicsActive = true; controller.enabled = false; rigidbody.isKinematic = false; rigidbody.AddForce(force); }动画融合技巧：// 在Animator中混合物理动画 animator.SetFloat("FallSpeed", verticalSpeed); // 使用动画遮罩层实现上半身不受物理影响 animator.SetLayerWeight(1, 1.0f); // 第1层控制上半身六、各方案性能对比|指标|纯CharacterController|纯Rigidbody|混合方案||-|-|-|-||CPU占用|低（无物理计算）|中高|中||内存占用|低|中|中||物理交互复杂度|需手动实现|自动|按需切换||移动精度|高|中|高||适合场景|平台跳跃/ACT|沙盒/物理游戏|动作RPG|总结你的原始脚本不需要Rigidbody：之前的重力实现完全可以通过手动计算完成，添加Rigidbody是画蛇添足物理需求的正确实现路径：90%的基础功能：纯CharacterController10%的特殊物理需求：通过协程/临时启用Rigidbody实现扩展建议：使用State Pattern管理不同移动状态（行走/跳跃/受击），每个状态独立处理物理需求四、开发细节分离输入与物理响应，详细可以查看后面新出的文档物理参数调节：重力建议值：根据需求调整，太小可能会很飘跳跃力建议值：4-8（根据角色尺寸调整）移动速度建议值：2-6 m/s动画衔接优化：在动画状态过渡中设置合理的Exit Time和Transition Duration使用动画事件触发脚步声/跳跃音效碰撞检测增强：// 添加底部射线检测提高接地判断精度 if (Physics.Raycast(transform.position + Vector3.up * 0.1f, Vector3.down, 0.2f)) { // 接地处理... }输入优化：// 使用Input System Package实现多设备输入支持 PlayerInput playerInput = GetComponent<PlayerInput>(); Vector2 input = playerInput.actions["Move"].ReadValue<Vector2>();
引言对于网站相关的技术，我并不算了解。大学期间就学过一个 webapp 的制作课程项目，基本上仅限于了解。所以所有的搭建都是基于可视化，低代码的形式实现的。搭建过程在搭建博客时考虑了几种选择，主要为现在最常见的一些选择：WordPress，Halo，Solo，hexo，typecho，poezite主要参考的教程博客Poezit号称最美博客，确实很好看，但是推荐的服务器性能需求在 1H1G最后考虑到我的学习成本，时间成本都不富裕，选择性能较好，搭建方便，有后端的typecho整体搭建非常方便：使用宝塔面板安装常规环境 Nginx1.21 + PHP7.4 + Mysql5.7再直接部署typecho系统+butterfly主题最后进行简单的设置就部署完成辣头像设置引用博客主题头像需要设置两处：显示在首页的左侧边栏中：主题外观设置——初级设置——头像设置，填写图片地址，请确保这个图片地址是没有防盗链的，最简单方式就是在文章编辑页面右侧附件上传图片可以获得图片地址显示在时光机、评论、右上角顶部的头像处：gravatar（全球通用头像），打开后台——控制台——个人设置，点击左侧的头像，去该网站使用你在个人设置里填写的电子邮箱地址注册账号，并上传头像，typecho的头像会自动更新或者打开var/Typecho/Common.php，找到下面的代码，大概在939行，使用本地图片进行替换博客图片来源要想搭建出好看的博客，合适的文章头图是不可缺少的。个人倾向于使用一些acg相关的动画图片，于是选择去各个图库网址寻找个人使用的二次元图库来源：比较精选，类别也不少https://wallpaper.ur1.fun高清精选，可能质量会过高https://www.someacg.top/各种插画，质量还行https://anime-pictures.net/偏向二游相关，质量挺高的，但是预览有水印次元小镇 – 动漫爱好者分享社区ヽ(✿゜▽゜)ノ二次搭建过程此前的服务器到期了，有段时间没有把网站搭上耽误了一段时间，总算是又把网站搭上了新的服务器和域名因为都放在国内，所有还得走备案流程，只能说备案还是比较麻烦的，没什么经营需求的，其实完全可以放在国外服务器上二次搭建使用1panel面板，php8.1恢复备份的时候出了点问题，数据上似乎有点不兼容，相关的附件文件啥的也全都丢失了应该是因为使用1.3版本的typecho，和之前使用的差了一个版本的原因以后恢复备份的时候最好还是保证使用的环境一样比较好，或者干脆进行整个服务器的备份迁移，单独备份博客的数据再恢复还是比较折腾的