Unity中如何将Character Controller转为Rigidbody移动并复用现有脚本?
3D横版平台角色踩移动平台不跟随问题:CharacterController转Rigidbody适配方案
问题背景
我正在制作一款3D横版平台游戏,角色踩在移动平台上时无法随平台一同移动。打算将Character Controller替换为Rigidbody解决该问题,需要把现有Character Controller脚本适配到Rigidbody上,原代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerController : MonoBehaviour { public CharacterController controller; private Vector3 direction; public float speed = 8; public float jumpForce = 30; public float gravity = -20; public Transform groundCheck; public LayerMask groundLayer; public bool ableToMakeADoubleJump = true; public Animator animator; public Transform model; void Start() { } // Update is called once per frame void Update() { if (PlayerManager.gameOver) { //play death animation animator.SetTrigger("die"); //disable the script this.enabled = false; } float hInput = Input.GetAxis("Horizontal"); direction.x = hInput * speed; animator.SetFloat("speed", Mathf.Abs(hInput)); bool isGrounded = Physics.CheckSphere(groundCheck.position, 0.15f, groundLayer); animator.SetBool("isGrounded", isGrounded); if (isGrounded) { //Jump Codes ableToMakeADoubleJump = true; if (Input.GetButtonDown("Jump")) { Jump(); } } else { direction.y += gravity * Time.deltaTime; if (ableToMakeADoubleJump & Input.GetButtonDown("Jump")) { DoubleJump(); } } if (hInput != 0) { Quaternion newRoattion = Quaternion.LookRotation(new Vector3(hInput, 0, 0)); model.rotation = newRoattion; } //Move the player using the character controller controller.Move(direction * Time.deltaTime); } private void DoubleJump() { //Double Jump Codes animator.SetTrigger("doubleJump"); direction.y = jumpForce; ableToMakeADoubleJump = false; } private void Jump() { direction.y = jumpForce; } }
适配后的Rigidbody版本代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerController : MonoBehaviour { private Rigidbody rb; private float horizontalInput; public float speed = 8; public float jumpForce = 30; public float gravity = -20; public Transform groundCheck; public LayerMask groundLayer; public bool ableToMakeADoubleJump = true; public Animator animator; public Transform model; void Start() { // 获取Rigidbody组件并初始化设置 rb = GetComponent<Rigidbody>(); rb.useGravity = false; // 关闭内置重力,用自定义逻辑模拟 rb.freezeRotation = true; // 锁定旋转,防止角色物理倾倒 } void Update() { if (PlayerManager.gameOver) { animator.SetTrigger("die"); this.enabled = false; return; } horizontalInput = Input.GetAxis("Horizontal"); animator.SetFloat("speed", Mathf.Abs(horizontalInput)); bool isGrounded = Physics.CheckSphere(groundCheck.position, 0.15f, groundLayer); animator.SetBool("isGrounded", isGrounded); // 输入响应逻辑保留在Update,保证操作及时反馈 if (isGrounded) { ableToMakeADoubleJump = true; if (Input.GetButtonDown("Jump")) { Jump(); } } else { if (ableToMakeADoubleJump && Input.GetButtonDown("Jump")) { DoubleJump(); } } // 角色转向逻辑 if (horizontalInput != 0) { Quaternion newRotation = Quaternion.LookRotation(new Vector3(horizontalInput, 0, 0)); model.rotation = newRotation; } } // 物理相关逻辑移到FixedUpdate,保证物理计算稳定性 void FixedUpdate() { bool isGrounded = Physics.CheckSphere(groundCheck.position, 0.15f, groundLayer); // 处理水平移动 Vector3 currentVelocity = rb.velocity; currentVelocity.x = horizontalInput * speed; // 手动模拟重力 if (!isGrounded) { currentVelocity.y += gravity * Time.fixedDeltaTime; } else { // 地面状态下保持轻微向下的速度,避免角色浮空或陷入地面 currentVelocity.y = -0.5f; } rb.velocity = currentVelocity; } private void DoubleJump() { animator.SetTrigger("doubleJump"); rb.velocity = new Vector3(rb.velocity.x, jumpForce, rb.velocity.z); ableToMakeADoubleJump = false; } private void Jump() { rb.velocity = new Vector3(rb.velocity.x, jumpForce, rb.velocity.z); } }
关键改动说明
- 组件替换:移除
CharacterController,给角色添加Rigidbody组件,关闭内置重力并锁定旋转,避免物理行为异常 - 逻辑拆分:输入检测和动画控制保留在
Update,物理移动逻辑移到FixedUpdate,符合Unity物理更新的最佳实践 - 移动控制:直接修改Rigidbody的
velocity属性控制水平移动,替代原controller.Move()方法 - 重力与跳跃:手动模拟重力叠加,跳跃时直接设置y轴速度,保持原有的跳跃和二段跳手感
- 平台跟随:只要移动平台设置了
Rigidbody并设为Kinematic(或通过MovePosition移动),Rigidbody角色会自动和平台产生物理交互,实现跟随效果
内容的提问来源于stack exchange,提问作者Lightning21Cheetah
相关产品推荐
相关产品推荐

