UE4 C++ —— 碰撞检测

简述
UE4集成了PhysX物理引擎,用来模拟刚体的物理行为,包括常用的碰撞响应。

碰撞基础概念
碰撞对象通道
每个碰撞体都会设置一种(Object Responses)碰撞对象通道,碰撞对象通道可以是ue4默认的几种,也可以新建自定义的碰撞对象通道


新建自定义的碰撞对象通道,点击Project Settings->Collision
在Collision窗口里,找到Object Channelse项,点击New Object Channelse新建碰撞类型,设置名称和默认响应类型,这里新建两个碰撞对象类型Cube, Sphere

 

碰撞响应设置

类型详解
NoCollision无碰撞响应
Query Only(No Physics Collision)只会触发Overlap(重叠)事件,无刚体碰撞响应
Physics Only(No Query Collision)只有刚体碰撞响应,不触发Overlap(重叠)事件
Collision Enabled(Query and Physics )刚体碰撞响应和Overlap(重叠)事件都可以

碰撞响应类型
两个物体发生碰撞时会产生不同的碰撞响应,
Block(碰撞) ,发生Block碰撞响应后,两个Actor之间会发生阻挡行为,并触发Hit事件
UFUNCTION()
void OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, FVector NormalImpulse, const FHitResult& Hit);

Overlap(重叠) ,发生Overlap碰撞响应后,会触发Generate Overlap Events事件

UFUNCTION()
virtual void OnOverlayEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

UFUNCTION()
virtual void OnOverlayEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

Ignore(忽略),两个Actor忽略碰撞响应

 

碰撞响应

触发Block条件
(1)两个物体的碰撞响应都设置为Block
(2)其中一个物体必须设为Physics(刚体),勾选Simulate Physics项。
(3)要触发Hit事件,需开启Simulate Generates Hit Events.
触发Overlap条件
(1)其中一个物体的碰撞响应为Overlap,任何一个物体的碰撞响应都不能设为Ignore
(2)要触发重叠事件,需开启Generate Overlap Events
Ignore条件
(1)其中一个物体的碰撞响应为Ignore

碰撞实例应用
新建C++工程,创建两个Actor,命名为CubeActor和AphereActor,这两个物体将进行碰撞响应


现在这两个Actor是空的,我们需要在C++中给他们添加StaticMesh,并进行事件绑定
源码
CubeActor.h

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "CubeActor.generated.h"

UCLASS()
class PROJECTDEMO1_API ACubeActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ACubeActor();

	UFUNCTION()
	virtual void OnOverlayBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult);

	UFUNCTION()
	virtual void OnOverlayEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

	UFUNCTION()
		void OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, FVector NormalImpulse, const FHitResult& Hit);

protected:

	//根组件
	class USceneComponent* RootScene;

	//静态模型
	UPROPERTY(EditAnywhere)
	class UStaticMeshComponent* StaticMesh;
};

CubeActor.cpp

#include "CubeActor.h"

// Sets default values
ACubeActor::ACubeActor()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	//实例化根组件
	RootScene = CreateDefaultSubobject<USceneComponent>(TEXT("RootScene"));
	RootComponent = RootScene;

	//创建静态模型组件
	StaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BaseMesh"));
	StaticMesh->SetupAttachment(RootComponent);
	StaticMesh->SetCollisionProfileName(FName("CubeProfile"));

	//绑定检测方法到碰撞体
	FScriptDelegate OverlayBegin;
	OverlayBegin.BindUFunction(this, "OnOverlayBegin");
	StaticMesh->OnComponentBeginOverlap.Add(OverlayBegin);

	FScriptDelegate OverlayEnd;
	OverlayEnd.BindUFunction(this, "OnOverlayEnd");
	StaticMesh->OnComponentEndOverlap.Add(OverlayEnd);

	FScriptDelegate DelegateHit;
	DelegateHit.BindUFunction(this, "OnHit");
	StaticMesh->OnComponentHit.Add(DelegateHit);
}

void ACubeActor::OnOverlayBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
	if (GEngine) {
		GEngine->AddOnScreenDebugMessage(-1, 20, FColor::Yellow, "Cube Begin---------");
	}
}

void ACubeActor::OnOverlayEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	if (GEngine) {
		GEngine->AddOnScreenDebugMessage(-1, 20, FColor::Yellow, "Cube End---------");
	}
}

void ACubeActor::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, FVector NormalImpulse, const FHitResult& Hit)
{
	if (GEngine) {
		GEngine->AddOnScreenDebugMessage(-1, 20, FColor::Yellow, "ACubeActor OnHit---------");
	}
}

