Macro UFUNCTION()

UFUNCTION ()  służy do inicjacji funkcji C++ do edytora Blueprint. 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ą implementowane jako funkcje C ++, które nie zwracają wartości, czyli ich zwracany typ to void :

Funkcja Blueprint z pinem wykonawczym jest implementowana jako funkcja C++, która nie jest oznaczona jako BlueprintPure: 

Jeśli funkcja C ++ jest oznaczona za pomocą BlueprintPure , jest reprezentowana jako czysta funkcja. Czysta funkcja nie ma pinów wykonywania, nie może modyfikować danych instancji i może być używana w wyrażeniach. Jest szeroko stosowany w funkcjach 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 zdarzeń schematu, musi mieć jeden z tych dwóch specyfikatorów:

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

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.
  • BlueprintNativeEven : 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 zwracany typ funkcji C ++ to void , zostanie zaimplementowany jako Event w Blueprints. Jeśli funkcja C ++ zwróci wartość, zostanie zaimplementowana jako funkcja Blueprint. Zobaczmy wszystkie te 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 zaimplementowany 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 w oparciu o klasę TestUFunction  C++  . Aby to zrobić, kliknij prawym przyciskiem myszy klasę TestUFunction i wybierz opcję  Create Blueprint Class na podstawie TestUFunction .

Kliknij prawym przyciskiem myszy Blueprint Event Graph i zobacz, że cztery funkcje zadeklarowane w C++ są wymienione

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

Przed testowaniem musimy zaimplementować funkcję TreasureFound() w Blueprint. Na karcie My Blueprint kliknij przycisk Override obok pozycji Funkcje. Zwróć uwagę, że funkcje Treasure Found i Native Example pojawiają się na liście. Kliknij Treasue 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ż nie zaimplementowano wersji Blueprint funkcji NativeExample() użyto wersji C++. Aby ukończyć ten przykład, zaimplementujemy wersję Blueprint NativeExample().

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

W tym przykładzie usuń węzeł Parent: Native Example i wyświetl komunikat w parametrze  Return Value.

Skompiluj Blueprint i rozpocznij grę. Zauważ, że wywołano tylko wersję Blueprint NativeExample()


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