PlayerCharacter: Konwertowanie Blueprint script do C++

W tym artykule, będziemy konwertować część skryptu Wzorca FirstPersonCharacter (przemianowany BP_PlayerCharacter ).

Decydując się na konwersję skryptu Blueprint do C ++, należy wziąć pod uwagę dwa ważne czynniki:

  • Złożoność : czasami konieczne jest wdrożenie logiki, która jest złożona lub obejmuje wiele obliczeń matematycznych. Ze względu na wizualny charakter Blueprint, tego typu skrypty mogą być mylące, gdy są reprezentowane przez węzły Blueprint, dzięki czemu implementacja w C ++ jest bardziej odpowiednia i czytelna.  
  • Szybkość :  szybkość wykonywania kodu C ++ jest większa niż w przypadku skryptu Blueprint. Nie oznacza to, że powinieneś przekonwertować wszystkie swoje Blueprints na C ++ tylko z tego powodu. Istnieje niezliczona ilość innych czynników, które będą określać wydajność projektu Unreal. Musisz sprawdzić, czy istnieją nietrywialne skrypty, które są wykonywane bardzo często, na przykład węzły Blueprint, które są połączone ze zdarzeniem Tick .

Przekonwertujemy prosty skrypt Blueprint na C ++, aby pokazać, jak to się robi. Otwórz Blueprint BP_PlayerCharacter i zobacz na wykresie zdarzenia działania, które są w ruchu . Usunąłem węzły związane z testem użytkowania HMD (Head Mount Display), aby przykład był prosty, jak pokazano na poniższym obrazku. 

Weźmy węzły Blueprint ze zdarzenia InputAxis MoveForward i przekonwertujmy je na pojedynczą funkcję C ++. W tym przykładzie istnieją tylko dwa węzły, ale gdyby było ich kilkadziesiąt, można by je również przekonwertować na pojedynczą funkcję C ++.  samą konwersję wykonamy dla zdarzenia InputAxis MoveRight .

Musimy znaleźć funkcje C ++ odpowiadające węzłom Blueprint. Pod nazwą węzła Blueprint znajduje się linia Target is … , która wskazuje klasę, w której zdefiniowano funkcję reprezentowaną przez węzeł. Na powyższym obrazku mamy dwa węzły, których celem jest aktor i dwa węzły z pionem docelowym . Wszystkie te funkcje będą dostępne w naszej klasie C ++ PlayerCharacter, ponieważ klasa Character dziedziczy zmienne i funkcje klasy Pawn, a klasa Pawn dziedziczy zmienne i funkcje klasy Actor .

Pierwszym krokiem jest wyszukanie funkcji w Unreal Engine API Reference . Poszukaj nazwy węzła Blueprint, usuwając puste miejsca, na przykład AddMovementInput . W dokumentacji API można zobaczyć opis parametrów funkcji. Niestety, dokumentacja API nie wskazuje, czy parametr jest opcjonalny. Aby to sprawdzić, spójrz na stronę funkcji w dokumentacji API, aby znaleźć ścieżkę i nazwę pliku nagłówkowego . Poszukaj pliku w folderze silnika swojego projektu . Otwórz plik i poszukaj nazwy funkcji w pliku. Deklaracja funkcji AddMovementInput jest wykonywana w następujący sposób:

UFUNCTION(BlueprintCallable, Category="Pawn|Input", meta=(Keywords="AddInput"))
virtual void AddMovementInput(FVector WorldDirection, float ScaleValue = 1.0f, 
                                                      bool bForce = false);

Zauważ, że parametry ScaleValue i bForce przyjmują wartości domyślne. Oznacza to, że te parametry są opcjonalne i funkcję AddMovementInput można wywołać, przekazując tylko parametr WorldDirection .

Wcześniej utworzyliśmy klasę C ++ PlayerCharacter, która ma być używana jako klasa nadrzędna Blueprint BP_PlayerCharacter . Otwórz plik PlayerCharacter.h i dodaj deklaracje dla nowych funkcji MoveForward () i MoveRight (), jak pokazano w kodzie poniżej.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "PlayerCharacter.generated.h"

UCLASS()
class TUTOPART3_API APlayerCharacter : public ACharacter
{
  GENERATED_BODY()

public:
  // Sets default values for this character's properties
  APlayerCharacter();

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

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

  // Called to bind functionality to input
  virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) 
                                                                            override;

  UFUNCTION(BlueprintCallable, Category = Movement)
  void MoveForward(float Value);
	
  UFUNCTION(BlueprintCallable, Category = Movement)
  void MoveRight(float Value);
};

W pliku PlayerCharacter.cpp mamy implementację funkcji MoveForward () i MoveRight () przy użyciu tej samej logiki, która była w skrypcie Blueprint.

#include "PlayerCharacter.h"

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

}

// Called when the game starts or when spawned
void APlayerCharacter::BeginPlay()
{
  Super::BeginPlay();	
}

// Called every frame
void APlayerCharacter::Tick(float DeltaTime)
{
  Super::Tick(DeltaTime);
}

// Called to bind functionality to input
void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
  Super::SetupPlayerInputComponent(PlayerInputComponent);
}

void APlayerCharacter::MoveForward(float Value)
{
  AddMovementInput(GetActorForwardVector(), Value);
}

void APlayerCharacter::MoveRight(float Value)
{
  AddMovementInput(GetActorRightVector(), Value);
}

Pierwszy parametr funkcji AddMovementInput () otrzymuje wartość zwracaną z wywoływanej funkcji.

Tylko uwaga dotycząca parametru Value używanego w funkcjach ruchu. Jeśli wartość jest ujemna, ruch będzie odbywał się w przeciwnym kierunku.

Skompiluj kod C ++.

Otwórz Blueprint BP_PlayerCharacter . Na wykresie zdarzeń zastąpimy węzły Blueprint, które są w ruchu wejściowym , naszymi funkcjami C ++. Zachowaj węzły zdarzeń InputAxis i usuń pozostałe.

Kliknij prawym przyciskiem myszy Blueprint Event Graph , poszukaj naszych funkcji C ++ w menu kontekstowym w kategorii Ruch i dodaj je do wykresu zdarzeń, który powinien wyglądać następująco:

Zwróć uwagę, że celem węzłów schematu jest postać gracza .

Zrobiliśmy ten prosty przykład, abyś mógł zrozumieć ten proces konwersji.


Źródło:https://romeroblueprints.blogspot.com/2021/03/playercharacter-converting-blueprint.html