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

Unity2D技术问题:输入归零时停止移动,保留角色朝向

解决Unity2D角色控制器输入归零时持续移动的问题

嘿,我明白你现在的困扰——当玩家停止输入后,角色还沿着最后方向一直走,动画也停不下来对吧?咱们来定位问题并修复它:

问题根源

你当前的代码里,当输入归零时(moveDirection == Vector2.zero),把moveDirection替换成了lastMoveDirection,这就导致FixedUpdate里一直用这个保存的方向来移动角色,自然停不下来。同时,动画的PlayerMoving参数也是基于moveDirection是否为零判断,所以一直处于行走状态。

修复方案

我们需要把移动控制和朝向/动画状态分开处理:

  • 有输入时,正常移动并记录最后朝向
  • 无输入时,停止移动,但保留最后朝向给动画使用

修改后的完整代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class PlayerController : MonoBehaviour
{
    public float moveSpeed = 5.0f;
    private Vector2 moveDirection;
    private Vector2 lastMoveDirection = Vector2.down; // 默认初始朝向,可根据需求修改
    private Rigidbody2D rb;
    private Animator anim;
    private static bool playerExists;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();

        if (!playerExists)
        {
            playerExists = true;
            DontDestroyOnLoad(transform.gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }

    void Update()
    {
        // 初始化移动方向为零
        moveDirection = Vector2.zero;

        // 处理键盘输入
        moveDirection = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));

        // 处理触屏输入
        if (Input.touchCount > 0)
        {
            Touch touch = Input.GetTouch(0);
            // 重置方向,避免键盘+触屏同时输入冲突
            moveDirection = Vector2.zero;
            if (touch.position.x < Screen.width / 2)
                moveDirection.x = -1;
            else
                moveDirection.x = 1;

            if (touch.position.y < Screen.height / 2)
                moveDirection.y = -1;
            else
                moveDirection.y = 1;
        }

        // 限制斜向输入,只保留水平或垂直方向
        if (Mathf.Abs(moveDirection.x) > Mathf.Abs(moveDirection.y))
            moveDirection.y = 0;
        else
            moveDirection.x = 0;

        // 记录最后朝向(只有当有输入时才更新)
        if (moveDirection != Vector2.zero)
        {
            lastMoveDirection = moveDirection;
        }

        // 设置动画参数:用lastMoveDirection保持朝向,用moveDirection判断是否在移动
        anim.SetFloat("MoveX", lastMoveDirection.x);
        anim.SetFloat("MoveY", lastMoveDirection.y);
        anim.SetBool("PlayerMoving", moveDirection != Vector2.zero);
    }

    void FixedUpdate()
    {
        // 只有当moveDirection不为零时才移动
        rb.MovePosition(rb.position + moveDirection * moveSpeed * Time.fixedDeltaTime);
    }
}

关键修改点说明

  1. 初始化moveDirection为零:每次Update都先重置移动方向,确保无输入时不会继承旧值
  2. 分离lastMoveDirection和moveDirection:
    • moveDirection仅在有输入时才有值,无输入时为零,控制角色是否移动
    • lastMoveDirection只在有输入时更新,用来保存最后朝向,给动画提供方向参数
  3. 动画参数调整:
    • MoveX/MoveY使用lastMoveDirection,确保输入归零后角色保持最后朝向的动画帧
    • PlayerMoving使用moveDirection != Vector2.zero,准确判断角色是否在移动,控制动画切换
  4. 触屏输入优化:添加了moveDirection = Vector2.zero,避免键盘和触屏输入同时触发导致的方向冲突

这样修改后,当玩家停止输入时,角色会立刻停止移动,同时定格在最后朝向的动画帧上,完全符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 18:05:18