Klasa UActorComponent

UActorComponent klasa jest klasą bazową wykorzystywane do tworzenia komponentów, które mogą być dodawane do aktorów.

Instancja UActorComponent nie ma transformacji, nie może być dołączone do innego składnika i nie ma geometrii do renderowania lub użycia w kolizji. Istnieją podklasy UActorComponent, które dodają te funkcje.

Jako przykład spójrzmy na hierarchię klas klasy UStaticMeshComponent. Ta hierarchia jest dostępna w Unreal Engine API Reference.

Oto główne podklasy  UActorComponent:

  • USceneComponent:  Instancja tej klasy ma wartość Transform i może zostać dołączona do innego składnika. 
  • UPrimitiveComponent:  wystąpienie tej klasy ma lub generuje geometrię, która może być renderowana lub używana w kolizji. 

Jeśli chcesz uzyskać odwołanie do aktora zawierającego komponent, użyj funkcji GetOwner() w Component:

AActor* ActorOwner = GetOwner();

Przykładowe użycie :

Stworzymy ActorComponent, który będzie zawierał zmienne do przechowywania zdrowia, many i poziomu gracza. Komponent będzie miał funkcję UpgradeLevel(), która zwiększy poziom gracza i zaktualizuje maksymalne wartości zdrowia i many. Ten składnik może być używany w C ++ i Blueprints.

Utwórz klasę C ++ o nazwie HealthManaComponent, używając klasy Actor Component jako klasy nadrzędnej, jak pokazano na poniższym obrazku. 

Zobacz w pliku HealthManaComponent.h, że makro UCLASS ma pewne specyfikatory, które pozwalają na użycie komponentu w Blueprints. Dodaj zmienne i funkcje, jak pokazano w poniższym kodzie:

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "HealthManaComponent.generated.h"


UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class TUTOPROJECT_API UHealthManaComponent : public UActorComponent
{
  GENERATED_BODY()

public:	
  // Sets default values for this component's properties
  UHealthManaComponent();

  // Called every frame
  virtual void TickComponent(float DeltaTime, ELevelTick TickType,
                 FActorComponentTickFunction* ThisTickFunction) override;
	
  UFUNCTION(BlueprintPure, Category = HealthMana)
  int32 GetCurrentHealth();
	
  UFUNCTION(BlueprintCallable, Category = HealthMana)
  void SetCurrentHealth(int32 newHealth);
	
  UFUNCTION(BlueprintPure, Category = HealthMana)
  int32 GetCurrentMana();
	
  UFUNCTION(BlueprintCallable, Category = HealthMana)
  void SetCurrentMana(int32 newMana);
	
  UFUNCTION(BlueprintPure, Category = HealthMana)
  int32 GetPlayerLevel();
	
  UFUNCTION(BlueprintCallable, Category = HealthMana)
  void UpgradeLevel();
	
protected:
  // Called when the game starts
  virtual void BeginPlay() override;

  int32 CurrentHealth;
  int32 MaxHealth;
  
  int32 CurrentMana;
  int32 MaxMana;
  
  int32 PlayerLevel;
};

Funkcja FMath :: Clamp() została użyta w implementacji funkcji SetCurrentHealth() i SetCurrentMana(), aby zapobiec wartości mniejszej od zera lub większej od maksymalnej dozwolonej wartości.

Plik HealthManaComponent.cpp powinien mieć następującą zawartość:

#include "HealthManaComponent.h"

UHealthManaComponent::UHealthManaComponent()
{
  PrimaryComponentTick.bCanEverTick = true;

  CurrentHealth = 100;
  MaxHealth = 100;
  
  CurrentMana = 100;
  MaxMana = 100;
  
  PlayerLevel = 1;
}

int32 UHealthManaComponent::GetCurrentHealth()
{
  return CurrentHealth;	
}
	
void UHealthManaComponent::SetCurrentHealth(int32 NewHealth)
{
  CurrentHealth = FMath::Clamp<int32>(NewHealth, 0, MaxHealth);
}
	
