图像加上一些数学运算,一些逻辑,一些“物理”效果来模拟现实中的场景,最后和人进行交互,在加上一些奇思妙想这就是游戏。这篇博客会介绍虚幻4中基础的物理系统,和两种新手入门使用的碰撞检测方式

物理系统开启

在虚幻4中如果需要场景中某个对象能获得现实中的物理效果,必须先开启实例对象细节面板中的模拟物理才行。默认是没勾选的,只要勾选上之后,当前的实例对象在场景中便有了现实中的物理效果,这个时候就可以测试这个对象是否启动了物理,当没启动物理的时候,把一个物理拖拽到空中的时候,它会僵直在空中,但是启动了模拟物理之后,在启用重力,把一个物理拖拽到空中之后,它会向下坠落。
在这里插入图片描述

给对象力和力矩

力:给对象施加一个力时,对象会被施加的力推动
力矩:给对象一个力矩时,对象被力矩影响而开始旋转

只要让想受到力影响的对象调用AddForce函数,就能对其施加一个力,可以看到第一个参数是一个向量,就是力的方向,其余的两个参数有默认参数可以先不关注
在这里插入图片描述

只要让想受到力影响的对象调用AddTorque函数,就能对其施加一个力矩,可以看到第一个参数是一个向量,其余的两个参数有默认参数可以先不关注

以下就是施加力和力矩的函数原型

this->MyStaticMesh->AddForce(Vector, " NAME_None", this->bAccelChange);
this->MyStaticMesh->AddTorque(Vector, " NAME_None", this->bAccelChange);

但是这样施加的力会受物体的质量影响,要想这个力不受质量的影响只需要把第三个参数设置为true,那么这个力就是一个简单的加速度,不受对象本身质量影响,bAccelChange可以理解为是否把物体本身的质量加入到受力影响的结果
注意:要启动模拟物理之后,才能调用这两个函数,否则编译器会报错

通过物理碰撞

在开启了物理之后就不得不提到一个关键的词语碰撞,当一个对象和另一个对象叠加到一起的时候,在场景中正常情况下他们会彼此穿过,如果需要它们像现实中受碰撞影响,发生一些事情的时候,就不得不给他们设置上碰撞检测了。

简单碰撞

可以随意点开一个模型会进入到这样的界面,默认是没有碰撞的,这时候可以点击红色箭头处的碰撞,给它添加上系统默认的许多简单碰撞,盒体的,胶囊形的等等,也可以选择自动凸包碰撞,让系统根据模型的棱角计算合适的碰撞体,设置完碰撞体之后,该对象的可碰撞范围就和设置的碰撞体一样,虽然这个模型是多面体,如果设置一个正方形碰撞给它,它的可以碰撞范围就是一个正方体,这些都是简单碰撞,会有一些细微的地方碰撞计算不准确
在这里插入图片描述

复杂碰撞

在这里插入图片描述
在详情面板可以搜索到这样一个选项,碰撞复杂度,复杂碰撞就是根据模型详细的计算出碰撞,但是这样开销极大,除非特别要求,不然不建议使用,一般是使用项目默认,就是根据用户设置的碰撞等级,来进行碰撞,如果选择了简单用作复杂,那么所有的复杂碰撞都会用简单碰撞,反之则简单的碰撞都会用复杂碰撞,都不常用,也不友好。

碰撞预设

设置完碰撞体之后,对象就有了发生碰撞的能力,但是还是不能进行碰撞,因为碰撞是两个对象之间才能发生碰撞,需要在对象的细节模板,碰撞预设属性里,设置对象能和哪些对象碰撞,必须双方都能和对方碰撞才能进行碰撞
在这里插入图片描述
碰撞预设中可以选择已经设置好的预设直接使用,也可以选择custom自定义一组碰撞预设,选择完碰撞预设之后,在选择启动物理和查询,设置对象类型,对象类型就是设置碰撞效果时,标记是否会碰撞的标记,碰撞效果可以选择忽略,碰撞之后等于没有碰撞,重叠会产生碰撞到的信息,但是依然会穿过,阻挡就是现实中,物体碰撞到一起的撞击效果
注意:当双方都设置为对另一个物理可碰撞的时候才能进行碰撞

改变坐标的碰撞

有一个AddActorLocalOffset();函数,它的第一个参数是向量,让当前对象的坐标增加,通过这个函数把一个物体设置到另一个物体上面的时候,正常情况会出现穿过的情况,这时候可以传入第二个参数,当前位置有遮挡物是否被阻挡,设置为true,这样如果在逐帧函数Tick函数里使用AddActorLocalOffset()让当前对象移动到另一个对象上时就会被阻挡,并获得碰撞信息,传入第三个参数FHitResult类型就能获取到碰撞的相关信息

// 定义一个FHitResult类型用于接收碰撞信息
FHitResult fHitResult;

// 调用AddActorLocalOffset改变对象的坐标,第一个参数是移动的向量,第二个参数是是否被路径上的碰撞物体阻挡,第三个参数是接收碰撞信息
AddActorLocalOffset(Vector, true, &fHitResult);

// 通过fHitResult输出碰撞发生的坐标
UE_LOG(LogTemp, Warning, TEXT("X: %f,Y: %f,Z: %f"), fHitResult.Location.X, fHitResult.Location.Y, fHitResult.Location.Z);

注意在通过坐标检测碰撞的时候,要关闭模拟物理

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