segunda-feira, 27 de fevereiro de 2012

Usando Física em UnrealScript

O código abaixo mostra uma enumeração na classe Actor que indica os possíveis tipos de física que um Actor pode utilizar.
//Extraído da classe Actor

var(Movement) const enum EPhysics
{
    PHYS_None,
    PHYS_Walking,
    PHYS_Falling,
    PHYS_Swimming,
    PHYS_Flying,
    PHYS_Rotating,
    PHYS_Projectile,
    PHYS_Interpolating,
    PHYS_Spider,
    PHYS_Ladder,
    PHYS_RigidBody,
    PHYS_SoftBody, 
    PHYS_NavMeshWalking, 
    PHYS_Unused,
    PHYS_Custom,    
} Physics;

Não encontrei nenhuma referência oficial sobre o significado de cada um desses tipos. Para definir o tipo de física de um Actor use a função SetPhysics() passando como parâmetro um dos valores do enum, como no exemplo abaixo:
SetPhysics(PHYS_Projectile);

Para inicializar a física de um Pawn utilize a função SetMovementPhysics() que possui o seguinte código:
//Extraído da classe Pawn

function SetMovementPhysics()
{
    // Verifica se está na água
    if (PhysicsVolume.bWaterVolume)
    {
        SetPhysics(PHYS_Swimming);
    }
    else if (Physics != PHYS_Falling)
    {
        SetPhysics(PHYS_Falling);
    }
}

Quando um objeto da classe Pawn está com o tipo de física PHYS_Falling ele sofrerá o efeito da gravidade e irá cair até tocar em algum chão, quando passará a ter o tipo PHYS_Walking. No tipo PHYS_Flying o Actor não sofre efeito da gravidade. No tipo PHYS_Rotating apenas a rotação do Actor é alterada enquanto que a sua localização permanece fixa.

As variáveis do Actor mais utilizadas pelo sistema de física são os vetores Velocity e Acceleration que são usados para alterar a posição do Actor. Em relação a rotação temos a variável RotationRate que define a velocidade de rotação. O Actor também possuía a variável DesiredRotation, mas ela foi movida para a classe Pawn. Esta variável é usada para que um Pawn rotacione suavemente até alcançar a rotação especificada em DesiredRotation.

Fiz um exemplo bem simples que apenas altera o tipo de física do jogador para PHYS_Flying. O código abaixo define um novo GameInfo, para testá-lo é preciso definir o Game Type do editor para UTGameFlying.
class UTGameFlying extends UTGame;

function StartMatch()
{ 
 local UTPlayerController playerController;
 
 super.StartMatch();
 foreach LocalPlayerControllers(class 'UTPlayerController', playerController) 
 {
    if( playerController.pawn != None ) 
    {            
      playerController.pawn.SetPhysics(PHYS_Flying);            
    }
 }
}


Para mais informações sobre Física no UDK:
Physics Home