// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "GameFramework/Actor.h"#include "TimeOfDayHandler.generated.h"// 定义了带有两个参数的代理,FOnTimeChangedSignature
DECLARE_MULTICAST_DELEGATE_TwoParams(FOnTimeChangedSignature, int32, int32)
UCLASS()
class BLANKUECPP_API ATimeOfDayHandler : public AActor
{
GENERATED_BODY()
public:
// Sets default values forthis actor's properties
ATimeOfDayHandler();
protected:
// Called when the game starts or when spawned
virtualvoidBeginPlay() override;
public:
// Called every frame
virtualvoidTick(float DeltaTime) override;
// 钟表走的速度
UPROPERTY()
int32 TimeScale;
UPROPERTY()
int32 Hours;
UPROPERTY()
int32 Minutes;
// 经过的时间
UPROPERTY()
float ElapsedSeconds;
// 声明代理
FOnTimeChangedSignature OnTimeChanged;
};
// Fill out your copyright notice in the Description page of Project Settings.#include"BlankUECPP.h"#include"TimeOfDayHandler.h"// Sets default values
ATimeOfDayHandler::ATimeOfDayHandler()
{
// 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;
// 让分钟当秒走
TimeScale =60;
Hours =0;
Minutes =0;
ElapsedSeconds =0.0f;
RootComponent = CreateDefaultSubobject<UBillboardComponent>(TEXT("BillBoard"));
}
// Called when the game starts or when spawnedvoid ATimeOfDayHandler::BeginPlay()
{
Super::BeginPlay();
}
// Called every framevoid ATimeOfDayHandler::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//GEngine->AddOnScreenDebugMessage(-1, 0.5f, FColor::Red, FString::Printf(TEXT("%f"),DeltaTime);
ElapsedSeconds += (DeltaTime*TimeScale);
if (ElapsedSeconds >=60)
{
ElapsedSeconds -=60;
Minutes++;
}
if (Minutes >=60)
{
Minutes -=60;
Hours++;
}
GEngine->AddOnScreenDebugMessage(-1, 0.5f, FColor::Red, FString::Printf(TEXT("M:%d H:%d"), Minutes,Hours));
// 执行代理,传出两个参数,传给绑定当前代理的函数// 是这一条语句让DemoClock里边的时钟一直不断的执行
OnTimeChanged.Broadcast(Hours, Minutes);
}
DemoClock
加载素材资源,绑定代理
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "GameFramework/Actor.h"#include "DemoClock.generated.h"
UCLASS()
class BLANKUECPP_API ADemoClock : public AActor
{
GENERATED_BODY()
public:
// Sets default values forthis actor's properties
ADemoClock();
protected:
// Called when the game starts or when spawned
virtualvoidBeginPlay() override;
public:
// Called every frame
virtualvoidTick(float DeltaTime) override;
// 目标绑定函数void TimeChanged(int32 Hours,int32 Minutes);
public:
UPROPERTY()
UStaticMeshComponent* ClockFace;
UPROPERTY()
UStaticMeshComponent* HourHand;
UPROPERTY()
UStaticMeshComponent* MinuteHand;
UPROPERTY()
USceneComponent* HourHandle;
UPROPERTY()
USceneComponent* MinuteHandle;
FDelegateHandle DelegateHandle;
};
// Fill out your copyright notice in the Description page of Project Settings.#include"BlankUECPP.h"#include"DemoClock.h"#include"TimeOfDayHandler.h"// Sets default values
ADemoClock::ADemoClock()
{
// 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;
// SceneComponent 这个叫场景组件
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("SceneRoot"));
HourHandle=CreateDefaultSubobject<USceneComponent>(TEXT("HourHandle"));
MinuteHandle= CreateDefaultSubobject<USceneComponent>(TEXT("MinuteHandle"));
ClockFace = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ClockFace"));
HourHand= CreateDefaultSubobject<UStaticMeshComponent>(TEXT("HourHand"));
MinuteHand= CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MinuteHand"));
ConstructorHelpers::FObjectFinder<UStaticMesh> meshAsset(TEXT("StaticMesh'/Engine/BasicShapes/Cylinder.Cylinder'"));
if (meshAsset.Object)
{
ClockFace->SetStaticMesh(meshAsset.Object);
HourHand->SetStaticMesh(meshAsset.Object);
MinuteHand->SetStaticMesh(meshAsset.Object);
}
ClockFace->SetupAttachment(RootComponent);
ClockFace->SetRelativeTransform(FTransform(FRotator(0,0,90),FVector(0,0,0),FVector(2,2,0.5)));
HourHand->AttachToComponent(HourHandle,FAttachmentTransformRules::KeepRelativeTransform);
MinuteHand->AttachToComponent(MinuteHandle, FAttachmentTransformRules::KeepRelativeTransform);
HourHandle->SetupAttachment(RootComponent);
MinuteHandle->SetupAttachment(RootComponent);
HourHand->SetRelativeTransform(FTransform(FRotator(0, 0, 0), FVector(0, 55, 25), FVector(0.1, 0.1, 0.5)));
MinuteHand->SetRelativeTransform(FTransform(FRotator(0, 0, 0), FVector(0, 60, 50), FVector(0.1, 0.1, 1)));
}
// Called when the game starts or when spawnedvoid ADemoClock::BeginPlay()
{
Super::BeginPlay();
TArray<AActor*> TimeOfDayHandlers;
// 获得关卡中所有的ATimeOfDayHandle类型的Actor,并把他们放到TimeOfDayHandlers的数 组中。
UGameplayStatics::GetAllActorsOfClass(GetWorld(),ATimeOfDayHandler::StaticClass(),TimeOfDayHandlers);
if (TimeOfDayHandlers.Num() !=0)
{
// auto 可以自动推断timeOfDayHandler的类型
auto timeOfDayHandler = Cast<ATimeOfDayHandler>(TimeOfDayHandlers[0]);
// 这个是绑定当前代理
DelegateHandle = timeOfDayHandler->OnTimeChanged.AddUObject(this, &ADemoClock::TimeChanged);
}
}
// Called every frame
void ADemoClock::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void ADemoClock::TimeChanged(int32 Hours, int32 Minutes)
{
HourHandle->SetRelativeRotation(FRotator(-30*Hours,0,0));
MinuteHandle->SetRelativeRotation(FRotator(-6*Minutes,0,0));
}