A classe Vehicle é uma subclasse de Pawn. O sistema de veículos no UDK é bem complexo e permite a criação de diferentes tipos de veículos. A imagem abaixo mostra as subclasses de Vehicle existentes no UDK:
Podemos ver quatro tipo de veículos definidos que são: UTVehicle_Cicada, UTVehicle_Hoverboard, UTVehicle_Manta e UTVehicle_Scorpion. Entretanto, todas essas classes possuem o modificador abstract. Isto indica que não podem ser criados objetos dessas classes. A principal idéia das classes abstratas é criar uma classe base com diversas funcionalidades para servir como modelo. As classes que realmente definem os veículos são as que terminam com o nome "_Content".
Para disponibilizar veículos no cenário é preciso utilizar a classe UDKVehicleFactory que é uma subclasse de "Actor->NavigationPoint". A imagem abaixo mostra os tipos existentes no UDK:
Para disponibilizar veículos no cenário é preciso utilizar a classe UDKVehicleFactory que é uma subclasse de "Actor->NavigationPoint". A imagem abaixo mostra os tipos existentes no UDK:
Existem apenas três Factory. O veículo que está faltando é o Hoverboard porque ele já está disponível automaticamente para o jogador no tipo de jogo "Vehicle Capture The Flag". Para testá-lo no editor defina o Game Type como UTVehicleCTFGame_Content e após iniciar o jogo pressione a tecla "Q" para usar o Hoverboard que é uma espécie de skate sem rodas como pode ser visto na imagem abaixo.
Para entrar em um veículo que esteja disponível no cenário, chegue perto dele e pressione a tecla "E". Se for possível entrar no veículo, umas das funções da classe Vehicle que será chamada é a "DriverEnter(Pawn P)" cujo código se encontra abaixo.
//Extraído da classe Vehicle (pacote Engine)
/** DriverEnter()
* Make Pawn P the new driver of this vehicle
* Changes controller ownership across pawns
*/
function bool DriverEnter(Pawn P)
{
local Controller C;
// Set pawns current controller to control the vehicle pawn instead
C = P.Controller;
Driver = P;
Driver.StartDriving( self );
if ( Driver.Health <= 0 )
{
Driver = None;
return false;
}
SetDriving(true);
// Disconnect PlayerController from Driver and connect to Vehicle.
C.Unpossess();
Driver.SetOwner( Self ); // This keeps the driver relevant.
C.Possess( Self, true );
if( PlayerController(C) != None && !C.IsChildState(C.GetStateName(), LandMovementState) )
{
PlayerController(C).GotoState( LandMovementState );
}
WorldInfo.Game.DriverEnteredVehicle(self, P);
return true;
}
Esta função pega a referência do objeto Pawn que entrou no veículo e guarda na variável Driver para que possa restaurá-lo quando ele sair do veículo. O Controller deixa de referenciar o Pawn através da função "Unpossess()" e passa agora a referenciar o veículo através da função "Possess( Self, true )". O objeto Self é a referência ao veículo e o segundo parâmetro com o valor true indica que é uma transição para um veículo. É feito um teste para verificar se o Controller se trata de um PlayerController e se ainda não se encontra no estado LandMovementState. LandMovementState é uma variável do tipo name definida na classe Pawn. Esse tipo de variável é usada para armazenar o nome de um item em UnrealScript como o nome de classes, funções e estados. Na classe Pawn ela recebe o valor PlayerWalking no DefaultProperties. Na classe Vehicle essa variável recebe o valor PlayerDriving. Isto significa que ao entrar em um veículo o PlayerController passará para o estado PlayerDriving.
No PlayerController podemos ver um bom exemplo do uso de estados. A cada frame é executada a função "PlayerMove()", se estiver no estado PlayerWalking a função "PlayerMove()" chamará a função "ProcessMove()", mas se estiver no estado PlayerDriving a função "PlayerMove()" chamará a função "ProcessDrive()". O código abaixo mostra as funções definidas para o estado PlayerDriving na classe PlayerController.
No PlayerController podemos ver um bom exemplo do uso de estados. A cada frame é executada a função "PlayerMove()", se estiver no estado PlayerWalking a função "PlayerMove()" chamará a função "ProcessMove()", mas se estiver no estado PlayerDriving a função "PlayerMove()" chamará a função "ProcessDrive()". O código abaixo mostra as funções definidas para o estado PlayerDriving na classe PlayerController.
//Extraído da classe PlayerController (pacote Engine)
// Player Driving a vehicle.
state PlayerDriving
{
ignores SeePlayer, HearNoise, Bump;
function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot);
// Set the throttle, steering etc. for the vehicle based on the input provided
function ProcessDrive(float InForward, float InStrafe, float InUp, bool InJump)
{
local Vehicle CurrentVehicle;
CurrentVehicle = Vehicle(Pawn);
if (CurrentVehicle != None)
{
bPressedJump = InJump;
CurrentVehicle.SetInputs(InForward, -InStrafe, InUp);
CheckJumpOrDuck();
}
}
function PlayerMove( float DeltaTime )
{
UpdateRotation(DeltaTime);
ProcessDrive(PlayerInput.RawJoyUp, PlayerInput.RawJoyRight, PlayerInput.aUp, bPressedJump);
if (Role < ROLE_Authority)
{
ServerDrive(PlayerInput.RawJoyUp, PlayerInput.RawJoyRight, PlayerInput.aUp, bPressedJump, ((Rotation.Yaw & 65535) << 16) + (Rotation.Pitch & 65535));
}
bPressedJump = false;
}
unreliable server function ServerUse()
{
local Vehicle CurrentVehicle;
CurrentVehicle = Vehicle(Pawn);
CurrentVehicle.DriverLeave(false);
}
event BeginState(Name PreviousStateName)
{
CleanOutSavedMoves();
}
event EndState(Name NextStateName)
{
CleanOutSavedMoves();
}
}
Para mais informações sobre a Classe Vehicle: