Klasa TutoProjectCollectable – Components

W tym artykule stworzymy klasę TutoProjectCollectable i zdefiniujemy jej komponenty. Ta klasa jest aktorem i reprezentuje przedmiot, który może zebrać gracz.

W Content Browser przejdź do folderu TutoProject, który znajduje się w folderze C++ Classes. Kliknij prawym przyciskiem myszy wolne miejsce i wybierz opcję “New C ++ Class …“.

Na następnym ekranie wybierz Actor jako klasę parent (nadrzędną) i kliknij przycisk Next.

Na ostatnim ekranie wpisz TutoProjectCollectable w polu Name i kliknij przycisk Create Class

Użyj Static Mesh component, aby wizualnie przedstawić tę klasę w grze. Static Mesh, która ma być używany, to SM_Statue z materiałem M_Metal_Gold. Są nieodłączną częścią zawartości Starter Content. Static Mesh będzie wyglądać następująco:

Otwórz plik TutoProjectCollectable.h. Zwróć uwagę, że kod wygenerowany przez Unreal Engine dwukrotnie używa modyfikatora public: access. To jest prawidłowy kod, ale wolimy trzymać publiczne zmienne i funkcje w jednym miejscu. Skopiuj deklarację funkcji Tick (float DeltaTime), umieść ją pod konstruktorem ATutoProjectCollectable() i usuń drugi public: block.

Utworzymy dwa wskaźniki dla komponentów, jeden dla składnika Static Mesh, a drugi dla składnika sceny. Komponent sceny zostanie użyty jako Root, abyśmy mogli zdefiniować względne położenie Static Mesh. Publiczny: blok TutoProjectCollectable.h będzie wyglądał następująco:

#pragma once

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

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

	// Called every frame
	virtual void Tick(float DeltaTime) override;
    
   	UPROPERTY(VisibleAnywhere)
	USceneComponent* RootScene;

	UPROPERTY(VisibleAnywhere)
	UStaticMeshComponent* StaticMesh;

...

Omówimy makro UPROPERTY () w następnym artykule.

Konfiguracja komponentów odbywa się w pliku TutoProjectCollectable.cpp wewnątrz konstruktora ATutoProjectCollectable(). Poniższy kod przedstawia tworzenie USceneComponent, do którego będzie odwoływał się wskaźnik RootScene. Następnie następuje przypisanie wskaźnika do RootComponent w celu wskazania, że ten składnik będzie głównym elementem Actor Root.

RootScene = CreateDefaultSubobject<USceneComponent>("RootScene");
RootComponent = RootScene;

Tworzenie składnika Static Mesh jest również wykonywane za pomocą funkcji CreateDefaultSubobject(). Static Mesh Component jest dołączany do komponentu sceny za pomocą funkcji SetupAttachment(). Następnie odpowiedź na kolizję jest definiowana jako nakładanie się, aby Static Mesh nie blokował ruchu gracza.

StaticMesh = CreateDefaultSubobject<UStaticMeshComponent>("StaticMesh");
StaticMesh->SetupAttachment(RootScene);
StaticMesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Overlap);

Gdyby dwa komponenty zostały utworzone w Blueprincie, wyglądałyby to następująco:

Stworzyliśmy Static Mesh Component, ale teraz musimy zdefiniować, który Static Mesh będzie używany. Do wyszukiwania pliku Static Mesh w projekcie używana jest struktura o nazwie FObjectFinder. Jeśli wyszukiwanie powiedzie się, Static Mesh zostanie przypisany do komponentu.

ConstructorHelpers::FObjectFinder<UStaticMesh> MeshFile(
    TEXT("/Game/StarterContent/Props/SM_Statue.SM_Statue"));

  if (MeshFile.Succeeded())
  {
    StaticMesh->SetStaticMesh(MeshFile.Object);
  }

Aby uzyskać ścieżkę do zasobu w projekcie, kliknij prawym przyciskiem myszy na zasób i wybierz opcję Copy Reference, jak pokazano na poniższym zrzucie ekranu.

Definicja materiału używanego przez Static Mesh Component jest bardzo podobna do definicji Static Mesh. Jeśli materiał zostanie znaleziony, zostanie zdefiniowany jako materiał indeksu 0 Static Mesh.

Kod konstruktora w pliku TutoProjectCollectable.cpp będzie wyglądał następująco:

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

  RootScene = CreateDefaultSubobject<USceneComponent>("RootScene");
  RootComponent = RootScene;

  StaticMesh = CreateDefaultSubobject<UStaticMeshComponent>("StaticMesh");
  StaticMesh->SetupAttachment(RootScene);
  StaticMesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Overlap);

  ConstructorHelpers::FObjectFinder<UStaticMesh> MeshFile(
    TEXT("/Game/StarterContent/Props/SM_Statue.SM_Statue"));

  if (MeshFile.Succeeded())
  {
    StaticMesh->SetStaticMesh(MeshFile.Object);
  }

  ConstructorHelpers::FObjectFinder<UMaterial> MaterialFile(
    TEXT("/Game/StarterContent/Materials/M_Metal_Gold.M_Metal_Gold"));

  if (MaterialFile.Succeeded())
  {
    StaticMesh->SetMaterial(0, MaterialFile.Object);
  }
}

Źródło:https://romeroblueprints.blogspot.com/2020/08/tutoprojectcollectable-class-components.html