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

Unity开发中如何实现NPC左右行走时动画与移动方向匹配

问题根源

  • Decrease() 函数在现有代码中没有任何调用入口,判定逻辑完全不会执行,自然无法输出坐标变化日志,也无法获取移动方向
  • 未将X轴坐标变化的判定结果和Sprite朝向翻转、动画状态做绑定,导致方向判断结果没有实际生效
  • lastXVal 没有初始化初始值,首次判定时会出现基准值错误

调整方案

1. 核心逻辑修改

在Update移动逻辑执行后加入方向判定,绑定Sprite翻转逻辑,初始化lastXVal的基准值,修改后完整代码如下:

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

public class NPCController : MonoBehaviour
{
    private float waitTime;
    private Animator _animator;
    private SpriteRenderer _renderer;

    public Transform moveSpot;
    private bool _facingRight = true;
    public float lastXVal;
    public float speed;
    public float startWaitTime;
    public float minX;
    public float maxX;
    public float minY;
    public float maxY;

    void Awake()
    {
        _animator = GetComponent<Animator>();
        _renderer = GetComponent<SpriteRenderer>();
    }

    void Start()
    {
        waitTime = startWaitTime;
        moveSpot.position = new Vector2(Random.Range(minX, maxX), Random.Range(minY, maxY));
        // 初始化X坐标基准值
        lastXVal = transform.position.x;
    }

    void Update()
    {
        transform.position = Vector2.MoveTowards(transform.position, moveSpot.position, speed * Time.deltaTime);
        // 调用方向判定逻辑
        CheckMoveDirection();

        if (Vector2.Distance(transform.position, moveSpot.position) < 0.2f)
        {
            if (waitTime <= 0)
            {
                _animator.SetBool("Walk", true);
                _animator.SetBool("Idle", false);
                moveSpot.position = new Vector2(Random.Range(minX, maxX), Random.Range(minY, maxY));
                waitTime = startWaitTime;
            }
            else
            {
                _animator.SetBool("Walk", false);
                _animator.SetBool("Idle", true);
                waitTime -= Time.deltaTime;
            }
        }
    }

    // 替换原有Decrease函数的方向判定逻辑
    private void CheckMoveDirection()
    {
        if (transform.hasChanged)
        {
            float currentX = transform.position.x;
            if (currentX < lastXVal && _facingRight)
            {
                Flip();
                Debug.Log("Decreased!");
            }
            else if (currentX > lastXVal && !_facingRight)
            {
                Flip();
                Debug.Log("Increased");
            }
            lastXVal = currentX;
            transform.hasChanged = false;
        }
    }

    // 翻转Sprite朝向
    private void Flip()
    {
        _facingRight = !_facingRight;
        _renderer.flipX = !_facingRight;
    }
}

如果需要保留原有Decrease函数的命名,只要把CheckMoveDirection改名为Decrease即可。

2. 动画状态机校验

确认Animator配置符合以下规则即可正常运行:

  • Walk、Idle两个状态的切换条件对应代码中设置的Bool参数
  • Walk状态的切换优先级高于Idle,避免动画冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 03:15:02