You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Unity CharacterController实现类似Rigidbody AddForce的击退效果?

用CharacterController复刻AddForce效果的实现方案

CharacterController本身不依赖Unity物理引擎的刚体受力系统,要实现类似AddForce()的效果,核心是手动模拟力的积累、衰减(阻力)以及速度叠加逻辑,以下是具体实现方案:

核心思路

  • 维护一个Vector3 forceVelocity变量,专门存储外力(比如击退)产生的速度分量
  • 施加力时,根据力的类型(冲量/持续力等)给forceVelocity叠加对应的速度变化量
  • 每一帧对forceVelocity应用阻力,让外力效果逐渐衰减
  • 最终将玩家基础移动速度与forceVelocity叠加,传入CharacterController.Move()完成运动

完整代码示例

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [Header("基础移动配置")]
    public float moveSpeed = 5f;
    public CharacterController controller;

    [Header("外力模拟配置")]
    public float mass = 1f; // 模拟刚体质量,值越大,相同力产生的速度越小
    public float drag = 0.9f; // 阻力系数,越接近0衰减越快,越接近1衰减越慢
    private Vector3 forceVelocity;

    void Update()
    {
        // 1. 处理玩家基础移动
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");
        Vector3 moveDir = transform.right * horizontal + transform.forward * vertical;
        Vector3 baseVelocity = moveDir.normalized * moveSpeed;

        // 2. 更新外力速度的衰减
        forceVelocity *= drag;
        // 消除微小速度残留,避免无意义的持续移动
        if (forceVelocity.magnitude < 0.01f)
            forceVelocity = Vector3.zero;

        // 3. 叠加所有速度,驱动CharacterController移动
        Vector3 finalVelocity = baseVelocity + forceVelocity;
        controller.Move(finalVelocity * Time.deltaTime);
    }

    // 复刻Rigidbody.AddForce的功能
    public void AddForce(Vector3 force, ForceMode forceMode = ForceMode.Force)
    {
        switch (forceMode)
        {
            case ForceMode.Force:
                // 模拟持续力:F=ma → 速度增量为(force/mass)*Δt
                forceVelocity += force / mass * Time.deltaTime;
                break;
            case ForceMode.Impulse:
                // 模拟瞬间冲量:直接叠加速度增量(force/mass),忽略时间
                forceVelocity += force / mass;
                break;
            case ForceMode.VelocityChange:
                // 直接改变速度,忽略质量
                forceVelocity += force;
                break;
            case ForceMode.Acceleration:
                // 直接叠加加速度,忽略质量:速度增量为force*Δt
                forceVelocity += force * Time.deltaTime;
                break;
        }
    }

    // 示例:调用击退效果(被攻击时触发)
    public void ApplyKnockback(Vector3 knockbackDir, float knockbackForce)
    {
        AddForce(knockbackDir.normalized * knockbackForce, ForceMode.Impulse);
    }
}

关键细节说明

  • ForceMode适配:代码实现了Unity Rigidbody的四种力模式,击退效果一般用ForceMode.Impulse(瞬间冲量)更符合手感
  • 参数调优:mass控制玩家对力的敏感程度,drag控制外力效果的持续时间,可根据游戏手感灵活调整
  • 速度叠加逻辑:外力速度与基础移动速度直接叠加,和Rigidbody的行为一致——比如玩家移动时被击退,会产生斜向运动轨迹
  • 重力处理:如果需要模拟重力,可在finalVelocity中加入Physics.gravity * Time.deltaTime,或直接使用CharacterController自带的重力计算

内容的提问来源于stack exchange,提问作者Pope's_chicken_army

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 02:01:11