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

Unity霰弹枪Raycast随机扩散实现:指定角度内发射射线

如何在Unity中实现Raycast霰弹枪的随机扩散效果?

想要在Unity中制作一款使用Raycast的霰弹枪,实现弹丸的随机扩散效果。请问如何让Raycast在指定角度范围(例如20度)内朝随机方向发射?

以下是我的代码:

for (int i = 0; i < (((GunInfo)itemInfo).bullets); i++){
    Ray ray = cam.ViewportPointToRay(new Vector3(0.5f, 0.5f));
    ray.origin = cam.transform.position;
    if (Physics.Raycast(ray, out RaycastHit hit))
    {
        hit.collider.gameObject.GetComponent<IDamageable>()?.TakeDamage(((GunInfo)itemInfo).damage); //ignore this
        PV.RPC("RPC_Shoot", RpcTarget.All, hit.point, hit.normal); //ignore this
    }
}

我对Raycast的使用经验并不丰富,目前还没能找到解决方法,也没找到适合该场景的可行方案。


解决方案

要实现指定角度内的随机射线扩散,核心是基于相机前向方向生成带随机偏移的射线方向,这里提供两种实用方法:

方法一:随机俯仰/偏航角度偏移

直接生成指定范围内的随机俯仰(Pitch)和偏航(Yaw)角度,通过旋转基准方向得到扩散后的射线方向,实现简单直观:

// 定义霰弹扩散角度(单位:度)
float spreadAngle = 20f;

for (int i = 0; i < (((GunInfo)itemInfo).bullets); i++){
    // 获取相机的前向基准方向
    Vector3 baseForward = cam.transform.forward;
    
    // 生成-spreadAngle/2 到 spreadAngle/2之间的随机俯仰、偏航偏移
    float randomPitch = Random.Range(-spreadAngle / 2f, spreadAngle / 2f);
    float randomYaw = Random.Range(-spreadAngle / 2f, spreadAngle / 2f);
    
    // 应用旋转得到扩散后的方向
    Vector3 spreadDirection = Quaternion.Euler(randomPitch, randomYaw, 0) * baseForward;
    
    // 创建带扩散效果的射线
    Ray ray = new Ray(cam.transform.position, spreadDirection);
    
    if (Physics.Raycast(ray, out RaycastHit hit))
    {
        hit.collider.gameObject.GetComponent<IDamageable>()?.TakeDamage(((GunInfo)itemInfo).damage);
        PV.RPC("RPC_Shoot", RpcTarget.All, hit.point, hit.normal);
    }
}

方法二:基于三角函数的精确角度限制

通过三角函数计算最大偏移量,确保射线方向严格限制在指定角度内,适合对扩散范围要求精准的场景:

// 定义霰弹扩散角度(单位:度)
float spreadAngle = 20f;
// 将角度转为弧度,计算最大偏移的正切值
float maxOffsetTan = Mathf.Tan(spreadAngle * Mathf.Deg2Rad / 2f);

for (int i = 0; i < (((GunInfo)itemInfo).bullets); i++){
    // 获取相机的前向基准方向
    Vector3 baseForward = cam.transform.forward;
    
    // 生成垂直于前向的随机偏移向量,缩放至对应角度范围
    Vector3 spreadOffset = Random.insideUnitSphere;
    // 移除前向分量,确保偏移只在垂直平面
    spreadOffset -= Vector3.Dot(spreadOffset, baseForward) * baseForward;
    // 归一化后按角度缩放
    spreadOffset = spreadOffset.normalized * maxOffsetTan;
    
    // 合并基准方向与偏移,得到最终扩散方向
    Vector3 spreadDirection = (baseForward + spreadOffset).normalized;
    
    // 创建带扩散效果的射线
    Ray ray = new Ray(cam.transform.position, spreadDirection);
    
    if (Physics.Raycast(ray, out RaycastHit hit))
    {
        hit.collider.gameObject.GetComponent<IDamageable>()?.TakeDamage(((GunInfo)itemInfo).damage);
        PV.RPC("RPC_Shoot", RpcTarget.All, hit.point, hit.normal);
    }
}

关键说明

  • 两种方法都以相机前向方向为基准,确保扩散围绕准星中心展开
  • 方法一适合大多数游戏场景,实现成本低;方法二精度更高,能严格控制扩散边界
  • 调整spreadAngle的值即可改变霰弹的扩散程度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 09:05:22