当前位置: 首页 > news >正文

unity RaycastHit详解 - 冷夜

UnityEngine.RaycastHit 是 Unity 物理引擎中用于存储‌射线检测(Raycasting)结果‌的核心结构体。当使用 Physics.RaycastPhysics.Linecast 或 Physics.SphereCast 等方法进行碰撞检测时,如果射线与场景中的碰撞体(Collider)相交,Unity 会将相交点的详细物理信息填充到 RaycastHit 结构中。

它就像是一个“碰撞记录仪”,提供了关于“打中了什么”、“在哪里打中的”以及“表面朝向如何”等关键数据。

1. 核心属性详解

RaycastHit 包含多个只读属性,以下是开发中最常用的关键字段:

基础交互信息

  • collider‌ (Collider)
    • 被射线击中的碰撞体组件引用。通过它可以获取 GameObject (hit.collider.gameObject) 或其他组件。
  • transform‌ (Transform)
    • 被击中物体的变换组件。如果碰撞体附加了刚体,这通常指向刚体的 Transform;否则指向碰撞体所在的 GameObject 的 Transform。
  • rigidbody‌ (Rigidbody)
    • 被击中碰撞体所依附的刚体组件。如果该物体没有刚体,此值为 null
  • articulationBody‌ (ArticulationBody)
    • 被击中碰撞体所依附的关节体组件。如果没有,此值为 null

空间位置与几何信息

  • point‌ (Vector3)
    • ‌世界坐标系‌下的撞击点位置。这是射线与碰撞体表面实际接触的点。常用于生成特效(如弹孔、火花)的位置。
  • normal‌ (Vector3)
    • 撞击点处的‌表面法线‌(世界坐标系)。这是一个单位向量,垂直于碰撞表面。
    • ‌用途‌:计算反射角度(如子弹反弹)、确定物体在斜面上的滑动方向、或者判断玩家是否站在地面上(法线接近向上)。
  • distance‌ (float)
    • 从射线原点(Ray.origin)到撞击点(hit.point)的距离。
    • ‌用途‌:判断目标是否在武器射程内,或用于排序多个命中结果(最近的优先)。

UV 与纹理坐标(高级渲染用)

  • textureCoord‌ (Vector2)
    • 撞击点处的主 UV 纹理坐标。
  • textureCoord2‌ (Vector2)
    • 撞击点处的辅助 UV 纹理坐标。
  • lightmapCoord‌ (Vector2)
    • 撞击点处的光照贴图 UV 坐标。
  • barycentricCoordinate‌ (Vector3)
    • 命中三角形的重心坐标。用于更精细地插值计算命中点在三角形内的具体位置。
  • triangleIndex‌ (int)
    • 被命中的网格三角形的索引。结合 Mesh 数据可以获取更底层的几何信息。

其他

  • colliderInstanceId‌ (int)
    • 被击中碰撞体的实例 ID,用于快速比较是否击中了同一个碰撞器对象。

2. 基本用法示例

示例 1:鼠标点击拾取物体

这是最常见的用法,将屏幕上的鼠标位置转换为世界空间的射线,检测点击到的物体。

