销毁Actor对象
2024年1月7日 2024年1月11日
使用委托实现Actor对象的销毁
C++订阅委托
服务端提供服务, 在有需要的位置通知客户端
客户端注册服务, 给出回调函数
服务端通知客户端, 即调用客户端注册的回调函数
GeometryObject作为服务端
设置销毁定时器, 定时器到期, 通知客户端
定义委托类型
- | |
---|---|
服务端 | GeometryObject |
-
客户端只能是C++, 支持多客户端
-
回调函数接受一个参数
使用DECLARE_MULTICAST_DELEGATE_OneParam
1DECLARE_MULTICAST_DELEGATE_OneParam(FOnActorDestroy, AActor*);
定义委托类型数据成员
通过数据成员广播, 供客户端注册
- | |
---|---|
OnActorDestroy | 销毁Actor时通知客户端 |
GeometryObject
public
1FOnActorDestroy OnActorDestroy;
设置定时器
添加数据成员
- | ||
---|---|---|
DestroyTimer | 销毁定时器 | private |
DestroyTimerRate | 定时器时间间隔 | private |
GeometryObject
1FTimerHandle DestroyTimer; 2float DestroyTimerRate = 30.0f;
添加函数成员: 初始化定时器
private
在BeginPlay中调用
1void AGeometryObject::InitTimerDestroy() { 2 GetWorldTimerManager().SetTimer(DestroyTimer, this, 3 &AGeometryObject::OnTimerDestroy, 4 DestroyTimerRate, true); 5}
添加函数成员: 定时器回调函数
private
到期后关闭定时器, 并通知客户端
1void AGeometryObject::OnTimerDestroy() { 2 GetWorldTimerManager().ClearTimer(DestroyTimer); 3 OnActorDestroy.Broadcast(this); 4}
至此,委托服务器端的部署全部完成
GeometryHub作为客户端
添加函数成员: 委托处理函数
private
负责销毁Actor对象
1void AGeometryHub::OnActorDestroy(AActor *Actor) 2{ 3 if (!Actor) return; 4 UE_LOG(LogGeometryHub, Log, TEXT("Destroy Timer of Actor %s is UP"), *Actor->GetName()); 5 6 AGeometryObject *Geometry = Cast<AGeometryObject>(Actor); 7 if (!Geometry) return; 8 UE_LOG(LogGeometryHub, Log, TEXT("Next to DESTROY Actor %s"), *Geometry->GetName()); 9 10 Geometry->Destroy(); 11// Geometry->SetLifeSpan(2.0f); 12}
添加数据成员: 存放Actor类型
protected
需在虚幻编辑器中设置
1UPROPERTY(EditAnywhere) 2TSubclassOf<AGeometryObject> GeometryClassForDestroy;
添加函数成员: 创建Actor对象, 注册委托
private
在BeginPlay中调用
1void AGeometryHub::SpawnGeometryForDestroy() 2{ 3 UWorld* World = GetWorld(); 4 if (World) 5 { 6 const FTransform Transform = 7 FTransform(FRotator::ZeroRotator, FVector(300.0f, 0.0f, 800.0f)); 8 AGeometryObject* Geometry = World->SpawnActorDeferred<AGeometryObject>(GeometryClassForDestroy, Transform); 9 Geometry->OnActorDestroy.AddUObject(this, &AGeometryHub::OnActorDestroy); 10 Geometry->FinishSpawning(Transform); 11 12 } 13}
销毁Actor的两种方式
- | |
---|---|
Destroy | 直接销毁Actor |
SetLifeSpan | 延时销毁Actor |
销毁Actor时会调用EndPlay函数
重载EndPlay函数
-
给出EndPlay的声明
-
实现EndPlay
- 调用基类的EndPlay
- 输出日志
1void AGeometryObject::EndPlay(EEndPlayReason::Type EndPlayReason) { 2 Super::EndPlay(EndPlayReason); 3 UE_LOG(LogGeometry, Log, TEXT("EndPlay Called")); 4}
- 调用基类的EndPlay
-
查看日志