在UE4刚开始学习碰撞检测的时候,发现重叠事件和碰撞相应函数无法调用,经过自己反复实验,找到了一些机制,现在记录下来。
- 首先定义一个Actor用来检测重叠事件和碰撞事件
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "OverlapActor.generated.h"
UCLASS()
class TRACELENGTH_API AOverlapActor : public AActor {
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AOverlapActor();
UPROPERTY(VisibleAnywhere, Category = "Pickup")
class UStaticMeshComponent* PickupMesh;
UPROPERTY(VisibleAnywhere, Category = "Pickup")
class UBoxComponent* OverlapBox;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UFUNCTION()
void BeginOverlap(UPrimitiveComponent*OverlappedComponent, AActor* OtherActor, UPrimitiveComponent*OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
UFUNCTION()
void EndOverlap(UPrimitiveComponent*OverlappedComponent, AActor* OtherActor, UPrimitiveComponent*OtherComp, int32 OtherBodyIndex);
UFUNCTION()
void ComponentHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "OverlapActor.h"
#include "Components/StaticMeshComponent.h"
#include "Components/BoxComponent.h"
// Sets default values
AOverlapActor::AOverlapActor() {
// 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;
PickupMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("PickupMesh"));
SetRootComponent(PickupMesh);
OverlapBox = CreateDefaultSubobject<UBoxComponent>(TEXT("OverlapBox"));
OverlapBox->SetupAttachment(GetRootComponent());
}
// Called when the game starts or when spawned
void AOverlapActor::BeginPlay() {
Super::BeginPlay();
OverlapBox->OnComponentBeginOverlap.AddDynamic(this, &AOverlapActor::BeginOverlap);
OverlapBox->OnComponentEndOverlap.AddDynamic(this, &AOverlapActor::EndOverlap);
PickupMesh->OnComponentHit.AddDynamic(this, &AOverlapActor::ComponentHit);
}
// Called every frame
void AOverlapActor::Tick(float DeltaTime) {
Super::Tick(DeltaTime);
}
void AOverlapActor::BeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) {
UE_LOG(LogTemp, Warning, TEXT("BeginOverlap"));
}
void AOverlapActor::EndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex) {
UE_LOG(LogTemp, Warning, TEXT("EndOverlap"));
}
void AOverlapActor::ComponentHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit) {
UE_LOG(LogTemp, Warning, TEXT("ComponentHit"));
}
对应的蓝图如下:
2. 设置场景
在场景中仿真这个Actor,并且放置一个立方体Cube2在它的正上方,用来检测重叠和碰撞事件
3. 检测重叠事件
3.1. 勾选Cube2 ,【细节面板】->【物理】->【模拟物理】和【启用重力】
3.2. 勾选 Cube2【碰撞】->【生产重叠事件】
3.3. 勾选BP_OverlapActor下的OverlapBox->【生产重叠事件】
这样就可以检测重叠事件了,当运行的时候,上方的立方体掉落下来,日志中就会输出相应的信息
4. 检测碰撞事件
只有勾选向BP_OverlapActor下面的组件PickupMesh->【模拟生产命中事件】
运行日志就会打印出来碰撞日志
3.碰撞检测还有另外一种方法,就是在Actor中实现函数NotifyActorBeginOverlap
当Actor与另外一个Actor触发时的重叠时的触发事件,例如一个玩家走进触发器;当物体阻塞发生碰撞时,撞击墙壁,
注意 bGenerateOverlapEvents 必须为 true;
public:
void NotifyActorBeginOverlap(AActor* otherActor)override;
void ATestActor::NotifyActorBeginOverlap(AActor* otherActor) {
Super::NotifyActorBeginOverlap(otherActor);
AGameCharacter* gameCharacter = Cast<AGameCharacter>(otherActor);
if (gameCharacter){
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("ATestActor::NotifyActorBeginOverlap"));
}
}
aaa