当前位置:网站首页>Unity 射线与碰撞范围检测【踩坑记录】
Unity 射线与碰撞范围检测【踩坑记录】
2022-07-08 00:52:00 【地狱火堡垒】
射线检测
射线检测在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.position
或Rigidbody2D.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的方式,采用发射子弹之前,先发射射线,记录碰撞点(判断是否会发生碰撞),然后在发射子弹。
边栏推荐
- 常见的磁盘格式以及它们之间的区别
- Introduction to ADB tools
- 《ClickHouse原理解析与应用实践》读书笔记(7)
- Little knowledge about TXE and TC flag bits
- [knowledge map] interpretable recommendation based on knowledge map through deep reinforcement learning
- 需要思考的地方
- CorelDRAW2022下载安装电脑系统要求技术规格
- 线程死锁——死锁产生的条件
- metasploit
- The circuit is shown in the figure, r1=2k Ω, r2=2k Ω, r3=4k Ω, rf=4k Ω. Find the expression of the relationship between output and input.
猜你喜欢
XMeter Newsletter 2022-06|企业版 v3.2.3 发布,错误日志与测试报告图表优化
[knowledge map paper] r2d2: knowledge map reasoning based on debate dynamics
C language -cmake cmakelists Txt tutorial
Master go game through deep neural network and tree search
Beaucoup d'enfants ne savent pas grand - chose sur le principe sous - jacent du cadre orm, non, ice River vous emmène 10 minutes à la main "un cadre orm minimaliste" (collectionnez - le maintenant)
Kwai applet guaranteed payment PHP source code packaging
Key points of data link layer and network layer protocol
nmap工具介紹及常用命令
COMSOL --- construction of micro resistance beam model --- final temperature distribution and deformation --- addition of materials
MQTT X Newsletter 2022-06 | v1.8.0 发布,新增 MQTT CLI 和 MQTT WebSocket 工具
随机推荐
关于TXE和TC标志位的小知识
MySQL查询为什么没走索引?这篇文章带你全面解析
metasploit
生命的高度
Redission源码解析
Nanny level tutorial: Azkaban executes jar package (with test samples and results)
Mouse event - event object
Talk about the realization of authority control and transaction record function of SAP system
In the digital transformation of the financial industry, the integration of business and technology needs to go through three stages
[knowledge atlas paper] minerva: use reinforcement learning to infer paths in the knowledge base
Exit of processes and threads
Wechat applet uniapp page cannot jump: "navigateto:fail can not navigateto a tabbar page“
微信小程序uniapp页面无法跳转:“navigateTo:fail can not navigateTo a tabbar page“
《ClickHouse原理解析与应用实践》读书笔记(7)
List of top ten domestic industrial 3D visual guidance enterprises in 2022
How to use diffusion models for interpolation—— Principle analysis and code practice
文盘Rust -- 给程序加个日志
leetcode 866. Prime Palindrome | 866. 回文素数
Reading notes of Clickhouse principle analysis and Application Practice (7)
"Hands on learning in depth" Chapter 2 - preparatory knowledge_ 2.1 data operation_ Learning thinking and exercise answers