UE4 C++:事件绑定(输入、碰撞检测、定时器)

本文介绍虚幻引擎中输入事件、碰撞检测与定时器的绑定方法。覆盖轴映射、动作映射设置,碰撞响应配置及定时器管理,提供C++实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 目录

Input输入事件绑定

轴映射与动作映射:SetupPlayerInputComponent

编辑器设置对应名称、代码设置响应事件,实现具体动作

C++设置添加轴和动作映射

碰撞检测事件绑定

碰撞对象通道与预设

碰撞响应设置:是否模拟物理碰撞以及触发Overlap事件

碰撞响应类型:Blokc、Overlap、Ignore

C++实现

定时器Timer与事件绑定

设置定时器:SetTimer

清空定时器:ClearTimer

暂停和恢复:PauseTimer和UnPauseTimer

判断是否活跃且未暂停:IsTimerActive

获取定时器速率:GetTImerRate

获取经过时间和剩余时间:GetTimerElapsed & GetTimerRemaining


虚幻引擎中的碰撞响应参考 | 虚幻引擎5.0文档 (unrealengine.com)

变量、定时器和事件 | 虚幻引擎5.0文档 (unrealengine.com) 

 虚幻引擎中的Gameplay定时器 | 虚幻引擎5.0文档 (unrealengine.com)

Input输入事件绑定

轴映射与动作映射:SetupPlayerInputComponent

编辑器设置对应名称、代码设置响应事件,实现具体动作

绑定名称及事件,Action还需绑定按键 

void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	PlayerInputComponent->BindAction("DropItem", EInputEvent::IE_Pressed, this, &AMyCharacter::DropItem);
	PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AMyCharacter::Jump);
	PlayerInputComponent->BindAxis("MoveForward", this, &AMyCharacter::MoveForward);
	PlayerInputComponent->BindAxis("MoveRight", this, &AMyCharacter::MoveRight);
	PlayerInputComponent->BindAxis("PitchCamera", this, &AMyCharacter::PitchCamera);
	PlayerInputComponent->BindAxis("YawCamera", this, &AMyCharacter::YawCamera);
}

事件:

void AMyCharacter::MoveForward(float AxisValue)
{
	MovementInput.X = FMath::Clamp<float>(AxisValue, -1.f, 1.f);
}

void AMyCharacter::MoveRight(float AxisValue)
{
	MovementInput.Y = FMath::Clamp<float>(AxisValue, -1.f, 1.f);
}

void AMyCharacter::PitchCamera(float AxisValue)
{
	CameraInput.Y = AxisValue;
}

void AMyCharacter::YawCamera(float AxisValue)
{
	CameraInput.X = AxisValue;
}

设置按键,游戏暂停可以继续响应

InputComponent->BindAction("ESCEvent", IE_Pressed, this, &ASLAiPlayerController::ESCEvent).bExecuteWhenPaused=true;//游戏暂停可以执行

C++设置添加轴和动作映射

	//添加、绑定ActionKeyMapping轴映射 方法一
	FInputActionKeyMapping onFire("OnFire", EKeys::LeftMouseButton, 0, 0, 0, 0);
	UPlayerInput::AddEngineDefinedActionMapping(onFire);
	PlayerInputComponent->BindAction("OnFire", IE_Pressed, this, &AMyCharacter::OnFire);

	//添加、绑定ActionKeyMapping轴映射 方法二
	UPlayerInput::AddEngineDefinedActionMapping(FInputActionKeyMapping("Sprint",EKeys::LeftShift));
	PlayerInputComponent->BindAction("Sprint", IE_Pressed,this,&AMyCharacter::StartSprint);
	PlayerInputComponent->BindAction("Sprint", IE_Released,this,&AMyCharacter::StopSprint);

	//添加、绑定AxisMapping轴映射
	UPlayerInput::AddEngineDefinedAxisMapping(FInputAxisKeyMapping("Turn", EKeys::MouseX, 1.0f));
	PlayerInputComponent->BindAxis("Turn", this, &AMyCharacter::OnTurn);

碰撞检测事件绑定

碰撞对象通道与预设

  • 默认提供碰撞对象类型,如WorldStatic、WorldDynamic等,允许用户自定义
  • 默认提供碰撞预设,如NoCollision、BlockAll、OverlapAll。允许用户自定义

碰撞响应设置:是否模拟物理碰撞以及触发Overlap事件

