Klasa TutoProjectCollectable – Functions

W tym artykule utworzymy kilka zmiennych i napiszemy funkcje klasy TutoProjectCollectable. Pojawi się tutaj nowa funkcja o nazwie InitStatue() i funkcje BeginPlay() oraz NotifyActorBeginOverlap() klasy Actor zostaną nadpisane.

Najpierw dodajmy zmienne i deklaracje funkcji do pliku nagłówkowego TutoProjectCollectable.h. W public: block dodaj deklarację funkcji NotifyActorBeginOverlap() poniżej funkcji Tick():

...

public:	
	// Sets default values for this actor's properties
	ATutoProjectCollectable();

	// Called every frame
	virtual void Tick(float DeltaTime) override;

	virtual void NotifyActorBeginOverlap(AActor* OtherActor) override;
    
    ...

W bloku protected: umieść zmienne i deklaracje funkcji pokazane poniżej. Zmienne będą używane w funkcjach, które będziemy pisać.

...

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

	class ATutoProjectGameMode* TutoProjectGameMode;

	FTimerHandle TimerHandleInitStatue;

	void InitStatue();

};

Teraz zamierzamy zmodyfikować plik TutoProjectCollectable.cpp. Konieczne jest dołączenie plików TutoProjectGameMode.h i TutoProjectCharacter.h, ponieważ będziemy odnosić się do tych klas.

#include "TutoProjectCollectable.h"
#include "TutoProjectGameMode.h"
#include "TutoProjectCharacter.h"

W funkcji BeginPlay () otrzymamy odniesienie do instancji klasy ATutoProjectGameMode, która jest używana przez grę do przechowywania jej w zmiennej TutoProjectGameMode, tak jak zostało to zrobione w klasie TutoProjectHUD. Następnie zostanie wywołana funkcja InitStatue() w celu zainicjowania instancji klasy TutoProjectCollectable.

// Called when the game starts or when spawned
void ATutoProjectCollectable::BeginPlay()
{
  Super::BeginPlay();
	
  TutoProjectGameMode = GetWorld()->GetAuthGameMode<ATutoProjectGameMode>();

  InitStatue();
}

Funkcja InitStatu () ma dwa cele. Pierwszym jest określenie lokalizacji instancji w obszarze gry. Drugim celem jest skonfigurowanie licznika czasu, który wskaże czas pozostawania instancji w danej lokalizacji. Po upływie tego czasu Timer wywoła funkcję InitStatue(), aby zmienić lokalizację instancji i skonfigurować nowy Timer. Liczba sekund, w ciągu których instancja zmienia lokalizację, jest wynikiem wyrażenia 6 – poziom gracza.

void ATutoProjectCollectable::InitStatue()
{
  float NewX = FMath::RandRange(XMinimum, XMaximum);
  float NewY = FMath::RandRange(YMinimum, YMaximum);

  FVector NewLocation = FVector(NewX, NewY, FloorZValue);
	
  SetActorLocation(NewLocation);
	
  float NewTime = 6 - TutoProjectGameMode->GetPlayerLevel();

  GetWorldTimerManager().SetTimer(TimerHandleInitStatue, this, 
                                  &ATutoProjectCollectable::InitStatue, NewTime, false);

Funkcja FMath::RandRange(Min, Max) zwraca losową liczbę między wartościami Min i Max. Zmienne zdefiniowane w funkcjach, takie jak NewX i NewY, są usuwane zaraz po zakończeniu funkcji.

Jeśli masz wątpliwości co do Timera, przeczytaj artykuł, w którym utworzyliśmy Timer w klasie TutoProjectGameMode:

Ostatnią funkcją jest NotifyActorBeginOverlap (AActor*OtherActor), która jest wywoływana, gdy Actor wchodzi na instancję. Parametr OtherActor jest odwołaniem do Actora, który wyzwolił nachodzenie. Cast służy do sprawdzania, czy OtherActor jest typu ATutoProjectCharacter. Jeśli nie jest tego typu, wynikiem Cast będzie pusty wskaźnik reprezentowany przez nullptr.

Ponadto operator not! służy do sprawdzenia, czy gra nie jest w trybie zakończenia gry. Używamy operatora and oraz &&, aby sprawdzić, czy oba warunki są prawdziwe. W tym przypadku wywołujemy funkcję ItemCollected() klasy TutoProjectGameMode oraz funkcję Destroy(), aby usunąć instancję z gry. Kolejna instancja zostanie utworzona za pomocą funkcji SpawnActor().

void ATutoProjectCollectable::NotifyActorBeginOverlap(AActor* OtherActor)
{
  Super::NotifyActorBeginOverlap(OtherActor);

  if (Cast<ATutoProjectCharacter>(OtherActor) != nullptr 
      && !TutoProjectGameMode->IsGameOver())
  {
    TutoProjectGameMode->ItemCollected();
    Destroy();

    FTransform DefaultTransform;
    GetWorld()->SpawnActor<ATutoProjectCollectable>(this->GetClass(), DefaultTransform);
  }
}

Kilka uwag na temat powyższego kodu. Funkcja Destroy() wskazuje, że Aktor musi zostać zniszczony, ale jego zniszczenie następuje pod koniec zdarzenia Tick. Dlatego może mieć instrukcje po funkcji Destroy().

Funkcja SpawnActor() wymaga FTransform, aby zdefiniować pozycję, w której zostanie utworzona instancja. Zmienna DefaultTransform została utworzona przy użyciu domyślnych wartości FTransform, ponieważ funkcja BeginPlay() zostanie wykonana dla nowej instancji i umieści ją w obszarze gry.

Pierwszy parametr funkcji SpawnActor() wskazuje klasę instancji, która zostanie utworzona. Instrukcja this->GetClass () została użyta do pobrania klasy instancji, w której działa ten kod. Tak więc, jeśli instancja klasy child TutoProjectCollectable zostanie zebrana przez gracza, to nowo utworzona instancja będzie używać tej klasy child.


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