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


     目录

    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还需绑定按键 

    1. void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
    2. {
    3. Super::SetupPlayerInputComponent(PlayerInputComponent);
    4. PlayerInputComponent->BindAction("DropItem", EInputEvent::IE_Pressed, this, &AMyCharacter::DropItem);
    5. PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AMyCharacter::Jump);
    6. PlayerInputComponent->BindAxis("MoveForward", this, &AMyCharacter::MoveForward);
    7. PlayerInputComponent->BindAxis("MoveRight", this, &AMyCharacter::MoveRight);
    8. PlayerInputComponent->BindAxis("PitchCamera", this, &AMyCharacter::PitchCamera);
    9. PlayerInputComponent->BindAxis("YawCamera", this, &AMyCharacter::YawCamera);
    10. }

    事件:

    1. void AMyCharacter::MoveForward(float AxisValue)
    2. {
    3. MovementInput.X = FMath::Clamp<float>(AxisValue, -1.f, 1.f);
    4. }
    5. void AMyCharacter::MoveRight(float AxisValue)
    6. {
    7. MovementInput.Y = FMath::Clamp<float>(AxisValue, -1.f, 1.f);
    8. }
    9. void AMyCharacter::PitchCamera(float AxisValue)
    10. {
    11. CameraInput.Y = AxisValue;
    12. }
    13. void AMyCharacter::YawCamera(float AxisValue)
    14. {
    15. CameraInput.X = AxisValue;
    16. }

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

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

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

    1. //添加、绑定ActionKeyMapping轴映射 方法一
    2. FInputActionKeyMapping onFire("OnFire", EKeys::LeftMouseButton, 0, 0, 0, 0);
    3. UPlayerInput::AddEngineDefinedActionMapping(onFire);
    4. PlayerInputComponent->BindAction("OnFire", IE_Pressed, this, &AMyCharacter::OnFire);
    5. //添加、绑定ActionKeyMapping轴映射 方法二
    6. UPlayerInput::AddEngineDefinedActionMapping(FInputActionKeyMapping("Sprint",EKeys::LeftShift));
    7. PlayerInputComponent->BindAction("Sprint", IE_Pressed,this,&AMyCharacter::StartSprint);
    8. PlayerInputComponent->BindAction("Sprint", IE_Released,this,&AMyCharacter::StopSprint);
    9. //添加、绑定AxisMapping轴映射
    10. UPlayerInput::AddEngineDefinedAxisMapping(FInputAxisKeyMapping("Turn", EKeys::MouseX, 1.0f));
    11. 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等
    1. UPROPERTY(EditAnywhere)
    2. USceneComponent* Root;
    3. UPROPERTY(EditAnywhere)
    4. UStaticMeshComponent* Cube;
    5. UFUNCTION()
    6. virtual void OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
    7. UFUNCTION()
    8. virtual void OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
    9. UFUNCTION()
    10. virtual void OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);
    1. ACollisionActor::ACollisionActor()
    2. {
    3. // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
    4. PrimaryActorTick.bCanEverTick = true;
    5. Root = CreateDefaultSubobject(TEXT("RootScene"));
    6. SetRootComponent(Root);
    7. Cube = CreateDefaultSubobject(TEXT("Cube"));
    8. Cube->SetupAttachment(Root);
    9. static ConstructorHelpers::FObjectFinder mesh(TEXT("StaticMesh'/Engine/BasicShapes/Cube.Cube'"));
    10. if (mesh.Succeeded())
    11. {
    12. Cube->SetStaticMesh(mesh.Object);
    13. }
    14. // 设置是否开启物理模拟
    15. Cube->SetSimulatePhysics(false);
    16. // 开启 Generated Hit Event
    17. Cube->SetNotifyRigidBodyCollision(true);
    18. // 开启CCD Continuous collision detection (CCD) 连续式碰撞检测
    19. Cube->BodyInstance.SetUseCCD(true);
    20. // 开启Generate Overlap Events
    21. Cube->SetGenerateOverlapEvents(true);
    22. // 设置碰撞预设
    23. Cube->SetCollisionProfileName(TEXT("OverlapAll"));
    24. //Cube->SetCollisionResponseToAllChannels(ECR_Overlap);
    25. // 设置碰撞响应设置
    26. Cube->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
    27. // 绑定函数
    28. Cube->OnComponentBeginOverlap.AddDynamic(this, &ACollisionActor::OnOverlapBegin);
    29. // 绑定函数 使用委托
    30. FScriptDelegate OverlapEndDelegate;
    31. OverlapEndDelegate.BindUFunction(this, TEXT("OnOverlapEnd"));
    32. Cube->OnComponentBeginOverlap.Add(OverlapEndDelegate);
    33. // 绑定碰撞函数
    34. Cube->OnComponentHit.AddDynamic(this, &ACollisionActor::OnHit);
    35. }
    1. void ACollisionActor::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
    2. {
    3. UE_LOG(LogTemp, Warning, TEXT("Overlap Begin"));
    4. }
    5. void ACollisionActor::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
    6. {
    7. UE_LOG(LogTemp, Warning, TEXT("Overlap End"));
    8. }
    9. void ACollisionActor::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
    10. {
    11. UE_LOG(LogTemp, Warning, TEXT("Hit"));
    12. Destroy();
    13. }

    定时器Timer与事件绑定

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

    设置定时器:SetTimer

    • 支持FTimerDelegate委托,可以扩展使用Lambda表达式,可以带参数
    1. template<class UserClass>
    2. void SetTimer
    3. (
    4. FTimerHandle & InOutHandle,
    5. UserClass * InObj,
    6. typename FTimerDelegate::TUObjectMethodDelegate_Const< UserClass >::FMethodPtr InTimerMethod,
    7. float InRate,
    8. bool InbLoop,
    9. float InFirstDelay
    10. )
    1. FTimerHandle SpawnerHandle;
    2. GetWorldTimerManager().SetTimer(SpawnerHandle, this, &AEnenmySpawner::SpawnEnemy, 5.0f, true);
    3. void AEnenmySpawner::SpawnEnemy()
    4. {
    5. GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Red, "Spawn");
    6. }

     

    清空定时器:ClearTimer

    • ClearAllTimerForObject:清空与特定对象关联的所有定时器
    1. GetWorldTimerManager().ClearTimer(SpawnerHandle);
    2. // 参数传入一个对象,本例以 this 举例
    3. GetWorldTimerManagerr().ClearAllTimersForObject(this);

    暂停和恢复:PauseTimer和UnPauseTimer

    1. GetWorldTimerManager().PauseTimer(SpawnerHandle);
    2. GetWorldTimerManager().UnPauseTimer(SpawnerHandle);
    3. GetWorldTimerManager().IsTimerPaused(SpawnerHandle);

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

    GetWorldTimerManager().IsTimerActive(SpawnerHandle);
    

    获取定时器速率:GetTImerRate

    句柄若无效则返回-1

    GetWorldTimerManager().GetTimerRate(SpawnerHandle);
    

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


    句柄若无效,返回-1

    句柄若无效,返回-1

    1. GetWorldTimerManager().GetTimerElapsed(SpawnerHandle);
    2. GetWorldTimerManager().GetTimerRemaining(SpawnerHandle);
  • 相关阅读:
    还在用双层for循环吗?太慢了
    Linux的命令基本格式
    电脑视频转换成mp4格式,视频格式转换器转换
    游戏品类加速回暖,文娱内容持续火热——2022年IAA行业品类发展洞察系列报告·第三期
    【毕业设计】深度学习OCR中文识别系统 - opencv python
    在家怎么看公司电脑里的东西?如何查看
    VHDL基础知识笔记(1)
    SAS|format&proc tabulate
    JQuery UI——滑动条组件
    年轻人不用太过于努力
  • 原文地址:https://blog.csdn.net/Jason6620/article/details/126528304