Unity 3D中敌人跟随玩家时如何根据移动方向播放动画?
问题描述
我正在开发一款2.5D足球游戏,采用3D空间+精灵资源的方案。当前需要实现敌人跟随玩家移动时,根据自身移动方向播放对应动画,方向包括:向后、向左、向右、后左、后右、前左、前右,且尽量不使用Blend Tree(混合树)。
之前尝试用transform.position.x/z判断方向,但效果很差——因为位置坐标无法反映实时的移动输入/速度方向。现有代码如下:
using UnityEngine; public class EnnemyAnimation : MonoBehaviour { void Update() { if (transform.position.x > 0) { Debug.Log("right"); // play animation right } else if (transform.position.x < 0) { Debug.Log("left"); // play animation left } else if (transform.position.z < 0) { Debug.Log("back"); // play animation back } else if (transform.position.z > 0) { Debug.Log("front"); // play animation front } else if (transform.position.x < 0 && transform.position.z < 0) { Debug.Log("back-left"); // play animation back left } else if (transform.position.x > 0 && transform.position.z < 0) { Debug.Log("back-right"); // play animation back right } else if (transform.position.x < 0 && transform.position.z > 0) { Debug.Log("front-left"); // play animation front left } else if (transform.position.x > 0 && transform.position.z > 0) { Debug.Log("front-right"); // play animation front right } } }
实现方案
核心思路
放弃用位置坐标判断,改用敌人的移动方向向量(或目标方向向量)来判定,这样能精准反映当前的移动意图,避免位置漂移带来的判断错误。
修正代码
using UnityEngine; public class EnemyAnimation : MonoBehaviour { // 跟随目标(比如玩家) public Transform target; private Rigidbody rb; private Animator anim; // 方向阈值:过滤微小移动,避免动画频繁切换 public float directionThreshold = 0.2f; void Start() { rb = GetComponent<Rigidbody>(); anim = GetComponent<Animator>(); } void Update() { // 1. 获取指向目标的方向(忽略Y轴,适配2.5D平面移动) Vector3 worldMoveDir = target.position - transform.position; worldMoveDir.y = 0; worldMoveDir.Normalize(); // 2. 转换为敌人本地坐标系下的方向(避免世界坐标干扰) Vector3 localMoveDir = transform.InverseTransformDirection(worldMoveDir); // 3. 过滤静止状态 bool isMoving = worldMoveDir.magnitude > 0.01f; if (!isMoving) { anim.Play("Idle"); return; } // 4. 按前后→左右的优先级判断方向 if (localMoveDir.z < -directionThreshold) { // 向后区域 if (localMoveDir.x < -directionThreshold) anim.Play("BackLeft"); else if (localMoveDir.x > directionThreshold) anim.Play("BackRight"); else anim.Play("Back"); } else if (localMoveDir.z > directionThreshold) { // 向前区域 if (localMoveDir.x < -directionThreshold) anim.Play("FrontLeft"); else if (localMoveDir.x > directionThreshold) anim.Play("FrontRight"); else anim.Play("Front"); } else { // 纯左右区域 if (localMoveDir.x < -directionThreshold) anim.Play("Left"); else if (localMoveDir.x > directionThreshold) anim.Play("Right"); } } }
关键说明
- 本地坐标系转换:
InverseTransformDirection将世界方向转为敌人自身的本地方向,确保"前/后/左/右"始终对应敌人的朝向,适配2.5D精灵的展示逻辑。 - 方向阈值:
directionThreshold可以根据游戏手感调整(建议0.1~0.3),避免物理抖动或微小移动导致动画频繁切换。 - 优先级判断:先判断前后方向,再细化左右,确保斜向方向不会被单一方向的判断覆盖。
- 适配自定义移动:如果不用Rigidbody驱动移动,直接把
worldMoveDir换成你的自定义移动输入向量即可,核心逻辑不变。
内容的提问来源于stack exchange,提问作者MikaMikashu