注:在头文件中我们定义了三个函数,(OnOverlayBegin, OnOverlayEnd, OnHit)分别绑定Overlay进入事件,Overlay离开事件和刚体碰撞事件,这三个函数在事件触发后将打印语句到屏幕,接着定义了一个根组件和StaticMesh,在构造函数中创建组件和进行事件绑定,另一个AphereActor类的代码同上。


C++代码写完后,编译保存,打开编辑器,创建两个蓝图类,分别继承于CubeActor和SphereActor,命名为BP_CubeActor和BP_SphereActor。并添加三维模型。


Overlap(重叠)事件
我们想让BP_CubeActor和BP_SphereActor触发Overlap(重叠)事件,需要将BP_CubeActor和BP_SphereActor的碰撞对象通道分别设为Cube和Sphere,并把互相的碰撞响应设为Overlap
打开BP_CubeActor蓝图类,设置它的碰撞属性
勾选Generate Overlap Events,Collision Presets设置为customize(自定义),Collision Enabled设置为Query Only(No Physics Collision),Object Type设为Cube(前面自定义的碰撞对象通道),Sphere响应方式勾选为Overlap。


打开BP_SphereActor蓝图类,设置它的碰撞属性,设置方法相似。不同的是需要把Object Type设为Sphere,Cube响应方式勾选为Overlap。

碰撞属性配置完成后,实例化这两个Actor,将他们拖入Level中


打开关卡蓝图,让Sphere向Cube移动,触发Overlap(重叠)事件


编译运行,不断按下‘1’键,直到Sphere刚接触到Cube时,就会触发Overlap Begin事件,随之调用绑定到该事件的函数,打印语句到屏幕。同理,当Sphere离开Cube时,触发Overlap End事件。

Block(碰撞)事件
接下来我们要让BP_CubeActor和BP_SphereActor触发Block(碰撞)事件
打开BP_CubeActor蓝图类,设置碰撞属性,将Collision Enabled设置为Physics Only(No Query Collision),Sphere响应方式勾选为Block。


同上,设置BP_SphereActor的碰撞属性


在两个Actor实例中启用Simulate Generates Hit Events事件,并设置为Physics(刚体)


将Sphere拖动到Cube上方


编译运行,程序开始后Sphere受重力下落,触发Block事件,调用绑定函数,打印语句到屏幕


 

碰撞预制文件
除了前面的自定义碰撞属性,还可以使用碰撞预制文件来设置碰撞属性
点击Project Settings->Collision,打开Collision窗口。在Preset部分,点击New


设置名称和碰撞属性


创建两个碰撞预制文件,SphereProfile和CubeProfile

在蓝图中指定碰撞预制文件


也可以在C++代码中指定
StaticMesh->SetCollisionProfileName(FName("CubeProfile"));

### UE4 碰撞检测勾选项设置教程 在 Unreal Engine 4 (UE4) 中,碰撞检测是一个重要的功能,用于判断物体之间是否发生接触或重叠。为了实现有效的碰撞检测,正确配置对象的碰撞属性至关重要。 #### 配置静态网格体(Static Mesh) 对于静态网格体而言,在其细节面板中存在多个与碰撞有关的选择项: - **Collision Presets**: 提供预设好的碰撞模式,如无碰撞、阻挡所有、仅触发器等。选择合适的预设能够快速设定基本行为[^1]。 - **Custom Collision Response to Channels**: 自定义响应通道允许开发者指定当特定类型的实体接近该物件时应如何反应——忽略(Ignore),阻挡(Block),还是作为触发(Overlap)。 #### 动态角色及其他可移动Actor 针对动态角色或者其他可能改变位置的对象来说,则需关注以下几个方面来调整碰撞特性: - **Character Movement Component Settings**: 如果涉及到人物模型的话,那么在其运动组件内也有专门用来控制地面检测以及楼梯攀爬等功能的相关参数调节空间[^2]。 - **Simulation Generates Hit Events**: 对于那些启用物理模拟的角色或其他物体,此选项决定了它们是否会因为与其他物体相碰而产生命中事件(Hit Event)。这有助于捕捉并处理碰撞瞬间的信息变化[^3]。 #### 编辑蓝图中的碰撞形状 除了上述提到的内容外,还可以通过编辑蓝图里的`Simple Collision Shape`来自由设计更精确复杂的碰撞边界。例如将默认盒形改为球形或者胶囊状以适应不同需求下的交互逻辑[^4]。 ```cpp // C++代码示例:为Actor添加简单的球形碰撞体积 USphereComponent* SphereComp; SphereComp = CreateDefaultSubobject<USphereComponent>(TEXT("SphereCollider")); RootComponent = SphereComp; // 设置半径大小 SphereComp->SetSphereRadius(50.f); ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值