using UnityEngine;public class RaycastClick : MonoBehaviour
{void Update(){// 当鼠标左键按下时if (Input.GetMouseButtonDown(0)){// 1. 从相机向鼠标位置发射射线Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);// 2. 定义接收结果的变量
            RaycastHit hit;// 3. 执行射线检测,最大距离为 100 米if (Physics.Raycast(ray, out hit, 100f)){// 4. 读取 RaycastHit 信息Debug.Log("击中了物体: " + hit.collider.name);Debug.Log("击中点世界坐标: " + hit.point);Debug.Log("表面法线: " + hit.normal);Debug.Log("距离相机: " + hit.distance);// 示例:如果击中的是敌人,造成伤害Enemy enemy = hit.collider.GetComponent<Enemy>();if (enemy != null){enemy.TakeDamage(10);}}}}
}

示例 2:前方障碍物检测与法线应用

用于角色控制或 AI 视线检测,利用 normal 来判断地面坡度或墙壁朝向。

using UnityEngine;public class GroundCheck : MonoBehaviour
{public float checkDistance = 1.5f;void Update(){// 从角色脚下向下发射射线Ray ray = new Ray(transform.position, Vector3.down);RaycastHit hit;if (Physics.Raycast(ray, out hit, checkDistance)){// 判断法线是否朝上(即是否是地面)// Vector3.up 与 hit.normal 的点积接近 1 表示表面水平朝上if (Vector3.Dot(hit.normal, Vector3.up) > 0.7f){Debug.Log("站在地上");}else{Debug.Log("碰到了斜坡或墙壁");}}}
}

3. 高级技巧与注意事项

1. 性能优化:LayerMask(层掩码)

默认情况下,Physics.Raycast 会检测所有层级的碰撞体。为了提升性能并避免误判(例如忽略触发器 Trigger 或特定背景层),应始终使用 LayerMask

// 只检测 "Enemy" 和 "Obstacle" 层
int layerMask = LayerMask.GetMask("Enemy", "Obstacle");if (Physics.Raycast(ray, out hit, 100f, layerMask))
{// 处理逻辑
}

2. 穿透检测:Physics.RaycastAll

标准的 Physics.Raycast 只返回‌第一个‌(最近的)命中结果。如果需要知道射线路径上穿过的所有物体(例如子弹穿透木板击中后面的敌人),需使用 Physics.RaycastAll

RaycastHit[] hits = Physics.RaycastAll(ray, 100f);// RaycastAll 返回的结果不一定按距离排序,建议手动排序
System.Array.Sort(hits, (x, y) => x.distance.CompareTo(y.distance));foreach (RaycastHit hit in hits)
{Debug.Log($"穿透物体: {hit.collider.name}, 距离: {hit.distance}");
}

3. 2D 物理的区别

请注意,RaycastHit 仅用于 ‌3D 物理系统‌(Physics 类)。如果你使用的是 ‌2D 物理系统‌(Physics2D类),对应的结构体是 ‌RaycastHit2D‌。两者的属性略有不同(例如 RaycastHit2D 没有 rigidbody 而是 rigidbody2D,且某些属性行为因 2D 特性而异)。

4. 触发器(Trigger)

默认情况下,Physics.Raycast ‌不会‌检测到标记为 Is Trigger 的碰撞体。如果需要检测触发器,需使用 Physics.Raycast 的重载版本并指定 QueryTriggerInteraction 参数,或者使用 Physics.RaycastNonAlloc等变体。

总结

RaycastHit 是 Unity 3D 交互开发的基石。掌握其核心属性 point(位置)、normal(朝向)、distance(距离)和 collider(对象引用),并结合 LayerMask 进行优化,可以实现从简单的鼠标拾取到复杂的物理反馈等各种功能。

http://www.jsqmd.com/news/783528/

相关文章:

  • CANN/pyasc向量最小值函数
  • AI Agent团队技能包:集成OpenClaw、Claude Code与tmux实现自动化开发
  • 一文吃透HDLC协议|从帧结构到封装解封装
  • AI控制框架KendaliAI:从模型调用到智能体编排的工程化实践
  • AI时代高等教育重塑:教学反馈、学术诚信与未来技能挑战
  • GitHub Models实战指南:6个本地可运行的AI模型部署案例
  • 2026贵阳新房高端定制装修:5大实力品牌横评与透明报价对标 - 优质企业观察收录
  • 潮玩资产化新纪元!盲盒V6MAX源码系统小程序,国际版盲盒源码赋能盲盒定制开发,颠覆海外盲盒app源码程序与盲盒源码 - 壹软科技
  • CANN/pypto填充操作API文档
  • 2026汽车划痕补漆品牌对比评测与推荐:哪个更靠谱? - 阿喂嘞lvv
  • VLA-0视觉语言动作模型:零修改部署与多模态AI实践
  • 【Kubernetes】Ubuntu 24.04 二进制方式部署 K8s
  • 2026年贵阳新房装修全屋整装深度横评:设计落地率、质保周期、性价比对比 - 优质企业观察收录
  • 2026年贵阳室内装修全案设计深度横评:从设计落地难到一站式全案交付的品质突围指南 - 优质企业观察收录
  • CANN/ops-cv图像处理算子库
  • 品牌测评:自动体外除颤仪厂家竞争力白皮书 - 品牌推荐大师1
  • Parquet文件原理与实战:列式存储如何提升查询性能和压缩效率
  • 研发冻干机控温精度与真空稳定性横向测评:五大国产品牌 vs 进口主流型号 - 品牌推荐大师1
  • 生成式AI驱动模拟电路设计:CktGen框架原理与实践指南
  • CANN/pyasc取小数计算函数
  • 为开源项目OpenClaw配置Taotoken以实现更灵活的Agent工作流
  • 合成数据验证特征缩放必要性的白盒实验方法
  • 基于YOLOv5与LSTM的智能交通信号控制系统实战
  • 东莞市全区域上门回收黄金 正规资质商家一站式服务 - 金掌柜黄金回收
  • SQL PIVOT原理与实战:从行转列到高性能宽表生成
  • 2026年山东沥青加温设备与道路养护设备源头厂家深度选购指南 - 企业名录优选推荐
  • 20251209樊沛东python程序设计实验三报告
  • CANN/cannbot-skills a2设备约束
  • CANN运行时任务更新指南
  • Llama 3.2 Vision轻量微调实战:500图打造电商级图文生成模型