segunda-feira, 25 de junho de 2012

Platformer Kit: SPG_PlayerPawn class (UnrealScript)

A classe SPG_PlayerPawn representa o personagem do jogador. Se você não conhece a classe Pawn dê uma lida no artigo: "Classe Pawn (UnrealScript)".

As variáveis abaixo da classe SPG_PlayerPawn estão disponíveis para modificação no editor.
class SPG_PlayerPawn extends Pawn;

// Dynamic light environment component to help speed up lighting calculations for the pawn
var(Pawn) const DynamicLightEnvironmentComponent LightEnvironment;

// How fast a pawn turns
var(Pawn) const float TurnRate;

// How high the pawn jumps
var(Pawn) const float JumpHeight;

// Socket to use for attaching weapons
var(Pawn) const Name WeaponSocketName;

// Height to set the collision cylinder when crouching
var(Pawn) const float CrouchHeightOverride<DisplayName=Crouch Height>;

// Radius to set the collision cylinder when crouching
var(Pawn) const float CrouchRadiusOverride<DisplayName=Crouch Radius>;

Também foi criado um Archetype para a classe SPG_PlayerPawn. A imagem abaixo mostra os valores de algumas variáveis.


A função FaceRotation() da classe SPG_PlayerPawn é chamada a partir da função UpdateRotation() da classe SPG_PlayerController.

Nesta função serão ajustadas dois tipos de Rotação: a rotação da mira e a rotação do personagem.

A rotação da mira é ajustada a partir da variável "AimNode.Aim.Y" baseada no valor da variável Pitch da Rotação que é passada como parâmetro. A variável AimNode é do tipo AnimNodeAimOffset.

A rotação do personagem é feita baseada no valor da variável Yaw da Rotação que é passada como parâmetro, utilizando a função SetRotation() da classe Pawn.
simulated function FaceRotation(Rotator NewRotation, float DeltaTime)
{
    local Rotator FacingRotation;

    // Set the desired yaw the new rotation yaw
    if (NewRotation.Yaw != 0)
    {
        DesiredYaw = NewRotation.Yaw;
    }

    // If the current yaw doesn't match the desired yaw, then interpolate towards it
    if (CurrentYaw != DesiredYaw)
    {
        CurrentYaw = Lerp(CurrentYaw, DesiredYaw, TurnRate * DeltaTime);
    }

    // If we have a valid aim offset node
    if (AimNode != None)
    {
        // Clamp the current pitch to the view pitch min and view pitch max
        CurrentPitch = Clamp(CurrentPitch + NewRotation.Pitch, ViewPitchMin, ViewPitchMax);

        if (CurrentPitch > 0.f)
        {
            // Handle when we're aiming up
            AimNode.Aim.Y = float(CurrentPitch) / ViewPitchMax;
        }
        else if (CurrentPitch < 0.f)
        {
            // Handle when we're aiming down
            AimNode.Aim.Y = float(CurrentPitch) / ViewPitchMin;
           
            if (AimNode.Aim.Y > 0.f)
            {
                AimNode.Aim.Y *= -1.f;
            }
        }
        else
        {
            // Handle when we're aiming straight forward
            AimNode.Aim.Y = 0.f;
        }
    }

    // Update the facing rotation
    FacingRotation.Pitch = 0;
    FacingRotation.Yaw = CurrentYaw;
    FacingRotation.Roll = 0;

    SetRotation(FacingRotation);
}

A função DoJump() é chamada para realizar o pulo do personagem. Ela leva em conta os diferentes modos de Física que o personagem pode se encontrar.

Em essência, a velocidade no eixo Z (para cima) recebe o valor que se encontra na variável JumpHeight que foi definido nesta classe e que pode ser ajustada no Archetype. Depois é verificado se o jogador se encontra em uma plataforma móvel. Caso seja verdade então a velocidade da plataforma (Base.Velocity.Z) influencia a velocidade do pulo do jogador.
function bool DoJump(bool bUpdating)
{
    if (bJumpCapable && !bIsCrouched && !bWantsToCrouch && (Physics == PHYS_Walking || Physics == PHYS_Ladder || Physics == PHYS_Spider))
     {
        if (Physics == PHYS_Spider)
        {
            Velocity = JumpHeight * Floor;
        }
        else if (Physics == PHYS_Ladder)
        {
            Velocity.Z = 0.f;
        }
        else
        {
            Velocity.Z = JumpHeight;
        }

        if (Base != None && !Base.bWorldGeometry && Base.Velocity.Z > 0.f)
        {
            Velocity.Z += Base.Velocity.Z;
        }

        SetPhysics(PHYS_Falling);
        return true;
    }

    return false;
}