Unity 射线与碰撞范围检测【踩坑记录】

article/2025/11/11 6:35:30

射线检测

射线检测在2D和3D的区别比较大

  • 一定要加上对应的Collider组件

  • 对应的函数只检测对应的Collider,Physics.Raycast是不会检测到Collider 2D的(这个让我有一次debug了好久才发现)

  • 对应API如下

Physics.Raycast(Vector3 origin,Vector3 direction,out RaycastHit hitinfo,float distance,int LayerMask);
//origin:射线的起始点,因为是位置坐标所以使用Vector3表示
//direction:射线的方向,因为是方向坐标所以使用Vector3表示
//hitinfo:一个结构体,可以储存碰撞体的所有信息。你可以声明一个空的然后直接代入就可以
//下面是可选参数:
//distance:射线检测的距离
//LayerMask:图层,如果输入图层的序号就可以只检测这个图层的相应物体,

可以使用Debug.DrawLine(Vector3 origin,Vector3 destination,Color color)Debug.DrawRay(Vector3 origin,Vector3 direction,Color color)来使射线可视化

此外因为Ray都是由两个Vector3变量构造而成的,而2D世界都是Vector2,只能用Vector2变量表示了。

当从物体中心点发出时,检测到的第一个碰撞体却是自己。

那我们该怎么解决这个问题呢?答案是Physics2D.queriesStartInColliders = false;这样如果碰撞体是我们射线所在起点的内部时,我们不让它返回该碰撞体。

为什么LayerMask是int

LayerMask的形式是int。它表示的是你图层的序号的二次方倍

