Tworzenie Delegates w C++
W tym artykule pokaże ci jak tworzyć delegates w C ++. W prosty sposób możemy zdefiniować Delegata jako odniesienie do funkcji.
Unreal Engine ma szeroką gamę typów delegatów, co utrudnia zrozumienie wszystkich tych opcji.
Z tego powodu w tym artykule skupimy się na użytecznym przykładzie funkcjonalnym, który możesz dostosować do swojego projektu.
W pierwszej części artykułu przedstawię kroki niezbędne do korzystania z Delegata, pokazując fragmenty przykładowego kodu. W przykładowym użyciu zobaczysz pełny przykładowy kod.
W tym przykładzie utworzymy klasę o nazwie APlatformTrigger . Gdy Aktor nakłada się na wystąpienie APlatformTrigger , delegat zostanie użyty do powiadomienia, że platforma została aktywowana. Inne klasy mogą wiązać funkcje z delegatem, które zostaną wykonane po aktywowaniu platformy.
Oto kroki niezbędne do utworzenia delegata:
Krok 1 – Utwórz typ delegata
Unreal Engine ma kilka makr, które są używane do tworzenia typu delegata. Poniższy kod utworzył typ delegata o nazwie FDelegateTrigger .
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDelegateTrigger);
To makro musi znajdować się w pliku nagłówkowym klasy APlatformTrigger powyżej makra UCLASS () . Ten delegat jest DYNAMICZNY, aby umożliwić wiązanie w Blueprints i MULTICAST, aby umożliwić powiązanie więcej niż jednej funkcji.
Krok 2 – Zdefiniuj zmienną przy użyciu utworzonego typu delegata
Poniższy wiersz definiuje zmienną typu FDelegateTrigger . Makro UPROPERTY (BlueprintAssignable) jest używane, aby umożliwić powiązanie w Blueprints.
UPROPERTY(BlueprintAssignable)
FDelegateTrigger OnPlatformTriggered;
Krok 3 – Uruchom delegata
W naszym przykładzie delegat zostanie wykonany, gdy platforma się nakłada. Odbywa się to przez wywołanie funkcji Broadcast () zmiennej Delegate.
OnPlatformTriggered.Broadcast();
Kolejne kroki są wykonywane w innej klasie C ++. W tym przykładzie jest to klasa o nazwie AExplosionHandle .
Krok 4 – Zdefiniuj wskaźnik do klasy, która ma delegata
Wskaźnik jest zdefiniowany jako UPROPERTY (), dzięki czemu instancję APlatformTrigger można wybrać w edytorze poziomów.
UPROPERTY(EditAnywhere, Category = "Delegate Test")
APlatformTrigger* PlatformTriggerInstance;
Krok 5 – Zdefiniuj UFUNCTION (), który będzie powiązany z Delegatem
W tym przykładzie jest funkcja o nazwie Explode () , która aktywuje system cząstek.
UFUNCTION()
void Explode();
Krok 6 – Powiązanie funkcji z delegatem
Wiązanie jest wykonywane w funkcji BeginPlay () . Wskaźnik PlatformTriggerInstance służy do wywoływania funkcji AddDynamic () zmiennej delegata OnPlatformTriggered .
PlatformTriggerInstance->OnPlatformTriggered.AddDynamic(this,
&AExplosionHandle::Explode);
Kiedy Delegat APlatformTrigger klasy jest wykonywany, Explode () funkcja AExplosionHandle klasie zostanie wywołana.
W przykładowym użyciu zobaczymy również, jak łączyć się za pomocą schematów.
Przykładowe użycie:
W tym przykładzie będziesz potrzebować projektu C ++, który ma szablon trzeciej osoby z zawartością startową .
Utwórz klasę C ++ o nazwie PlatformTrigger, używając klasy Actor jako klasy nadrzędnej. Plik PlatformTrigger.h zawiera makro, które tworzy typ Delegate FDelegateTrigger i zmienną zdefiniowaną za pomocą tego typu:
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "PlatformTrigger.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDelegateTrigger);
UCLASS()
class TUTOPROJECT_API APlatformTrigger : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
APlatformTrigger();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
virtual void NotifyActorBeginOverlap(AActor* OtherActor) override;
UPROPERTY(VisibleAnywhere)
USceneComponent* RootScene;
UPROPERTY(VisibleAnywhere)
UStaticMeshComponent* StaticMeshComponent;
UPROPERTY(BlueprintAssignable)
FDelegateTrigger OnPlatformTriggered;
};
PlatformTrigger klasa używa Static Mesh Shape_Cylinder . Wysokość zmniejszono, zmieniając skalę na 0,1 na osi Z. Delegat jest wykonywany w funkcji NotifyActorBeginOverlap () . Oto zawartość pliku PlatformTrigger.cpp:
#include "PlatformTrigger.h"
// Sets default values
APlatformTrigger::APlatformTrigger()
{
// Set this actor to call Tick() every frame.
PrimaryActorTick.bCanEverTick = true;
RootScene = CreateDefaultSubobject<USceneComponent>("RootScene");
RootComponent = RootScene;
StaticMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>("StaticMesh");
StaticMeshComponent->SetupAttachment(RootScene);
ConstructorHelpers::FObjectFinder<UStaticMesh> MeshFile(
TEXT("/Game/StarterContent/Shapes/Shape_Cylinder.Shape_Cylinder"));
if (MeshFile.Succeeded())
{
StaticMeshComponent->SetStaticMesh(MeshFile.Object);
}
StaticMeshComponent->SetCollisionResponseToAllChannels(
ECollisionResponse::ECR_Overlap);
StaticMeshComponent->SetRelativeScale3D(FVector(1.0f, 1.0f, 0.1f));
}
void APlatformTrigger::NotifyActorBeginOverlap(AActor* OtherActor)
{
Super::NotifyActorBeginOverlap(OtherActor);
OnPlatformTriggered.Broadcast();
}
// Called when the game starts or when spawned
void APlatformTrigger::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void APlatformTrigger::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
Utwórz kolejną klasę C ++ o nazwie ExplosionHandle, używając klasy Actor jako klasy nadrzędnej. Ta klasa ma wskaźnik do klasy PlatformTrigger i ma funkcję UFUNCTION (), która zostanie powiązana z delegatem. Plik ExplosionHandle.h wygląda następująco:
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "ExplosionHandle.generated.h"
UCLASS()
class TUTOPROJECT_API AExplosionHandle : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AExplosionHandle();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UPROPERTY(VisibleAnywhere)
USceneComponent* RootScene;
UPROPERTY(VisibleAnywhere)
class UParticleSystemComponent* ParticleSystemComponent;
UPROPERTY(EditAnywhere, Category = "Delegate Test")
class APlatformTrigger* PlatformTriggerInstance;
UFUNCTION()
void Explode();
};
W konstruktorze mamy konfigurację układu cząstek, który reprezentuje eksplozję. W funkcji BeginPlay () funkcja Explode () jest powiązana z delegatem. Nie zapomnij dodać niezbędnego #include . Oto zawartość pliku ExplosionHandle.cpp:
#include "ExplosionHandle.h"
#include "PlatformTrigger.h"
#include "Particles/ParticleSystemComponent.h"
// Sets default values
AExplosionHandle::AExplosionHandle()
{
// Set this actor to call Tick() every frame.
PrimaryActorTick.bCanEverTick = true;
// RootComponent initialization
RootScene = CreateDefaultSubobject<USceneComponent>("RootScene");
RootComponent = RootScene;
// ParticleSystemComponent initialization
ParticleSystemComponent = CreateDefaultSubobject<UParticleSystemComponent>(
TEXT("ParticleSystemComponent"));
ParticleSystemComponent->SetupAttachment(RootScene);
ParticleSystemComponent->SetAutoActivate(false);
ConstructorHelpers::FObjectFinder<UParticleSystem> ParticleTemplate(
TEXT("/Game/StarterContent/Particles/P_Explosion.P_Explosion"));
if (ParticleTemplate.Succeeded())
{
ParticleSystemComponent->SetTemplate(ParticleTemplate.Object);
}
}
void AExplosionHandle::BeginPlay()
{
Super::BeginPlay();
if(PlatformTriggerInstance)
{
PlatformTriggerInstance->OnPlatformTriggered.AddDynamic(this,
&AExplosionHandle::Explode);
}
}
void AExplosionHandle::Explode()
{
ParticleSystemComponent->Activate();
}
void AExplosionHandle::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
Skompiluj kod C ++ i dodaj wystąpienie PlatformTrigger na poziomie. Dodaj instancję ExplosionHandle w pobliżu platformy i na karcie Szczegóły instancji w kategorii Delegate Test wybierz instancję PlatformTrigger .

