Używanie Components w C++

W tym artykule utworzymy podklasę AActor zawierającą kilka komponentów, aby pokazać w praktyce, jak są one używane w C ++.

Oto komponenty, które zostaną użyte w przykładzie:

  • Scene Component : jest używany jako główny komponent aktora.
  • Static Mesh Component: Zawiera statyczną siatkę, która wizualnie reprezentuje aktora.
  • Capsule Component : Komponent używany do testu kolizji.
  • Particle System Component : zawiera emiter cząstek.
  • Point Light Component : komponent, który emituje światło we wszystkich kierunkach z punktu.
  • Rotating Movement Component : służy do ciągłego obracania aktora.
  • Audio Component : służy do odtwarzania dźwięku w miejscu, w którym znajduje się aktor. 

Przykładowe Użycie:

W tym przykładzie potrzebujesz zawartość ze Starter Content.

Stwórzmy krzesło elektryczne. Cała jego funkcjonalność będzie realizowana za pomocą komponentów. Będzie emitowała system particle z iskramia, a komponent audio z dźwiękiem iskier. Będzie zawierał czerwony punkt światła oraz stale się obracał.

Utwórz klasę C ++ o nazwie ElectricChair, używając klasy Actor jako klasy nadrzędnej. W pliku ElectricChair.h zdefiniuj wszystkie komponenty i zadeklaruj funkcję PostInitializeComponents(), jak pokazano na poniższym kodzie:

#pragma once

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

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

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 PostInitializeComponents() override;
	
	UPROPERTY(VisibleAnywhere)
	USceneComponent* RootScene;

	UPROPERTY(VisibleAnywhere)
	UStaticMeshComponent* StaticMeshComponent;
	
	UPROPERTY(VisibleAnywhere)
	class UCapsuleComponent* CapsuleComponent;
	
	UPROPERTY(VisibleAnywhere)	
	class UParticleSystemComponent* ParticleSystemComponent;
	
	UPROPERTY(VisibleAnywhere)	
	class UPointLightComponent* PointLightComponent;
	
	UPROPERTY(VisibleAnywhere)
	class URotatingMovementComponent* RotatingMovementComponent; 

	UPROPERTY(VisibleAnywhere)
	class UAudioComponent* AudioComponent;
	
	UPROPERTY(VisibleAnywhere, Category = Sound)
	class  USoundCue* SparksSoundCue;
};

W pliku cpp musimy dodać linie #include z plikami nagłówkowymi klas komponentów. Aby dowiedzieć się, jak #include klasę, poszukaj jej w Unreal Engine API Reference . 

W konstruktorze klas ładowane są zasoby Static Mesh, Particle System i SoundCue. Aby uzyskać ścieżkę do zasobu w edytorze Unreal, kliknij Asset prawym przyciskiem myszy i wybierz opcję Copy Reference .

Konstruktor zawiera inicjalizacje komponentów. Plik ElectricChair.cpp powinien mieć następującą zawartość:

#include "ElectricChair.h"
#include "Engine/CollisionProfile.h"
#include "Components/CapsuleComponent.h"
#include "Components/PointLightComponent.h"
#include "Components/AudioComponent.h"
#include "Particles/ParticleSystemComponent.h"
#include "GameFramework/RotatingMovementComponent.h"
#include "Sound/SoundCue.h"
#include "Engine/EngineTypes.h"