int32 UHealthManaComponent::GetCurrentMana()
{
  return CurrentMana; 
}
	
void UHealthManaComponent::SetCurrentMana(int32 NewMana)
{
  CurrentMana = FMath::Clamp<int32>(NewMana, 0, MaxMana);
}

int32 UHealthManaComponent::GetPlayerLevel()
{
  return PlayerLevel;
}	
	
void UHealthManaComponent::UpgradeLevel()
{
  PlayerLevel++;

  MaxHealth = PlayerLevel * 100;
  CurrentHealth = MaxHealth;

  MaxMana = PlayerLevel * 100;
  CurrentMana = MaxMana;  
}

// Called when the game starts
void UHealthManaComponent::BeginPlay()
{
  Super::BeginPlay();
}

// Called every frame
void UHealthManaComponent::TickComponent(float DeltaTime, ELevelTick TickType,
                                FActorComponentTickFunction* ThisTickFunction)
{
  Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}  

Najpierw zobaczmy, jak używać HealthManaComponent w Blueprint. Skompiluj kod C ++ i utwórz Blueprint. Na karcie Blueprint Components kliknij przycisk Add Component. HealthManaComponent jest w niestandardowej kategorii, jak pokazano w tym obrazie:

Na wykresie zdarzeń Blueprint można uzyskać dostęp do funkcji HealthManaComponent:

Teraz użyjmy HealthManaComponent w klasie C +. Utwórz klasę C++ o nazwie TestUActorComponent, używając klasy Actor jako klasy nadrzędnej. Plik TestUActorComponent.h powinien mieć następującą zawartość:

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TestUActorComponent.generated.h"

UCLASS()
class TUTOPROJECT_API ATestUActorComponent : public AActor
{
  GENERATED_BODY()
	
public:	
  // Sets default values for this actor's properties
  ATestUActorComponent();

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)
  class UHealthManaComponent* HealthManaComponent;
	
  FTimerHandle TimerHandle;

  void UpgradePlayerLevel();
};    

TestUActorComponent klasa posiada stoper, który wywołuje UpgradePlayerLevel() funkcja co 5 sekund. Funkcja ta nazywa HealthManaComponent UpgradeLevel () funkcji, a następnie wyświetla składowe wartości prądu na ekranie.

Oto zawartość pliku TestUActorComponent.cpp:

#include "TestUActorComponent.h"
#include "HealthManaComponent.h"

// Sets default values
ATestUActorComponent::ATestUActorComponent()
{
  // Set this actor to call Tick() every frame.
  PrimaryActorTick.bCanEverTick = true;
	
  HealthManaComponent = CreateDefaultSubobject<UHealthManaComponent>(
                                              TEXT("HealthManaComponent"));

}

// Called when the game starts or when spawned
void ATestUActorComponent::BeginPlay()
{
  Super::BeginPlay();
	
  GetWorldTimerManager().SetTimer(TimerHandle, this,
       &ATestUActorComponent::UpgradePlayerLevel, 5.f, true);	
}

void ATestUActorComponent::UpgradePlayerLevel()
{
  HealthManaComponent->UpgradeLevel();
	
  FString Message = FString::Printf(TEXT("Level: %d - Health: %d - Mana: %d"), 
                                    HealthManaComponent->GetPlayerLevel(),
                                    HealthManaComponent->GetCurrentHealth(),
                                    HealthManaComponent->GetCurrentMana());
       
  if(GEngine)
  {
    GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, Message);
  }	
}

// Called every frame
void ATestUActorComponent::Tick(float DeltaTime)
{
  Super::Tick(DeltaTime);
}    

Skompiluj kod C ++ i dodaj instancje TestUActorComponent na swoim poziomie. Uruchom grę i poczekaj 5 sekund, aby zobaczyć komunikat na ekranie. Poniższy obrazek pokazuje, kiedy komponent osiągnął poziom 3:


Źródło:https://romeroblueprints.blogspot.com/2020/11/the-uactorcomponent-class.html