UE4_代理示例_时钟

时钟

TimeOfDayHandler
  注册代理,执行代理

// 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 for this actor's properties
    ATimeOfDayHandler();

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public: 
    // Called every frame
    virtual void Tick(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 spawned
void ATimeOfDayHandler::BeginPlay()
{
    Super::BeginPlay();

}

// Called every frame
void 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 for this actor's properties
    ADemoClock();

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public: 
    // Called every frame
    virtual void Tick(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 spawned
void 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));
}

猜你喜欢

转载自blog.csdn.net/longyanbuhui/article/details/76269079