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

Unity 2D开发如何让枪械朝鼠标方向而非鼠标位置发射子弹

问题根源

你当前子弹速度随鼠标距离变化的原因非常直接:你赋值给子弹刚体速度的direction向量,是枪口到鼠标点的原始位移向量,这个向量的长度等于枪口和鼠标之间的实际世界单位距离。鼠标离枪口越近,向量长度越短,子弹速度就越低;鼠标越远速度越快,速度完全不受控制。

修复方案

不需要额外重新计算指向角度,只要对方向向量做归一化处理即可:归一化会把向量的长度固定为1,只保留纯粹的朝向信息,之后用这个单位方向向量乘以你预设的固定子弹速度,就能保证子弹永远沿枪口指向飞行,速度全程恒定,和鼠标与玩家的距离完全无关。

具体修改步骤

  • 在类的公共变量区新增固定子弹速度参数,方便后续在编辑器调整数值
  • 计算完枪口到鼠标的位移后,直接获取归一化后的单位方向向量
  • 给子弹赋值速度时,用「单位方向向量 * 固定子弹速度」替换原来直接传入原始位移向量的写法
  • 修正原代码中碰撞忽略的逻辑问题:不需要通过Find查找子弹克隆体,直接传入当前生成的子弹实例即可

修正后的完整代码

public GameObject bullet;
public GameObject player;
public float bulletSpeed = 12f; // 子弹固定飞行速度,可根据需求在Inspector调整


// All the following is within an update function

//Gets the mouse position, and assigns direction from gun to mouse
Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
// 对齐z轴坐标,避免2D场景下方向计算出现偏差
mousePosition.z = transform.position.z;
// 对位移向量做归一化,获取仅保留朝向信息的单位向量
Vector2 direction = (mousePosition - transform.position).normalized;
float angle = Vector2.SignedAngle(Vector2.right, direction);

Vector2 PlayerDimensions = player.transform.lossyScale;
Vector2 PlayerLocation = player.transform.position;


//If the Gun weapon type is selected
if (weaponType == 2)
{
   // Is used to flip the player sprite based on if the gun is facing left or right
   if (PlayerLocation.x > mousePosition.x)
   {
      PlayerDimensions.x = -1;
      player.transform.localScale = new Vector2(PlayerDimensions.x, PlayerDimensions.y);
   }
   else if (PlayerLocation.x < mousePosition.x)
   {
      PlayerDimensions.x = 1;
      player.transform.localScale = new Vector2(PlayerDimensions.x, PlayerDimensions.y);
   }
   // Aims the gun based on if player is facing left or right
   if (player.transform.lossyScale.x > 0)
   {
      transform.eulerAngles = new Vector3(0, 0, angle);
   }
   else if (player.transform.lossyScale.x < 0)
   {
      transform.eulerAngles = new Vector3(0, 0, 180 + angle);
   }
}

if (Input.GetMouseButtonDown(0) && weaponType == 2)
{
   Debug.Log("Shoot");

   Vector3 myPos = new Vector3(transform.position.x, transform.position.y);
   // 如果需要子弹生成时和枪口角度一致,可将Quaternion.identity替换为transform.rotation
   GameObject Bullet = Instantiate(bullet, myPos, Quaternion.identity);
   // 修正碰撞忽略逻辑,直接传入当前生成的子弹实例即可
   Physics2D.IgnoreCollision(Bullet.GetComponent<BoxCollider2D>(), player.GetComponent<BoxCollider2D>(), true);

   // 用单位方向乘以固定速度赋值,保证子弹速度恒定
   Bullet.GetComponent<Rigidbody2D>().velocity = direction * bulletSpeed;
}

补充说明:如果你已经通过angle变量控制了枪口的旋转角度,也可以直接用角度生成速度向量:Bullet.GetComponent<Rigidbody2D>().velocity = new Vector2(Mathf.Cos(angle * Mathf.Deg2Rad), Mathf.Sin(angle * Mathf.Deg2Rad)) * bulletSpeed;,效果和归一化方向向量完全一致,两种写法选一种即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 08:57:39