Macro UFUNCTION()

UFUNCTION () służy do implementacji funkcji w C ++. Możliwe jest tworzenie funkcji C ++, które będą wywoływane w edytorze Blueprints. Możliwe jest również wywołanie w C ++ funkcji, które zostały zaimplementowane w Blueprints.

Blueprint może reprezentować funkcję C ++ na trzy różne sposoby. Zdarzenia są zaimplementowane jako funkcje c ++, który nie zwraca wartości, to znaczy ich typ zwracany jest typu “void”:

Funkcja Blueprint z pinem wykonawczym jest implementowana jako Funkcja C ++, która nie jest oznaczona jako Blueprint “Pure”: 

Jeśli funkcja C ++ jest oznaczona za pomocą Blueprint Pure , jest reprezentowana jako funkcja bez pinu wykonywania, nie może modyfikować danych instancji i może być używana w wyrażeniach. Jest szeroko stosowana w funkcjach typu Get.

Porozmawiajmy teraz o specyfikatorach funkcji . Po pierwsze, każda UFUNCTION() musi mieć specyfikator Category, aby funkcja była poprawnie wyświetlana w menu kontekstowym Blueprint.

Aby funkcja UFUNCTION() została użyta w wykresie Blueprints, musi mieć jeden z tych dwóch specyfikatorów:

  • BlueprintCallable : pojawi się jako funkcja Blueprint z kodem wykonawczym.
  • BlueprintPure : Pojawi się jako pure function.

Możliwe jest zdefiniowanie funkcji C ++, która zostanie zaimplementowana w Blueprint. Aby to zrobić, użyj jednego z tych dwóch specyfikatorów w funkcji  UFUNCTION () :

  • BlueprintImplementableEvent : Funkcja jest zaimplementowana tylko w Blueprint. Jeśli zostanie znaleziona implementacja C ++, wygeneruje błąd kompilacji.
  • BlueprintNativeEvent : umożliwia implementację wersji C ++ funkcji, która będzie używana, jeśli wersja Blueprint nie zostanie zaimplementowana. Wersja C ++ musi mieć nazwę funkcji oraz przyrostek  _Implementation.

Jeśli zwracanym typem funkcji C ++ jest void , zostanie zaimplementowany jako Event w Blueprints. Jeśli funkcja C ++ zwróci wartość, zostanie zaimplementowana jako funkcja Blueprint. 

Sprawdzimy teraz te wszystkie specyfikatory w akcji w przykładowym użyciu.

Przykładowe użycie:

Utwórz klasę C ++ o nazwie TestUFunction, używając klasy Actor jako klasy nadrzędnej. W pliku TestUFunction.h dodaj deklaracje czterech funkcji poniżej funkcji Tick ​​() , jak pokazano w tym kodzie:

...

public:	
  // Called every frame
  virtual void Tick(float DeltaTime) override;
	
  UFUNCTION(BlueprintCallable, Category = Tutorial)
  int32 WelcomeMsg(FString PlayerName);
	
  UFUNCTION(BlueprintPure, Category = Tutorial)
  float CalculateDamage(float PowerAttack, float DefenseValue);
	
  UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category = Tutorial)
  void TreasureFound();
	
  UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = Tutorial)
  FString NativeExample();
};

W pliku TestUFunction.cpp dodaj implementację trzech funkcji pokazanych poniżej: 

...

int32 ATestUFunction::WelcomeMsg(FString PlayerName)
{
  FString Message = FString::Printf(TEXT("Welcome %s."), *PlayerName);
  
  if(GEngine)
  {
    GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Red, Message);
  }
  
  //Returns the number of characters in PlayerName
  return PlayerName.Len();
}

float ATestUFunction::CalculateDamage(float PowerAttack, float DefenseValue)
{
  return (PowerAttack * 10) / DefenseValue;
}

FString ATestUFunction::NativeExample_Implementation()
{
  return TEXT("NativeExample: C++ version");
}

Zauważ, że funkcja TreasureFound () nie została zaimplementowana. Dzieje się tak, ponieważ zostanie zaimplementowana tylko w Blueprint ze względu na specyfikator BlueprintImplementableEvent . Funkcja NativeExample () ma specyfikator BlueprintNativeEvent, który umożliwia jej implementację w językach C ++ i Blueprint. Wersja C ++ została zaimplementowana pod nazwą NativeExample_Implementation () .

Skompiluj kod C ++. Utwórz Blueprint na podstawie klasy TestUFunction  C ++  . Aby to zrobić, kliknij prawym przyciskiem myszy klasę TestUFunction i wybierz opcję  Utwórz klasę Blueprint na podstawie TestUFunction .

Kliknij prawym przyciskiem myszy Blueprint Event Graph i zobacz, że cztery funkcje zadeklarowane w C ++ są wymienione w kategorii Tutorial, jak pokazano na poniższym obrazku. Pojawiają się na tej liście, ponieważ mają specyfikator BlueprintCallable lub BlueprintPure .

Nazwiemy cztery funkcje w wydarzeniu BeginPlay w Blueprint . Dodaj funkcje do wykresu zdarzeń, jak pokazano na poniższym obrazku.

Przed testowaniem musimy zaimplementować funkcję TreasureFound () w Blueprint. Na karcie My Blueprint kliknij przycisk Override obok pozycji Funkcje . Zwróć uwagę, że na liście pojawiają się funkcje Treasure Found i Native Example . Kliknij Treasure Found

Zwracany typ funkcji TreasureFound () to void , więc jest zaimplementowany jako Event w Blueprint. Dodaj funkcję Print String z komunikatem:

Skompiluj Blueprint i dodaj instancję na poziomie. Uruchom grę i zobacz komunikaty na ekranie. Każda linia przedstawia wykonanie jednej z funkcji.

Ponieważ wersja Blueprint funkcji NativeExample () nie została zaimplementowana, użyto wersji C ++. Aby ukończyć ten przykład, zaimplementujemy wersję Blueprint NativeExample () .

Na karcie My Blueprint kliknij przycisk Override obok pozycji Functions i wybierz opcję Native Example . Jest implementowana jako funkcja, ponieważ ma wartość zwracaną. Zobacz węzeł Parent: Native Example na poniższym zrzucie ekranu. Ten węzeł wykona wersję C ++ NativeExample () . Pozwala to na dodanie funkcji w Blueprint do tej funkcji. Ale jeśli chcesz, aby wersja Blueprint zastąpiła wersję C ++, po prostu usuń ten węzeł. 

W naszym przykładzie usunę węzeł Parent: Native Example i napisze komunikat w parametrze  Return Value .

Skompiluj Blueprint i rozpocznij grę. Zwróć uwagę, że wywołano tylko wersję Blueprint NativeExample(). 


Źródło:https://romeroblueprints.blogspot.com/2020/10/the-ufunction-macro.html