本笔记的记录了碰撞的用法,并使用C++和蓝图混合开发。入门示例成品。
碰撞
UBoxComponent类似于Unity的BoxCollider。
设置碰撞启用状态
设置UBoxComponent仅仅是检测有没有物体和它重叠,还是带物理碰撞,可以调用SetCollisionEnabled,类似Unity的BoxCollider的IsTrigger属性。
// 设置碰撞启用:纯查询(无物理碰撞)
TriggerBox->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
ECollisionEnabled的取值如下。
namespace ECollisionEnabled
{
enum Type
{
NoCollision, // 没有物理碰撞,也不查询重叠
QueryOnly, // 仅查询重叠,无物理碰撞
PhysicsOnly, // 仅物理碰撞,无查询重叠
QueryAndPhysics, // 查询重叠,且带物理碰撞
};
}
指定物体碰撞类型
类似于Unity的GameObject的layer的概念。设置自身的碰撞类型如下。
// 设置自身对象类型:WorldStatic
TriggerBox->SetCollisionObjectType(ECollisionChannel::ECC_WorldStatic);
ECollisionChannel类型可以到“设置 > 项目设置…… > 碰撞 > Object Channels”里设置自定义类型,其枚举值可以到DefaultEngine.ini里取查找。
设置自定义碰撞矩阵的例子如下。
// 先设置忽略所有频道的碰撞,再设置对Pawn的碰撞为Overlap
TriggerBox->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);
TriggerBox->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Overlap);
设置监听重叠的监听函数
类似Unity的OnTriggerEnter和OnTriggerExit。
// Box监听函数,函数声明可以F12查看TriggerBox->OnComponentBeginOverlap的声明
UFUNCTION()
void OnBoxOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
// Box监听函数,函数声明可以F12查看TriggerBox->OnComponentEndOverlap的声明
UFUNCTION()
void OnBoxOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
void ATriggerableDoor::BeginPlay()
{
Super::BeginPlay();
TriggerBox->OnComponentBeginOverlap.AddDynamic(this, &ATriggerableDoor::OnBoxOverlapBegin);
TriggerBox->OnComponentEndOverlap.AddDynamic(this, &ATriggerableDoor::OnBoxOverlapEnd);
}
void ATriggerableDoor::OnBoxOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
}
void ATriggerableDoor::OnBoxOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
}
一些蓝图相关的UFUNCTION函数说明符
BlueprintImplementableEvent
声明了UFUNCTION(BlueprintImplementableEvent)的函数作为蓝图的事件使用,且不需要写函数实现(即使Visual Studio报绿色波浪下划线也不要管它)。
// BlueprintImplementableEvent的蓝图事件不需要写函数实现,作为蓝图的事件使用
UFUNCTION(BlueprintImplementableEvent, Category = "Triggerable Door|Trigger Switch")
void RaiseTrigger();
BlueprintCallable
声明了UFUNCTION(BlueprintCallable)的函数作为蓝图的方法使用,需要写函数实现。
// BlueprintCallable作为蓝图的function使用,需要由函数实现
UFUNCTION(BlueprintCallable, Category = "Triggerable Door|Trigger Switch")
void UpdateTriggerLocation(FVector Offset);
BlueprintNativeEvent
声明了UFUNCTION(BlueprintNativeEvent)的函数作为蓝图的事件使用,可以写函数实现,但是实现函数名需要加上后缀“_Implementation”(即使Visual Studio报红/绿色波浪下划线也不要管它)。
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Triggerable Door|Door Switch")
void SpawnActor();
void ATriggerableDoor::SpawnActor_Implementation()
{
}
BlueprintPure
声明了UFUNCTION(BlueprintNativeEvent)的函数作为蓝图的方法使用,需要写函数实现,只有输出引脚,蓝图编辑时候不需要拉生命线。
UFUNCTION(BlueprintPure, Category = "SpawnVolume")
TSubclassOf<AActor> GetSpawnActorClass();