Parametry funkcji oraz Macro UPARAM()

Język C++ umożliwia definiowanie wartości domyślnych parametrów funkcji. Wartość domyślna zostanie użyta, jeśli wartość nie zostanie podana podczas wywołania funkcji.

Oto przykład deklaracji funkcji z wartością domyślną:

void SpawnEnemy(int32 EnemyLevel = 1);

W pierwszym wierszu poniższego przykładu wartość parametru EnemyLevel będzie wynosić 1, a w drugim wierszu będzie wynosić 5 .

SpawnEnemy();
SpawnEnemy(5);

W UFUNCTION() możemy użyć specyfikatora funkcji AdvancedDisplay, aby ukryć domyślne parametry w węźle Blueprint. Przykładem jest deklaracja funkcji ScreenMessage poniżej.

UFUNCTION(BlueprintCallable, Category = TestUParam, meta=(AdvancedDisplay = 1))
void ScreenMessage(FString Message, 
                   FLinearColor TextColor = FLinearColor(1.f, 0.f, 0.f), 
                   float TimeToDisplay = 5.f);

AdvancedDisplay wskazuje, ile parametrów powinno być wyświetlanych w węźle Blueprint bez konieczności rozwijania. Jest to rodzaj specyfikatora zwanego jako Metadata.

Blueprint w ScreenMessage będzie wyglądał następująco:

Kliknij małą strzałkę, aby wyświetlić inne parametry:

Porozmawiajmy teraz o przekazywaniu parametrów przez wartość i przez odniesienie . Podczas przekazywania przez wartość wszelkie zmiany wprowadzone w parametrze są zawarte w samej funkcji. Podczas przekazywania przez odwołanie zmiana wprowadzona w parametrze wpływa na zmienną, która została przekazana jako parametr. Aby zdefiniować parametr jako odniesienie, użyj operatora & , jak pokazano w tym przykładzie:

void ParamExample(int32 ByValue, int32& ByRef);

Przekazywanie parametrów przez odwołanie jest szeroko stosowane, gdy parametr jest strukturą lub klasą, ponieważ uniemożliwia wykonanie kopii z całą zawartością parametru. Przekazywanie przez referencję jest również używane, aby umożliwić funkcji zwracanie więcej niż jednej wartości.

UFUNCTION() ujawnia parametry przekazywane przez powołanie jako parametry wyjściowe. Zobacz poniższy przykład i wygenerowany węzeł Blueprint. 

UFUNCTION(BlueprintCallable, Category = TestUParam)
void InputOutputParam(FVector& InVector, FVector& OutVector); 

Możemy użyć makra UPARAM() ze specyfikatorem ref, aby parametr przekazany przez odniesienie był wyświetlany jako parametr wejściowy:

UFUNCTION(BlueprintCallable, Category = TestUParam)
void InputOutputParam2( UPARAM(ref) FVector& InVector, FVector& OutVector); 

UPARAM() makro ma również DisplayName specyfikator, który jest używany do zmiany nazwy parametru w węźle Blueprint:

UFUNCTION(BlueprintCallable, Category = TestUParam)
void InputOutputParam3( UPARAM(ref, DisplayName="Input Vector") FVector& InVector,
                        UPARAM(DisplayName="Output Vector") FVector& OutVector); 

Przykładowe użycie:

Utwórz klasę C++ o nazwie TestUParam, używając klasy Actor jako klasy nadrzędnej. W TestUParam.h pliku, dodać  deklarację  z  dwóch funkcji poniżej Tick() funkcji, jak pokazano w poniższym kodzie:

...

public:	
  // Called every frame
  virtual void Tick(float DeltaTime) override;
	
  UFUNCTION(BlueprintCallable, Category = TestUParam, meta=(AdvancedDisplay = 1))
  void ScreenMessage(FString Message, 
                     FLinearColor TextColor = FLinearColor(1.f, 0.f, 0.f),
                     float TimeToDisplay = 5.f);
	
  UFUNCTION(BlueprintCallable, Category = TestUParam)
  bool AnalyzeVector( UPARAM(ref, DisplayName="Input Vector") FVector& InVector, 
                      float& VectorLength, 
                      FVector& NormalVector );
                      
};

W pliku TestUParam.cpp dodaj implementację dwóch funkcji pokazanych poniżej:

... 

void ATestUParam::ScreenMessage(FString Message, FLinearColor TextColor, 
                                float TimeToDisplay)
{
  if(GEngine)
  {
    GEngine->AddOnScreenDebugMessage(-1, TimeToDisplay, TextColor.ToFColor(true), 
                                     Message);
  }	
}

bool ATestUParam::AnalyzeVector( FVector& InVector, float& VectorLength, 
                                 FVector& NormalVector )
{
  bool IsNormalized = InVector.IsNormalized();
	
  NormalVector.X = InVector.X;
  NormalVector.Y = InVector.Y;
  NormalVector.Z = InVector.Z;
	
  if (IsNormalized)
  {
    VectorLength = 1.f;
  }
  else
  {
    VectorLength = InVector.Size();
		
    NormalVector.Normalize();
  }
	
  return IsNormalized;
}

Skompiluj kod C ++. Utwórz Blueprint w oparciu o klasę C++ TestUParam . Aby to zrobić, kliknij prawym przyciskiem myszy klasę TestUParam i wybierz opcję Create Blueprint class based on TestUParam .

Otwórz nowy Blueprint i uzyskaj dostęp do wykresu zdarzeń. Dodaj funkcje do zdarzenia BeginPlay , jak pokazano na poniższym obrazku.

Skompiluj Blueprint i dodaj instancję na poziomie. Uruchom grę i zobacz komunikaty na ekranie z informacjami o wektorze lokalizacji instancji. Czerwona linia to długość wektora, a żółta linia to znormalizowany wektor.


Źródło:https://romeroblueprints.blogspot.com/2020/11/function-parameters-and-uparam-macro.html