domingo, 18 de dezembro de 2011

Classe PlayerInput (UnrealScript)

A classe PlayerInput foi criada para gerenciar os dispositivos de entrada do jogo. Esta classe possui uma característica diferente, pois ela é uma classe interna à classe PlayerController. Isto significa que um objeto da classe PlayerInput não pode existir sem um objeto da classe PlayerController.

A declaração da classe PlayerInput foi feita assim:
class PlayerInput extends Input within PlayerController

Uma classe interna possui acesso direto às variáveis e funções da classe externa. Mas se na classe interna houver variáveis/funções com o mesmo nome, é preciso usar a palavra "Outer" para referenciar a classe externa. É sempre recomendado o uso do "Outer" para evitar confusões no código. Como exemplo, na classe PlayerController existe uma variável chamada "bDemoOwner". Para acessá-la na classe PlayerInput, use:
Outer.bDemoOwner
A instância da classe PlayerInput é criada na classe PlayerController na função "InitInputSystem()" da seguinte forma:
PlayerInput = new(Self) InputClass;
O "InputClass" é definido no DefaultProperties do PlayerController e o "Self" é a referência da classe PlayerController que será armazenada no objeto Outer da classe PlayerInput.

-----

Conforme foi visto no artigo sobre Mapeamento de Teclas, o arquivo de configuração DefaultInput.ini é usado para definir os comandos que poderão ser executados pelo jogador.

Na classe PlayerInput são definidas alguns variáveis que irão armazenar as informações relacionadas aos Eixos. Estas variáveis possuem um modificador chamado input tornando elas acessíveis ao sistema de entrada do Unreal.

Abaixo temos alguns exemplos de variáveis da classe PlayerInput:
var input    float    aBaseX;
var input    float    aBaseY;
var input    float    aBaseZ;
var input    float    aMouseX;
var input    float    aMouseY;
var input    float    aForward;
var input    float    aTurn;
var input    float    aStrafe;
var input    float    aUp;
var input    float    aLookUp;

var input    float    aRightAnalogTrigger;
var input    float    aLeftAnalogTrigger;
Exemplo de um mapeamento para uma dessas variáveis:
.Bindings=(Name="GBA_MoveForward",Command="Axis aBaseY Speed=1.0")

A ação GBA_MoveForward (mover em frente) atribuirá a posição do eixo do dispositivo de entrada diretamente à variável aBaseY. O atributo Speed é uma espécie de multiplicador do valor do eixo.

-----

Quando uma função está associada à uma tecla, ela só será chamada uma vez no momento do pressionamento da tecla. Para que ela seja chamada de novo é preciso soltar a tecla e pressionar de novo. Dessa forma não dá para implementar ações que sejam executadas enquanto a tecla está sendo pressionada.

Para resolver este problema podemos usar uma função executável que receba como parâmetro um valor booleano. No mapeamento essa função será chamada inicialmente com o valor "true" e quando a tecla for liberada (Onrelease) a função será chamada com o valor "false".

Como Exemplo, no jogo Unreal Tournament a Tabela de Pontos é exibida enquanto a tecla F1 está sendo pressionada. Ao soltar a tecla a Tabela de Pontos deixa de ser exibida.

O código abaixo mostra o mapeamento e a função que armazena o valor booleano.
//No arquivo DefaultInput.ini

.Bindings=(Name="GBA_ShowScores",Command="SetShowScores true | Onrelease SetShowScores false")


//Na classe HUD (pacote Engine)

exec function SetShowScores(bool bNewValue)
{
    //Armazena o valor booleano que indicará se a Tabela de Pontos deverá ser exibida.
    bShowScores = bNewValue; 
}