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

Unity2D玩家受击击退失效问题求助(无需布尔值方案)

解决Unity2D玩家受击击退被移动逻辑覆盖的问题

问题背景

开发Unity2D游戏时,玩家通过左右按键实现水平移动(由PlayerController脚本控制),右侧生成的邪恶蘑菇敌人(由MushroomMovement脚本控制)碰撞玩家时会施加击退效果。当前问题:启用PlayerController后,击退效果几乎完全失效,仅出现微小垂直抖动;禁用该脚本后击退效果正常。

问题根源

PlayerController的FixedUpdate帧中,playerRb.velocity = new Vector2(horizontalInput * movementSpeed, playerRb.velocity.y);语句会强制重置玩家水平方向的速度。玩家受击时击退逻辑修改了velocity,但下一帧就被该语句覆盖,导致击退效果被抵消。

非布尔值解决方案

核心思路:仅在玩家有主动水平输入时,才覆盖水平方向速度;无输入时保留当前水平速度(包括击退带来的速度),避免强制重置覆盖击退效果。

修改PlayerController的FixedUpdate方法,将原本直接赋值水平速度的逻辑,改为判断是否有输入后再执行:

修改后的PlayerController.cs

public class PlayerController : MonoBehaviour
{
    private Rigidbody2D playerRb;
    public float movementSpeed;
    private float horizontalInput;
    private bool isGrounded;
    public float jumpForce = 5f;
    private Animator playerAnimator;

    void Start()
    {
        playerRb = GetComponent<Rigidbody2D>();
        playerAnimator = transform.Find("Visuals").GetComponent<Animator>();
    }

    void Update()
    {
        horizontalInput = Input.GetAxisRaw("Horizontal");
    }

    void FixedUpdate()
    {
        // 仅当玩家有主动水平输入时,才设置移动速度
        if (horizontalInput != 0)
        {
            playerRb.velocity = new Vector2(horizontalInput * movementSpeed, playerRb.velocity.y);
        }
        // 无输入时保留当前水平速度(包括击退速度)

        bool isMoving = (horizontalInput != 0);
        playerAnimator.SetBool("isMoving", isMoving);

        if (Input.GetKey(KeyCode.UpArrow) && isGrounded)
        {
            isGrounded = false;
            playerRb.velocity = new Vector2(playerRb.velocity.x, jumpForce);
        }
    }

    void OnCollisionEnter2D(Collision2D other)
    {
        if (other.gameObject.CompareTag("Ground"))
        {
            isGrounded = true;
        }
    }
}

方案优势

  • 无需引入isKnockBacked等状态布尔值,保持代码简洁
  • 玩家在击退过程中仍可通过按键主动控制移动,不会被强制禁用操作
  • 完全保留原本的移动逻辑和击退逻辑,仅调整速度赋值的触发条件

补充说明

如果需要让击退效果和玩家输入有更自然的交互(比如玩家输入可以抵消部分击退),可以进一步修改为基于输入的速度平滑过渡,调整移动速度和击退力的数值平衡:

// 替代上面的if判断逻辑
float targetHorizontalVelocity = horizontalInput * movementSpeed;
// 平滑过渡当前速度到目标速度,保留击退的惯性
playerRb.velocity = new Vector2(
    Mathf.Lerp(playerRb.velocity.x, targetHorizontalVelocity, Time.fixedDeltaTime * 5f),
    playerRb.velocity.y
);

这种方式会让玩家输入逐渐覆盖击退速度,交互更平滑,可根据实际游戏手感调整插值系数。

内容的提问来源于stack exchange,提问作者user21909947

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 05:27:05