任务:创建单播委托,实现触发器控制灯光的亮和灭
1、DelegateTestGameModeBase.h函数声明委托
DelegateTestGameModeBase.h代码如下:
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "DelegateTestGameModeBase.generated.h"
DECLARE_DELEGATE_OneParam(MyDelegate, bool) //bool参数控制灯光的亮灭,false表示灭,true表示亮
/**
*
*/
UCLASS()
class DELEGATETEST_API ADelegateTestGameModeBase : public AGameModeBase
{
GENERATED_BODY()
public:
MyDelegate myDefaultDelegate;
};
2、以Actor为基类创建TriggerListener类,在该类中实现灯光控制函数并绑定1中声明的委托,并且在游戏结束时委托解除绑定
TriggerListener.h代码如下:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TriggerListener.generated.h"
class UPointLightComponent;
UCLASS()
class DELEGATETEST_API ATriggerListener : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ATriggerListener();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
UPointLightComponent* PointLight;
UFUNCTION()
void LightControl(bool value);
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
};
TriggerListener.cpp代码如下:
// Fill out your copyright notice in the Description page of Project Settings.
#include "TriggerListener.h"
#include "Components\PointLightComponent.h"
#include "Components\SceneComponent.h"
#include "GameFramework\GameMode.h"
#include "Kismet\GameplayStatics.h"
#include "DelegateTestGameModeBase.h"
// Sets default values
ATriggerListener::ATriggerListener()
{
// 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;
PointLight = CreateDefaultSubobject<UPointLightComponent>(TEXT("PointLight"));
USceneComponent* componentTemp = CreateDefaultSubobject<USceneComponent>(TEXT("componentTemp"));
RootComponent = componentTemp;
PointLight->SetupAttachment(componentTemp);
}
// Called when the game starts or when spawned
void ATriggerListener::BeginPlay()
{
Super::BeginPlay();
PointLight->SetVisibility(false);
UWorld* TheWorld = GetWorld();
if (TheWorld)
{
AGameModeBase* GameMode = Cast<AGameModeBase>(UGameplayStatics::GetGameMode(this));
if (GameMode)
{
ADelegateTestGameModeBase* MyGameMode = Cast<ADelegateTestGameModeBase>(GameMode);
if (MyGameMode)
{
//委托绑定灯光控制函数EnableLight
MyGameMode->myDefaultDelegate.BindUObject(this, &ATriggerListener::LightControl);
}
}
}
}
//灯光控制函数:开灯
void ATriggerListener::LightControl(bool value)
{
PointLight->SetVisibility(value);
}
//游戏结束时解除委托绑定
void ATriggerListener::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
UWorld* TheWorld = GetWorld();
if (TheWorld)
{
AGameModeBase* GameMode = Cast<AGameModeBase>(UGameplayStatics::GetGameMode(this));
if (GameMode)
{
ADelegateTestGameModeBase* MyGameMode = Cast<ADelegateTestGameModeBase>(GameMode);
if (MyGameMode)
{
//委托解除绑定
MyGameMode->myDefaultDelegate.Unbind();
}
}
}
}
3、以Actor为基类创建MyTrigger类,在该类中实现1中声明的委托的触发
MyTrigger.h代码如下:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyTrigger.generated.h"
class UBoxComponent;
UCLASS()
class DELEGATETEST_API AMyTrigger : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AMyTrigger();
public:
UBoxComponent* TriggerBoxComp;
virtual void NotifyActorBeginOverlap(AActor* OtherActor);
virtual void NotifyActorEndOverlap(AActor* OtherActor);
};
MyTrigger.cpp代码如下:
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyTrigger.h"
#include "Components\BoxComponent.h"
#include "Engine.h"
#include "DelegateTestGameModeBase.h"
// Sets default values
AMyTrigger::AMyTrigger()
{
// 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;
TriggerBoxComp = CreateDefaultSubobject<UBoxComponent>(TEXT("TriggrBoxComp"));
RootComponent = TriggerBoxComp;
}
void AMyTrigger::NotifyActorBeginOverlap(AActor* OtherActor)
{
if (OtherActor)
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, FString::Printf(TEXT("%s is enter!"), *(OtherActor->GetName())));
UWorld* TheWorld = GetWorld();
if (TheWorld)
{
AGameModeBase* GameMode = Cast<AGameModeBase>(UGameplayStatics::GetGameMode(TheWorld));
if (GameMode)
{
ADelegateTestGameModeBase* MyGameMode = Cast<ADelegateTestGameModeBase>(GameMode);
if (MyGameMode)
{
//触发委托:灯光控制函数
MyGameMode->myDefaultDelegate.ExecuteIfBound(true);
}
}
}
}
}
void AMyTrigger::NotifyActorEndOverlap(AActor* OtherActor)
{
if (OtherActor)
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, FString::Printf(TEXT("%s is leave!"), *(OtherActor->GetName())));
UWorld* TheWorld = GetWorld();
if (TheWorld)
{
AGameModeBase* GameMode = Cast<AGameModeBase>(UGameplayStatics::GetGameMode(TheWorld));
if (GameMode)
{
ADelegateTestGameModeBase* MyGameMode = Cast<ADelegateTestGameModeBase>(GameMode);
if (MyGameMode)
{
//触发委托:灯光控制函数
MyGameMode->myDefaultDelegate.ExecuteIfBound(false);
}
}
}
}
}
灯光效果图如下: