Unity 2D:如何修正子弹射击方向及坐标转换边界判断问题?
子弹水平射击异常的修改方案
共通的基础逻辑错误(两套代码都存在)
- 移动方向完全错位:当前代码计算新位置时,仅对Y轴做了速度累加,X轴全程保留初始值,本质是垂直飞行的逻辑,和要求的沿X轴水平射击目标完全不符。这是子弹一开始就垂直飞的根本原因。
- 边界判断轴和移动方向不匹配:现有代码的销毁判断全部围绕X轴坐标展开,但因为子弹没有在X轴产生位移,这个判断永远无法和移动逻辑形成闭环,自然会出现各种不符合预期的判断结果。
两套边界实现的单独问题
基于ViewportToWorldPoint的实现问题
- 边界参考值不全:仅计算了屏幕右上角的坐标点,没有配套计算左下角的边界值,没有完整的屏幕坐标参考,判断逻辑很容易失效。
- 判断和移动脱节:因为移动逻辑是Y轴方向、判断逻辑是X轴方向,两边轴不对应,就会出现“子弹在Y轴方向飞出老远,X轴判断却一直等不到触发条件”的错位表现。
基于ScreenToWorldPoint的实现问题
- 坐标计算参数错误:调用
ScreenToWorldPoint时,传入的Z轴值是相机自身的Z位置,在2D游戏常用的正交相机场景下,会导致计算出的世界边界坐标出现层面偏差,无法匹配子弹所在的游戏平面。 - 销毁判断逻辑完全错误:判断条件写的是
transform.position.x > screenBounds.x * -2,计算得到的screenBounds.x本身是屏幕最右侧的正向X坐标,乘-2后是一个非常小的负数值,子弹刚生成时的X坐标远大于这个负数,一帧内就会满足销毁条件,直接出现“子弹生成后立刻消失”的现象。
修正后的参考实现
要实现沿X轴水平射击的效果,直接对应调整移动和判断逻辑即可,参考代码:
public float speed = 5f; // 可在Inspector面板调整的射击速度 void Update() { // 获取子弹当前位置 Vector2 currentPos = transform.position; // 水平移动逻辑:仅对X轴累加位移,Y轴保持生成位置不变 currentPos = new Vector2(currentPos.x + speed * Time.deltaTime, currentPos.y); // 应用计算后的新位置 transform.position = currentPos; // 计算完整屏幕边界 Vector2 screenLeftBottom = Camera.main.ViewportToWorldPoint(new Vector2(0, 0)); Vector2 screenRightTop = Camera.main.ViewportToWorldPoint(new Vector2(1, 1)); // 子弹向右飞行时,飞出屏幕右边界即销毁,预留少量冗余值避免边界处突兀消失 if (transform.position.x > screenRightTop.x + 0.5f) { Destroy(gameObject); } }
如果是向左射击的逻辑,只需要把移动时的X轴增量改成负号,判断条件改成transform.position.x < screenLeftBottom.x - 0.5f即可。
如果要使用ScreenToWorldPoint实现边界判断,需要注意两点:
- 调用方法时传入的Z值要和子弹所在平面的Z值匹配,保证计算出的世界坐标和子弹处于同一层级,不要直接传相机自身的Z值。
- 销毁判断直接和计算得到的边界值做比较,不要随意给边界值乘负数、放大缩小系数,避免出现误触发。
内容的提问来源于stack exchange,提问作者johnny
相关产品推荐
相关产品推荐

