Unity开发:蛇头旋转方向限制条件失效问题求助
问题
我是Unity和编程的纯新手,正在制作一款经典贪吃蛇的复刻游戏。游戏场景为绿色地板加盒子搭建的边界,蛇头(含占位符)以恒定速度向前移动。
我编写了蛇头脚本,希望按下方向键时蛇头旋转90度转向对应方向,代码如下:
if (Input.GetKeyDown(KeyCode.LeftArrow) && transform.rotation.y != 90) { transform.localEulerAngles = new Vector3(0, -90, 0); } if (Input.GetKeyDown(KeyCode.RightArrow) && transform.rotation.y != -90) { transform.localEulerAngles = new Vector3(0, 90, 0); } if (Input.GetKeyDown(KeyCode.UpArrow) && transform.rotation.y != 180) { transform.localEulerAngles = new Vector3(0, 0, 0); } if (Input.GetKeyDown(KeyCode.DownArrow) && transform.rotation.y != 0) { transform.localEulerAngles = new Vector3(0, 180, 0); }
问题在于每个if语句的第二个判断条件(如transform.rotation.y != 90)失效。例如当蛇头朝右时按下左键,该条件本应阻止蛇头转向,但实际无法生效,请问该如何修复?
解决方案
核心问题原因
你用错了旋转的读取方式:transform.rotation是四元数(Quaternion),它的x/y/z/w分量不是直观的欧拉角度数,而是四元数内部的计算值,范围在[-1,1]之间,永远不会等于90、-90这种欧拉角数值,所以你的判断条件永远为真,自然起不到阻止转向的作用。
修复方案(两种可选)
方案1:改用localEulerAngles读取角度
直接用你设置时用的transform.localEulerAngles.y来做判断,同时处理Unity欧拉角的特殊存储和浮点误差:
if (Input.GetKeyDown(KeyCode.LeftArrow) && Mathf.Round(transform.localEulerAngles.y) != 90) { transform.localEulerAngles = new Vector3(0, -90, 0); } if (Input.GetKeyDown(KeyCode.RightArrow) && Mathf.Round(transform.localEulerAngles.y) != 270) // Unity中-90度会被存储为270度 { transform.localEulerAngles = new Vector3(0, 90, 0); } if (Input.GetKeyDown(KeyCode.UpArrow) && Mathf.Round(transform.localEulerAngles.y) != 180) { transform.localEulerAngles = new Vector3(0, 0, 0); } if (Input.GetKeyDown(KeyCode.DownArrow) && Mathf.Round(transform.localEulerAngles.y) != 0) { transform.localEulerAngles = new Vector3(0, 180, 0); }
- 加
Mathf.Round是因为Unity的欧拉角可能存在微小浮点误差(比如显示为89.99999而非90),取整后能避免判断失效。 - 注意:Unity中-90度的Y轴欧拉角会被转换为270度存储,所以判断右方向的反向时要检查270而非-90。
方案2:维护独立的方向变量(更推荐)
对于贪吃蛇这类逻辑简单的游戏,直接维护一个枚举类型的方向变量,比读取Transform角度更可靠,逻辑也更清晰:
// 先定义方向枚举 public enum SnakeDirection { Up, Down, Left, Right } private SnakeDirection currentDirection; void Start() { // 初始化默认方向为Up currentDirection = SnakeDirection.Up; transform.localEulerAngles = new Vector3(0, 0, 0); } void Update() { if (Input.GetKeyDown(KeyCode.LeftArrow) && currentDirection != SnakeDirection.Right) { currentDirection = SnakeDirection.Left; transform.localEulerAngles = new Vector3(0, -90, 0); } if (Input.GetKeyDown(KeyCode.RightArrow) && currentDirection != SnakeDirection.Left) { currentDirection = SnakeDirection.Right; transform.localEulerAngles = new Vector3(0, 90, 0); } if (Input.GetKeyDown(KeyCode.UpArrow) && currentDirection != SnakeDirection.Down) { currentDirection = SnakeDirection.Up; transform.localEulerAngles = new Vector3(0, 0, 0); } if (Input.GetKeyDown(KeyCode.DownArrow) && currentDirection != SnakeDirection.Up) { currentDirection = SnakeDirection.Down; transform.localEulerAngles = new Vector3(0, 180, 0); } }
这种方式完全规避了Transform角度的浮点误差问题,后续扩展蛇身跟随等功能时也更容易对接逻辑。
内容的提问来源于stack exchange,提问作者Siddharth
相关产品推荐
相关产品推荐