// Sets default values
AElectricChair::AElectricChair()
{
  // Set this actor to call Tick() every frame.
  PrimaryActorTick.bCanEverTick = true;

  // RootComponent initialization 
  RootScene = CreateDefaultSubobject<USceneComponent>(TEXT("RootScene"));
  RootComponent = RootScene;

  // CapsuleComponent initialization
  CapsuleComponent = CreateDefaultSubobject<UCapsuleComponent>(
                                           TEXT("CapsuleComponent"));
  CapsuleComponent->InitCapsuleSize(44.f, 60.f);
  CapsuleComponent->SetCollisionProfileName(
                      UCollisionProfile::BlockAllDynamic_ProfileName);
  CapsuleComponent->SetupAttachment(RootScene);
  CapsuleComponent->SetRelativeLocation(FVector(0.f, 0.f, 60.f));

  // StaticMeshComponent initialization
  StaticMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(
                                              TEXT("StaticMeshComponent"));
  StaticMeshComponent->SetCollisionProfileName(
                         UCollisionProfile::NoCollision_ProfileName);
  StaticMeshComponent->SetMobility(EComponentMobility::Movable);
  StaticMeshComponent->SetupAttachment(RootScene);
  
  ConstructorHelpers::FObjectFinder<UStaticMesh> MeshFile(
    TEXT("/Game/StarterContent/Props/SM_Chair.SM_Chair"));

  if (MeshFile.Succeeded())
  {
    StaticMeshComponent->SetStaticMesh(MeshFile.Object);
  }
  
  // AudioComponent initialization
  AudioComponent = CreateDefaultSubobject<UAudioComponent>(TEXT("AudioComponent"));
  AudioComponent->SetupAttachment(RootScene);
	
  ConstructorHelpers::FObjectFinder<USoundCue> SoundCueFile(
    TEXT("/Game/StarterContent/Audio/Fire_Sparks01_Cue.Fire_Sparks01_Cue"));
  
  if (SoundCueFile.Succeeded())
  {
    SparksSoundCue = SoundCueFile.Object;
  }
  
  // ParticleSystemComponent initialization
  ParticleSystemComponent = CreateDefaultSubobject<UParticleSystemComponent>(
                                                TEXT("ParticleSystemComponent"));
  
  ConstructorHelpers::FObjectFinder<UParticleSystem> ParticleTemplate(
    TEXT("/Game/StarterContent/Particles/P_Sparks.P_Sparks"));

  if (ParticleTemplate.Succeeded())
  {
    ParticleSystemComponent->SetTemplate(ParticleTemplate.Object);
  }
  
  ParticleSystemComponent->SetAutoActivate(true);
  ParticleSystemComponent->SetupAttachment(StaticMeshComponent);
  ParticleSystemComponent->SetRelativeLocation(FVector(-30.f, 0.f, 110.f));
  
  // PointLightComponent initialization
  PointLightComponent = CreateDefaultSubobject<UPointLightComponent>(
                                              TEXT("PointLightComponent"));
  PointLightComponent->SetIntensity(1000.f);
  PointLightComponent->SetLightColor(FLinearColor(1.f, 0.2f, 0.2f)); //RED color
  PointLightComponent->SetupAttachment(RootScene);
  PointLightComponent->SetRelativeLocation(FVector(0.f, 0.f, 100.f));
  
  // RotatingMovementComponent initialization
  RotatingMovementComponent = CreateDefaultSubobject<URotatingMovementComponent>(
                                                  TEXT("RotatingMovementComponent"));
  RotatingMovementComponent->SetUpdatedComponent(StaticMeshComponent);
  RotatingMovementComponent->RotationRate = FRotator(0.f, 90.f, 0.f);
}

void AElectricChair::PostInitializeComponents() 
{
  Super::PostInitializeComponents();
	
  AudioComponent->SetSound(SparksSoundCue);	
}

void AElectricChair::BeginPlay()
{
  Super::BeginPlay();
	
  AudioComponent->Play();
}

void AElectricChair::Tick(float DeltaTime)
{
  Super::Tick(DeltaTime);
}

Przypisanie SoundCue do Audio Component należy wykonać w funkcji PostInitializeComponents (). Ta funkcja jest wywoływana po zainicjowaniu wszystkich komponentów aktora.

Hierarchia między komponentami jest tworzona za pomocą funkcji SetupAttachment(). Jedynym składnikiem, który nie jest częścią hierarchii, jest URotatingMovementComponent, ponieważ ta klasa nie dziedziczy po USceneComponent i dlatego nie ma transformacji .

Skompiluj kod C ++ i dodaj instance ElectricChair na poziomie. Zobacz hierarchię komponentów w zakładce Details:

Uruchom grę i zobacz, jak krzesło elektryczne obraca się z efektem i dźwiękiem iskier. Postawiłem krzesło elektryczne na ciemnym poziomie. Wyglądało to tak: 


Źródło:https://romeroblueprints.blogspot.com/2020/11/using-components-in-c.html