碰撞响应类型:Blokc、Overlap、Ignore

C++实现

  • 注意Overlap Begin/End 的函数参数
  • 注意OnHit的函数参数
  • 注意Generated Hit Event的函数名
  • 绑定函数可以用AddDynamic,也可以用FScriptDelegate委托
  • 部分设置可不写,蓝图使用时再手动设置
  • 写法支持UShapeComponent及其派生类,如USphereComponent、UBoxComponent等
    UPROPERTY(EditAnywhere)
		USceneComponent* Root;

	UPROPERTY(EditAnywhere)
		UStaticMeshComponent* Cube;

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

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

	UFUNCTION()
		virtual void OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);
ACollisionActor::ACollisionActor()
{
 	// 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;

	Root = CreateDefaultSubobject<USceneComponent>(TEXT("RootScene"));
	SetRootComponent(Root);

	Cube = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Cube"));
	Cube->SetupAttachment(Root);
	static ConstructorHelpers::FObjectFinder<UStaticMesh> mesh(TEXT("StaticMesh'/Engine/BasicShapes/Cube.Cube'"));
	if (mesh.Succeeded())
	{
		Cube->SetStaticMesh(mesh.Object);
	}

	// 设置是否开启物理模拟
	Cube->SetSimulatePhysics(false);

	// 开启 Generated Hit Event
	Cube->SetNotifyRigidBodyCollision(true);
	
	// 开启CCD Continuous collision detection (CCD) 连续式碰撞检测
	Cube->BodyInstance.SetUseCCD(true);
	
	// 开启Generate Overlap Events
	Cube->SetGenerateOverlapEvents(true);

	// 设置碰撞预设
	Cube->SetCollisionProfileName(TEXT("OverlapAll"));
	//Cube->SetCollisionResponseToAllChannels(ECR_Overlap);

	// 设置碰撞响应设置
	Cube->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);

	// 绑定函数
	Cube->OnComponentBeginOverlap.AddDynamic(this, &ACollisionActor::OnOverlapBegin);

	// 绑定函数 使用委托
	FScriptDelegate OverlapEndDelegate;
	OverlapEndDelegate.BindUFunction(this, TEXT("OnOverlapEnd"));
	Cube->OnComponentBeginOverlap.Add(OverlapEndDelegate);
	
	// 绑定碰撞函数
	Cube->OnComponentHit.AddDynamic(this, &ACollisionActor::OnHit);
}
void ACollisionActor::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	UE_LOG(LogTemp, Warning, TEXT("Overlap Begin"));
}

void ACollisionActor::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	UE_LOG(LogTemp, Warning, TEXT("Overlap End"));
}

void ACollisionActor::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
	UE_LOG(LogTemp, Warning, TEXT("Hit"));
	Destroy();
}

定时器Timer与事件绑定

  • 定时执行操作,可执行一次,或循环执行直到手动终止
  • 定时器在全局定时管理器(FTimerManager类型)中管理。全局定时器管理器存在于游戏实例对象上以及每个场景中
  • 定时器需要绑定委托或函数、作为执行体。这些函数将填充FTimerHandle定时器句柄
  • FTimerHandle支持暂停、恢复倒计时;查询或更改剩余时间;取消定时器
  • 设置定时器的函数
    • SetTimer 定时执行
    • SetTimerForNextTick 下一帧执行
  • 案例
    • 定时SpawnActor
    • 定时销毁
    • buff持续、如霸体、持续伤害

设置定时器:SetTimer

  • 支持FTimerDelegate委托,可以扩展使用Lambda表达式,可以带参数
template<class UserClass>
void SetTimer
(
    FTimerHandle & InOutHandle,
    UserClass * InObj,
    typename FTimerDelegate::TUObjectMethodDelegate_Const< UserClass >::FMethodPtr InTimerMethod,
    float InRate,
    bool InbLoop,
    float InFirstDelay
)
FTimerHandle SpawnerHandle;

GetWorldTimerManager().SetTimer(SpawnerHandle, this, &AEnenmySpawner::SpawnEnemy, 5.0f, true);	

void AEnenmySpawner::SpawnEnemy()
{
	GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Red, "Spawn");
}

 

清空定时器:ClearTimer

  • ClearAllTimerForObject:清空与特定对象关联的所有定时器
GetWorldTimerManager().ClearTimer(SpawnerHandle);