就是相当于一个二进制数,需要检测的图层的对应位置为1,其余为0

  • 1 << 10 打开第10的层。 等价于1 << LayerMask.NameToLayer(“Ground”); 也等价于LayerMask.GetMask((“Ground”);
  • ~(1 << 10) 打开除了第10之外的层。(取反符号)
  • ~(1 << 0) 打开所有的层。
  • (1 << 10) | (1 << 8) 打开第10和第8的层。

2D碰撞检测

Unity的物理引擎是基于PhysX的,但有时候游戏需要可配置的物理效果,按帧或者是时间线的方式来产生类似的效果。

Rigidbody 2D

选用了Rigidbody 2D组件的话,不能修改transform.position,而是要使用Rigidbody2D.positionRigidbody2D.rotation

Body Type

  • Dynamic: 表示动态刚体,完全模拟物理效果,与任何Rigidbody 2D都会发生物理效果,但是效率最低,只适合角色使用
  • Kinematic: 表示运动学,只能和Dynamic刚体碰撞,如果需要和其他类型碰撞或者是需要触发碰撞事件,需要勾选Use Full Kinematic Contacts.
  • Static: 和Dynamic发生碰撞效果,和Kinematic只能发生碰撞事件(需要勾选Use Full Kinematic Contacts

碰撞事件

我们除了可以在碰撞者和被碰撞者上监听碰撞事件外,如果监听碰撞的元素比较多,还能将碰撞事件抛出去由外部统一处理。

void Start()
{CollisionLi1stener.onCollisionEnter2D.AddListener(delegace (GameObject g1, GameObject g2) {Debug.LogFormat ( "{0}开始碰撞{1}",g1.name , g2.name);});CollisionLi1stener.onCollisionStay2D.AddListener(delegace (GameObject g1, GameObject g2) {Debug.LogFormat ( "{0}碰撞中{1}",g1.name , g2.name);});CollisionLi1stener.onCollisionExit2D.AddListener(delegace (GameObject g1, GameObject g2) {Debug.LogFormat ( "{0}结束碰撞{1}",g1.name , g2.name);});}

碰撞方向

Unity2D并没有提供方法来判断方向,但是提供了碰撞发生的坐标点,需要我们自己来计算碰撞方向。

void OnCollisionStav2D(Collision2D coll){foreach (ContactPoint2D contact in coll.contacts){//绘制线Debug.DrawLine ( contact.point, transform.position, Color.red);var direction = transform.InverseTransformPoint (contact.point);if(direction.x > 0f){ print( "右碰撞");}if(direction.x < 0f){print("左碰撞");}if(direction.y > 0f){print ("上碰撞");}if(direction.y < 0f){print ("下碰撞");}}
}

Effector

unity可以给Collider 2D组件添加的额外效果

  • Platform Effector 2D: 单向板地面,能从下往上跳,却掉不下来
  • Surface Effector 2D: 传输带一样带摩擦移动
  • Point Effector 2D: 类似炸弹,爆炸后可以把周围东西炸开
  • Buoyancy Effector 2D: 模拟浮力
  • Area Effector 2D: 区域力

不依赖物理引擎

我们可以不依赖物理引擎,可以极大的优化效率,比如我们可以利用射线检测实现碰撞检测

射线检测

在这里插入图片描述

可以看出只用一根射线检测是不行的,在2D-Epic-Controller中就使用了10个射线检测来判断地面和前提碰撞

这种方法手感非常的完美,不过实现起来有些许麻烦

Physical.Overlap

我们可以直接使用下面几种:

  • Physics.OverlapBox
  • Physics.OverlapCapsule
  • Physics.OverlapSphere

可以在此基础上使用Gizmos 辅助线框来实现在Scence中更好的视觉效果

如果是2D则使用Physics2D.开头的一系列函数

3D碰撞检测

碰撞检测穿透

只要是跟碰撞相关的基本都是离不开Rigidbody这个组件,当中的Collision detection参数可以选择碰撞检测方式

在这里插入图片描述

主要用于处理高速s运动的物体,会有时候直接穿过其他物体的时候
在这里插入图片描述

(上图每个箭头两端均指的是两个即将碰撞的物体的Collision Detection属性的值,箭头中间的属性值所指的是这两个物体时间碰撞所用的碰撞检测模式)

  • Discrete(离散型检测模式)就是普通的默认状态;

  • Continuous(连续检测)则是更加精细的碰撞检测,但是很耗资源;

  • Continuous和Continuous Dynamic的共同点在于,对待没有刚体和设置为Continuous Dynamic的物体都使用连续碰撞检测,对待刚体设置为Discrete的物体都使用离散碰撞检测。

  • 不同点在于,Continuous Dynamic在检测另一个设置为Continuous的物体使用的仍然是连续碰撞检测模式,而Continuous检测另一个Continuous的物体时使用的却是离散碰撞检测。

在这里插入图片描述

此两类方法由于依赖于连续(线性)扫描,所以会忽略物体的角速度,当物体迅速旋转时,仍然会有穿墙的情况发生

之后又出了一个Continuous Speculative **(基于推测式)**这里官方的API解释是要比Continuous和Dynamic的方式这两种方式更加的节省性能,是扫描方式的进行连续碰撞检测。

使用连续碰撞检测(Continuous和Continuous Dynamic)前提:

刚体和非刚体(静态碰撞器): 刚体物体的碰撞器必须是Box,Sphere,Capsule,非刚体物体的碰撞器必须是Mesh。

不使用物理引擎

不使用刚体 Rigidbody的方式,采用发射子弹之前,先发射射线,记录碰撞点(判断是否会发生碰撞),然后在发射子弹。


http://chatgpt.dhexx.cn/article/RhM1tLjT.shtml

相关文章

Unity 碰撞位置

获取碰撞位置的方法1&#xff1a;使用 Collider.ClosestPoint Returns a point on the collider that is closest to a given location. 返回碰撞器上最接近给定位置的点。 下方是子弹打到物体上&#xff0c;生成撞击火星的代码&#xff1a; // 碰撞体的检测 private void O…

Unity入门7——物理系统之碰撞检测

一、刚体 Rigid Body ​ 刚体利用体积&#xff08;碰撞器 Collider&#xff09;进行碰撞计算&#xff0c;模拟真实的碰撞效果&#xff0c;产生力的作用 ​ 碰撞产生的必要条件&#xff1a; 两个物体都有碰撞器 Collider至少一个物体有刚体 Mass&#xff1a;质量 默认为千克&a…

解决Unity物体速度过快无法进行碰撞检测(碰撞检测穿透)

一、解决碰撞检测穿透方法一 首先我们知道只要是跟碰撞相关的基本都是离不开刚体 Rigidbody这个组件&#xff0c;刚体中有一个参数适用于检测碰撞的 如下图 Collision Detection就是碰撞检测。 然而有时候开发游戏&#xff0c;对于高速运动的物体&#xff08;比如&#xff…

【Unity】Unity中获得碰撞体碰撞的位置

有时间的直接看sprite slicer这个插件的代码&#xff0c;原理也是发射线检测&#xff0c;代码逻辑什么的比下面的文章来的好的多&#xff0c;如果有空我也可以整理一下。 在纯物理环境中&#xff0c;为了获得碰撞体碰撞的位置&#xff0c;我们可以使用Collider2D.OnCollisionE…

Unity 3D中的射线与碰撞检测

在我们的游戏开发过程中&#xff0c;有一个很重要的工作就是进行碰撞检测。例如在射击游戏中子弹是否击中敌人&#xff0c;在RPG游戏中是否捡到装备等等。在进行碰撞检测时&#xff0c;我们最常用的工具就是射线&#xff0c;Unity 3D的物理引擎也为我们提供了射线类以及相关的函…

unity3D之简单的碰撞检测 .

版权声明&#xff1a;欢迎订阅公众号【5厘米的理想】&#xff0c;愿生命里的每一个小理想&#xff0c;都能成为生命里的小确幸。本文地址为&#xff1a; http://blog.csdn.net/qinyuanpei/article/details/23093665 大家好&#xff0c;欢迎大家关注由我为大家带来的Unity3D游戏…

Unity碰撞检测的必要条件

Unity中有两个独立的物理引擎&#xff0c;一个用于3D物理系统&#xff0c;一个用于2D物理系统。两个引擎是使用不同的组件实现的。因此BoxCollider和Rigidbody一起使用&#xff0c;代码中用OnTriggerEnter才能检测到触发;BoxCollider2D和Rigidbody2D一起使用&#xff0c;代码中…

Unity3D入门(二):碰撞检测

碰撞器由来 1.系统默认会给每个对象(GameObject)添加一个碰撞组件(ColliderComponent)&#xff0c;一些背景对象则可以取消该组件。 2.在unity3d中&#xff0c;能检测碰撞发生的方式有两种&#xff0c;一种是利用碰撞器&#xff0c;另一种则是利用触发器。这两种方式的应用非…

Unity碰撞检测机制的原理(更新中...)

总是碰到关于碰撞的问题&#xff0c;今天实在忍不住了&#xff0c;来把它搞懂&#xff0c;不然听到八叉树&#xff0c;BSP什么的就怕可不行。 转自&#xff1a;http://www.manew.com/thread-102595-1-1.html 碰撞机制 最近做动态地形生成的时候&#xff0c;发现碰撞检测无效&…

Unity 3D之碰撞检测

一、碰撞器 碰撞检测两大必备条件&#xff1a;1.其中一方具备刚体&#xff0c;碰撞双方碰撞器 1、刚体 2、盒子碰撞器 3、碰撞检测方法 void Start(){this.gameObject.AddComponent<Rigidbody>();//添加刚体}void OnCollisionEnter(Collision other){if (other.gameOb…

Unity2d 学习笔记(四)碰撞检测

碰撞检测功能在游戏开发里是比较常用的&#xff0c;比如地图上无法穿越的部分&#xff0c;以及对于敌人的攻击判定等等。这篇博客就开简单介绍一下碰撞事件的处理。 参考视频&#xff1a;Unity碰撞检测_哔哩哔哩_bilibili 首先&#xff0c;我们需要为想要进行碰撞检测的对象添…

2022-04-20 Unity入门7——物理系统之碰撞检测

文章目录 一、刚体 Rigid Body二、碰撞器 Collider三、物理材质四、碰撞检测函数五、刚体加力 一、刚体 Rigid Body ​ 刚体利用体积&#xff08;碰撞器 Collider&#xff09;进行碰撞计算&#xff0c;模拟真实的碰撞效果&#xff0c;产生力的作用 ​ 碰撞产生的必要条件&…

Unity3D —— 碰撞检测

&#xff08;一&#xff09;两种碰撞检测方式 &#xff08;1&#xff09;Collider&#xff1a;碰撞器 ➜需要与刚体一起添加到游戏对象上才能触发碰撞&#xff0c;没有碰撞体的刚体会彼此相互穿过。 碰撞信息检测函数&#xff1a; //碰撞开始 void OnCollisionEnter(Collis…

【Unity入门】24.碰撞检测

【Unity入门】碰撞检测 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity入门系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;一&#xff09;碰撞体 &#xff08;1&#xff09;Collider组件 上节课我们有学习到&#xff0c;unity的物理系统提供了更方便的碰撞…

Unity3D教程:简单的碰撞检测

需求&#xff1a;当立方体Cube碰到地面Plane的时候&#xff0c;输出碰撞物体的名称&#xff0c;则表述检测到立方体碰撞了地面。 1.搭建一个简单的场景。 在新的工程中选择File->new Scene创建新的场景。然后在该场景中添加地板&#xff1a;GameObject->Create Other-&…

Unity学习笔记(二) 碰撞检测与触发检测

正好看到了Roll a ball这个游戏&#xff0c;于是就温故一下碰撞检测和触发检测 1.前期准备 中间省去建造一些基础的物体的过程&#xff0c;最后呈现如下图 我们的主角就是中间的球体 其GameObject名为player,我们在其身上添上刚体组件(Rigidbody)使其可以进行物理移动 …

Python实战——过采样数据的处理之改进的SMOTE算法

文章目录 1 理论2 实现3 补充3.1 原理介绍3.1.1 欠采样与过采样3.1.2 Tomek Link 法欠采样3.1.3 Random Over Sampling 随机过采样3.1.4 SMOTE 过采样3.1.5 综合采样 3.2 Python实战3.2.1 数据探索3.2.2 不同的抽样方法对训练集进行处理3.2.2.1 拆分自变量与因变量3.2.2.2 抽样…

机器学习中非平衡数据的处理 —— smote算法

目录&#xff1a;SMOTE算法 1、不平衡数据的背景知识2、SMOTE算法的理论思想3、SMOTE模块的使用 1、不平衡数据的背景知识 在实际应用中&#xff0c;分类问题中类别的因变量可能存在严重的偏倚&#xff0c;即类别之间的比例严重失调&#xff0c;如欺诈问题&#xff0c;欺诈类观…

Python:SMOTE算法

17.11.28更新一下&#xff1a;最近把这个算法集成到了数据预处理的python工程代码中了&#xff0c;不想看原理想直接用的&#xff0c;有简易版的python开发&#xff1a;特征工程代码模版 &#xff0c;进入页面后ctrlF搜smote就行&#xff0c;请自取 之前一直没有用过python&…

探索SMOTE算法

摘要 SMOTE是一种综合采样人工合成数据算法&#xff0c;用于解决数据类别不平衡问题(Imbalanced class problem)&#xff0c;以Over-sampling少数类和Under-sampling多数类结合的方式来合成数据。本文将以Nitesh V. Chawla&#xff08;2002&#xff09;的论文为蓝本&#xff0…