domingo, 6 de setembro de 2020

Classe TutoProjectCharacter e InputComponent

A classe C++ TutoProjectCharacter representa o jogador e foi criada pelo modelo de projeto Third Person que também criou um Blueprint chamado ThirdPersonCharacter, localizado na pasta ThirdPersonCPP/BlueprintsTutoProjectCharacter é a classe pai deste Blueprint, que é usado para especificar o Skeletal Mesh do jogador.

A única modificação que faremos na classe TutoProjectCharacter é adicionar um mapeamento de Input para permitir que o jogador reinicie o jogo ao pressionar a tecla Enter.

No editor de nível, acesse o menu Edit->Project Settings... e na categoria Engine escolha a opção Input. Clique no símbolo + ao lado de Action Mappings, coloque o nome RestartGame para o novo Action Mapping, e selecione a tecla Enter. O mapeamento de Input do projeto vai ficar assim:


O arquivo TutoProjectCharacter.cpp tem uma função chamada SetupPlayerInputComponent() onde é feito a vinculação do Input às funções C++ que serão executadas quando o Input for acionado. O código abaixo mostra alguns exemplos:

void ATutoProjectCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
  // Set up gameplay key bindings
  check(PlayerInputComponent);
  PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
  PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);

  PlayerInputComponent->BindAxis("MoveForward", this, &ATutoProjectCharacter::MoveForward);
  PlayerInputComponent->BindAxis("MoveRight", this, &ATutoProjectCharacter::MoveRight);
  
...

A função check() é usada para garantir que PlayerInputComponent é válido. Se ele estiver inválido, a execução do programa irá parar com uma mensagem de erro.

Vamos criar a função RestartGame() que será chamada quando o jogador pressionar a tecla Enter. O primeiro passo é adicionar a declaração da função no arquivo TutoProjectCharacter.h. Coloque no segundo bloco protected:, abaixo da função SetupPlayerInputComponent(), como mostra este código: 

...

protected:
  // APawn interface
  virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
  // End of APawn interface

  void RestartGame();

...
No arquivo TutoProjectCharacter.cpp faça a vinculação do Input "RestartGame" no final da função SetupPlayerInputComponent(), após o Input "ResetVR": 
...

  // VR headset functionality
  PlayerInputComponent->BindAction("ResetVR", IE_Pressed, this, &ATutoProjectCharacter::OnResetVR);

  PlayerInputComponent->BindAction("RestartGame", IE_Pressed, this, &ATutoProjectCharacter::RestartGame);
}

Não esqueça do operador & antes da identificação da função RestartGame. Ele é usado para retornar o endereço de memória da função.

No final do arquivo TutoProjectCharacter.cpp crie a função RestartGame() com este conteúdo:

void ATutoProjectCharacter::RestartGame()
{
  GetWorld()->GetAuthGameMode<ATutoProjectGameMode>()->StartGame();
}

Estamos pegando um ponteiro para a instância do Game Mode que está sendo usado pelo mapa, já fazendo o Cast para a classe ATutoProjectGameMode. Mas ao invés de armazenar o ponteiro, estamos apenas usando ele para chamar a função StartGame() da classe ATutoProjectGameMode.


Sumário C++