在前一文中介绍了如安在UE4中创建简单碰撞或者直接使用其mesh暗示的复杂碰撞: 那么在拿到碰撞之后,就可以进行物理运算,主要是碰撞查询和物理仿真,这里先介绍更为常见的碰撞查询。 最为直观的碰撞查询就是人物的移动物理了,你所控制的人物不掉落地板之外或者碰到障碍物就被阻挡,这其实是碰撞查询在背后起作用,如下动图: 我们也可以让人物直接穿过盒子,如下: 人物的移动物理本身是一块非常多的内容,我在文末会给出一些不错的分析文章,在这里只要知道移动距离是按照初中物理所学s=v*t得到的,v是当前人物的移动速度,而t是移动时长,在游戏里面t是很小的时间片。游戏中并不会有真正的“连续”移动,当t足够小的时候,每次移动量也很小,将人物SetActorLocation到这个小移动量暗示的世界坐标里,就可以得到看似连续的移动效果,本质是极小量的瞬移。 在每次计算移动位移时,都会进行碰撞查询,具体是用人物的胶囊体向速度标的目的进行扫略,它返回的结果是一个比例,如果比例是1.0,那么就可以执行完整的瞬移,而如果比例是0.5,就只能执行一半长度的瞬移,如果是0,就不进行任何移动。那么为何第一张动图被阻挡不能执行完整瞬移,第二张动图就偏偏可以呢? 这与“两方”的碰撞设置有关,碰撞是两个物件碰撞盒相交才会发生的事情,所以这里首先强调两方。碰撞响应总共有三个选项:Ignore,Overlap,Block。顾名思义,Ignore忽略碰撞,Block就是阻挡,而Overlap与Ignore类似,不会产生阻挡,但会产生重合的事件通知。两两组合就有下面的情况(图来自于https://www.unrealengine.com/zh-CN/blog/collision-filtering,也是一篇不错的碰撞查询入门文章): 其实只要记住两点: (1)只有两个对象互相Block时,才会真正的被阻挡,其他情况都不会; (2)只要有一方Ignore,就不会产生Overlap的重合事件; 在编纂器里,选中这个白盒子,在这里配置碰撞信息(Collison Preset,碰撞预设): 默认是Default,切换成其他的碰撞预设都能看到具体的碰撞响应,但大多都不成编纂(只读),如下图: 只有切成Custom...才可编纂: 我们来别离说下这些配置: CollisionEnabled决定了碰撞的用途,如下: NoCollision:如果是这个,那么其他碰撞设置都会被忽略不计,因为不再考虑碰撞了; Query Only:仅用于查询,不会考虑物理仿真; Physics Only:仅用于物理仿真,不考虑查询; Collision Enabled(Query and Physics):同时用于查询与仿真; 人物的移动物理属于查询,我们选择Query Only就行。 ObjectType决定了物体本身是什么碰撞类型,可选类型如下(也可以在ProjectSettings里面添加,后面会谈到): WorldStatic:静态几何物件,如山石,树干等; WorldDynamic:动态几何物件,如房门,地面可拾取物等; Pawn:人物或类人的东西,如玩家,野怪; PhysicsBody:物理体; Vehicle:载具,如摩托车,飞机等; Destructible:可破坏物件,如栅栏,窗户等; ObjectType配置的自由度很高,你也可以把石头配置成载具的ObjectType,只是这样在处理其他物件对它的响应时要绕得过来,一般不会做这种坑人坑己的事情。 碰撞响应决定了该对象对其他碰撞类型的响应,如下图: 仔细看可以发现碰撞响应还会细分成Trace Response与Object Response,个人理解其实不同不大,主要是通道过滤比力便利,直观理解射线检测类的配置成Trace Response,对象移动类的配置成Object Response就可以了。ObjectResponses列举出来的情况正是之前我们谈到的ObjectType的枚举,上图应解释成:白盒子对这几种碰撞类型的对象都是阻挡响应。 我们以第三人称人物为例,他本身碰撞类型是Pawn,如下: 注意我们看的是ObjectType,而不是上面的CollisionPresets。对人物而言,它对WorldStatic的响应是Block: 对于白盒子而言,它自身碰撞类型正是WorldStatic,而对Pawn的响应是Block,如下: 两两的碰撞响应都是Block,所以会发生阻挡。而如果将箱子对于人物的响应换成Ignore,如下: 则人物可以穿过箱子(大家试试看~)。 综上,每个物件的碰撞信息分成两块可配置: 其一,自身的碰撞类型ObjectType; 其二,这个物件对于其他碰撞类型对象的响应; 如果A的ObjectType是AO,B的ObjectType是BO,假定A配置成了Block BO,同时B配置成了Block AO,那么就会形成阻挡响应,彼此不能通过对方。 下面说下如何自定义碰撞类型,在菜单栏里面选择ProjectSettings,如下: 然后在左侧导航这里选择Engine->Collision,如下: 右侧可以新建自定义的ObjectChannels,TraceChannels以及Presets,前面提到过ObjectChannels与TraceChannels的区别主要在于通道的过滤,ObjectChannels还会创建一个同名的ObjectType。 对于ObjectChannels的碰撞响应过滤,我们使用蓝图中这个结点SingleSphereTraceForObjects(C++里面也有对应的函数),如下: 注意到ObjectTypes这里选择要过滤的通道,上图暗示只有ObjectType为Pawn或者是PhysicsBody的对象才会被碰撞检测到,其他类型的对象则被忽略。 对于TraceChannels的碰撞,使用的是SingleSphereTraceByChannel这个结点,如下: 注意这里的通道过滤项是TraceChannel,上图暗示只有配置成Block Weapon这个Channel的对象才会被检测到(表现在蓝图右侧OutHit输出结果上)。 此外,还有一些直观的理解,当你考虑的是对象移动时发生的碰撞,就用ObjectChannel(一开始UE的叫法是MovementChannels),如Pawn,StaticMesh;若考虑是射线检测时发生的碰撞,就用TraceChannel,如Weapon,Visibility。 举个例子,我们在ObjectChannel里面新加一个名为Pickup(暗示地上的可拾取物)的碰撞Channel,如下: 将默认的碰撞响应配置成了Block,以使pickup默认会被其他碰撞类型阻挡(如果不想让人行走时被pickup拦下,可以在去修正某个Pickup对ObjectType为Pawn的响应。 在TraceChannel里面新加一个名为Weapon(暗示枪的射线检测)的碰撞Channel,如下: 并将默认响应配置成了Block,即对默认对象类型来说枪射线会被阻挡。 回到编纂器场景窗口,并选中白盒子,查下其碰撞信息,如下: 可以看到TraceResponses和ObjectResponses这里已经多了之前添加的项目了。并且在ObjectType这里可以看到同名的ObjectResponses,如下: 还有一个Presets的自定义没说,回到Project setting这里: 所谓Presets就是碰撞预设,它是将一些常用的碰撞响应配置记录下来,这样以后新添一个对象时,就不用本身选择Custom,然后逐一勾选对不同ObjectType的响应了。比如这里我们配置一下Pickup的响应如下: 这样就可以看到PickupPreset最下面一行多了新加项(这里UE有一个UI上面的BUG,右侧的滚动条在第一次打开ProjectSetting是不会显示,也就无法向下滚动,这时只要再单击下Preset就可以了)。 这样我们就可以一键配置想要的碰撞信息了: 这里稍稍提到了LineTrace的蓝图配置,打算再分出一章详细说下蓝图里面的各种Trace,也是属于碰撞查询这个门类,就放到碰撞查询(下)里面说。 补一下UE移动这块非常好的文章: 《Exploring in UE4》移动组件详解[原理分析] UE4的移动碰撞 UE4人物移动同步算法 作者:Jerry 专栏地址:https://zhuanlan.zhihu.com/p/60840943 |
小黑屋|在路上 ( 蜀ICP备15035742号-1 )
GMT+8, 2024-11-25 18:25
Copyright 2015-2024 djqfx