六一的部落格


关关难过关关过,前路漫漫亦灿灿。



使用委托实现Actor对象的销毁

C++订阅委托

服务端提供服务, 在有需要的位置通知客户端

客户端注册服务, 给出回调函数

服务端通知客户端, 即调用客户端注册的回调函数


GeometryObject作为服务端

设置销毁定时器, 定时器到期, 通知客户端


定义委托类型

-
服务端 GeometryObject
  1. 客户端只能是C++, 支持多客户端

  2. 回调函数接受一个参数

使用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函数

  1. 给出EndPlay的声明

  2. 实现EndPlay

    • 调用基类的EndPlay
    • 输出日志
    1void AGeometryObject::EndPlay(EEndPlayReason::Type EndPlayReason) {
    2    Super::EndPlay(EndPlayReason);
    3    UE_LOG(LogGeometry, Log, TEXT("EndPlay Called"));
    4}
  3. 查看日志


销毁Actor对象


使用委托实现Actor对象的销毁

C++订阅委托

服务端提供服务, 在有需要的位置通知客户端

客户端注册服务, 给出回调函数

服务端通知客户端, 即调用客户端注册的回调函数


GeometryObject作为服务端

设置销毁定时器, 定时器到期, 通知客户端


定义委托类型

-
服务端 GeometryObject
  1. 客户端只能是C++, 支持多客户端

  2. 回调函数接受一个参数

使用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函数

  1. 给出EndPlay的声明

  2. 实现EndPlay

    • 调用基类的EndPlay
    • 输出日志
    1void AGeometryObject::EndPlay(EEndPlayReason::Type EndPlayReason) {
    2    Super::EndPlay(EndPlayReason);
    3    UE_LOG(LogGeometry, Log, TEXT("EndPlay Called"));
    4}
  3. 查看日志