Zacząć gre. Kiedy nachodzisz na platformę z Postacią, wybuch zostanie aktywowany.

Teraz powiążmy niestandardowe zdarzenie z delegatem za pomocą schematów.
Wybierz wystąpienie PlatformTrigger, które znajduje się na poziomie i otwórz Blueprint poziomu.
Kliknij prawym przyciskiem myszy na wykresie zdarzeń i wybierz opcję Utwórz odniesienie do PlatformTrigger .
Przeciągnij z niebieskiej szpilki węzła i upuść go na wykresie zdarzeń, aby wyświetlić menu kontekstowe. Wyszukaj platformę i wybierz opcję Assign On Platform Triggered . Spowoduje to dodanie węzła Bind i nowego zdarzenia niestandardowego.
Dodaj Event BeginPlay i połącz się z węzłem Bind Event . Dodaj czynność Drukuj ciąg i połącz się z węzłem zdarzenia niestandardowego. Umieść wiadomość w węźle Print String i skompiluj Level Blueprint. Ostateczny schemat wygląda następująco:
Uruchom ponownie grę. Gdy platforma jest aktywna, delegat wywoła funkcję, która aktywuje eksplozję, a także wywoła niestandardowe zdarzenie zdefiniowane w Blueprints:
Źródło:https://romeroblueprints.blogspot.com/2021/01/creating-delegates-in-c.html