// 参数传入一个对象,本例以 this 举例
GetWorldTimerManagerr().ClearAllTimersForObject(this);

暂停和恢复:PauseTimer和UnPauseTimer

GetWorldTimerManager().PauseTimer(SpawnerHandle);
GetWorldTimerManager().UnPauseTimer(SpawnerHandle);
GetWorldTimerManager().IsTimerPaused(SpawnerHandle);

判断是否活跃且未暂停:IsTimerActive

GetWorldTimerManager().IsTimerActive(SpawnerHandle);

获取定时器速率:GetTImerRate

句柄若无效则返回-1

GetWorldTimerManager().GetTimerRate(SpawnerHandle);

获取经过时间和剩余时间:GetTimerElapsed & GetTimerRemaining


句柄若无效,返回-1

句柄若无效,返回-1

GetWorldTimerManager().GetTimerElapsed(SpawnerHandle);
GetWorldTimerManager().GetTimerRemaining(SpawnerHandle);
<think>好的,用户想查找与UE4C++相关的开发资料或教程,以及API文档。首先,我需要回忆一下之前提供的引用内容,看看有没有相关的资源。引用[3]提到了UE4 C++纯Slate开发沙盒游戏的教程,这可能对用户有帮助。另外,引用[1]、[2]、[4]虽然主要关于UE5,但UE4UE5在C++开发上有一定的相似性,可能可以作为参考。 接下来,我应该整理这些引用中的相关信息。比如,引用[3]详细介绍了使用Slate进行界面开发,但用户可能需要知道Slate和UMG的区别,以及推荐的学习路径。此外,用户可能需要官方文档的链接,但引用中没有直接提到UE4的官方API链接,可能需要补充说明。 然后,考虑到用户可能遇到的挑战,比如UE4UE5之间的差异,以及如何找到适合的教程。需要建议用户注意版本兼容性问题,并推荐社区资源如CSDN博客和官方论坛。 另外,用户可能需要了解学习路径,比如从基础到进阶的内容,包括Actor创建、组件系统、Slate/UMG界面开发等。需要分步骤列出,并引用相关资源中的示例。 最后,生成相关问题时要覆盖用户可能进一步询问的方向,比如版本差异、性能优化、学习资源推荐等。确保问题具有针对性,帮助用户深入探索。</think>### UE4 C++ 开发教程与API文档整理 #### 一、核心学习资源 1. **官方文档** - [Unreal Engine 4 C++ Programming Guidelines](https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/ProgrammingWithCPP/) 包含基础语法、类结构、模块化编程等内容,适合系统性学习[^3]。 2. **社区教程推荐** - **CSDN博客《UE4 C++纯Slate开发沙盒游戏()》** 详细讲解如何用C++和Slate框架实现界面开发,但需注意Slate的复杂性(建议优先使用UMG)[^3]。 ```cpp // Slate界面示例代码片段 SNew(SVerticalBox) + SVerticalBox::Slot() .AutoHeight() [ SNew(SButton) .Text(FText::FromString("Start Game")) .OnClicked(this, &HUDWidget::OnStartGameClicked) ] ``` - **UE5教程的兼容性参考** 虽然引用[1][2][4]主要针对UE5,但核心C++开发逻辑与UE4相通,例如Actor创建、组件系统等[^2][^4]。 #### 二、关键开发方向 1. **基础开发流程** - **Actor与组件**:通过C++创建自定义Actor并添加移动组件(参考UE5教程中的小球移动案例)[^2]。 - **事件绑定**:实现输入事件响应与逻辑分离(如键盘控制角色移动)。 2. **界面开发选择** - **UMG(推荐)**:可视化UI设计工具,结合C++逻辑更高效[^3]。 - **Slate(高级)**:纯代码界面开发,适合定制化需求但学习成本高。 3. **网络与多人在线** - 参考UE5的在线子系统(OnlineSubsystem)配置方法,UE4中类似功能需查看[Online Subsystem文档](https://docs.unrealengine.com/4.27/en-US/API/Plugins/OnlineSubsystem/)[^4]。 #### 三、常见问题与工具 1. **调试技巧** - 使用`UE_LOG`输出日志,结合Visual Studio断点调试。 - 通过`GEngine->AddOnScreenDebugMessage`实时显示变量值。 2. **性能优化** - 避免高频Tick事件,改用定时器(`FTimerHandle`)。 - 使用Profiler工具分析内存与CPU占用。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值