PFM: Diseño y creación de enemigo Razor (parte 1)

Tras la creación del Speeder, hoy veremos los pasos seguidos para la creación de un nuevo enemigo, el temible “Razor”. El Razor es un robot con 3 afiladas cuchillas como patas cuyo único objetivo es localizar y destruir a cualquiera que se interponga en los objetivos de las máquinas, en este caso el jugador. Son rápidos y cuando atacan en grupo pueden resultar mortales, pues sus cuchillas causan un gran daño.

Como siempre, y para deleite de todos, los bocetos guarreros:

Razor000Desde el comienzo el diseño estaba claro: Una esfera con un gran visor por cabeza y 3 largas y afiladas patas. El diseño definitivo:  Razor00RED Como con el Speeder, comencé por un modelo de formas básicas para ajustar el tamaño y las proporciones.Razor01 Una vez ajustado ya modelé las formas definitivas:Razor02 El esqueleto para animación:Razor03Las texturas usadas. La primera es el unwrap del modelo. El resto son texturas que se han usado para crear el material. La última, que es el mapa de normales, sirve para dar al modelo un aspecto de relieve más allá de la geometría.

RazorTexturesEl material creado para el Razor es uno de los más complejos hasta ahora, al combinar numerosas texturas e incluir efectos como el de la lente. RazorMaterialEl material aplicado en el modelo final. Puede observarse el efecto de la lente, que parece estar más en el interior, tras un cristal.Razor05En este video se aprecia mejor el efecto y también, la apariencia de relieve que aportan los mapas de normales.

De momento el Razor sólo tendrá la animación de correr, pero más adelante podrá atacar al jugador.

El AnimTree:

RazorAnimTree

De momento se le ha programado para perseguir al jugador usando el NavigationMesh para orientarse.


Son muy cansiiiiiiinos

A continuación el código usado. Es similar al Speeder sólo que en vez de dirigirse al PFMTarget, los Razor intentan llegar al jugador, que es un objetivo móvil.

PFMEnemyControllerRazor

class PFMEnemyControllerRazor extends PFMEnemyController;

var PFMPawn PlayerPawn;     // Referencia al Pawn del jugador
var PFMPawn PlayerPawnAux;     // Referencia al Pawn del jugador

// Estado inicial. Búsqueda de jugador
auto state SearchPlayer
{
Begin:
    foreach DynamicActors(class'PFMPawn', PlayerPawnAux)
    {
        PlayerPawn = PlayerPawnAux;
        // Se queda con el que pille (En principio sólo habrá uno)
    }

    if(PlayerPawn != none)
    {
        `log(">>>> Encontrado PlayerPawn");
        GoToState('HuntPlayer');
    }

    `log(">>>> No encontrado Player");
    Sleep(1.0);
    GoTo 'Begin';
}

state HuntPlayer
{
    // Calcula el camino al objetivo
    function bool FindNavMeshPath()
    {
        NavigationHandle.PathConstraintList = none;
        NavigationHandle.PathGoalList = none;
        // Create constraints
        class'NavMeshPath_Toward'.static.TowardGoal( NavigationHandle, PlayerPawn );
        class'NavMeshGoal_At'.static.AtActor( NavigationHandle, PlayerPawn, 32 );
        // Find path
        return NavigationHandle.FindPath();
    }

Begin:

    if ( NavigationHandle == None )
    {
        `log(">>>>>>MEC!!! - NavigationHandle Erroneo");
        InitNavigationHandle();
    }
    else
    {
        InitNavigationHandle();
    }

    if( NavigationHandle.ActorReachable(PlayerPawn))
    {
        `log(">>>> Puedo llegar directamente al Pawn");
        MoveToward(PlayerPawn, PlayerPawn, 32);
    }
    else if (FindNavMeshPath())
    {
        //NavigationHandle.DrawPathCache(,true);
        NavigationHandle.SetFinalDestination(PlayerPawn.Location);

        if(NavigationHandle.GetNextMoveLocation(NextDest, Pawn.GetCollisionRadius()*5))
        {
            `log(">>>> Me muevo al siguiente punto");
            MoveTo(NextDest,none,128.0);
        }
        else
        {
            `log(">>>> No hay siguiente punto en el camino");
            MoveToward(PlayerPawn);
        }
    }
    else
    {
        `log(">>>> No se encuentra camino posible");
        MoveToward(PlayerPawn);
    }

    goto 'Begin';
}

defaultproperties
{
}

PFMEnemyPawnRazor

class PFMEnemyPawnRazor extends PFMEnemyPawn;

defaultproperties
{
    // SkeletalMesh
    Begin Object Name=EnemyMesh
        SkeletalMesh=SkeletalMesh'Enemies.Razor.SM_Razor'
        AnimSets(0)=AnimSet'Enemies.Razor.AS_Razor'
        AnimTreeTemplate=AnimTree'Enemies.Razor.AT_Razor'
        LightEnvironment=MyLightEnvironment
        bAcceptsLights=True
    End Object
    Components.Add(EnemyMesh)

    // Cilindro de colisión
    Begin Object Name=CollisionCylinder
        CollisionRadius=30.0
        CollisionHeight=46.0
        BlockNonZeroExtent=true
        BlockZeroExtent=true
        BlockActors=true
        CollideActors=true
    End Object
    CollisionComponent=CollisionCylinder
    Components.Add(CollisionCylinder)

    // Se especifica el controlador
    ControllerClass=class'PFM.PFMEnemyControllerRazor'

    Health=200
    GroundSpeed=600.0           //Velocidad máxima en suelo
    MaxStepHeight=15.0
    DrawScale=1.0
}

En la parte 2, el Razor podrá atacar al jugador.
Banner Blog

Anuncios

11 pensamientos en “PFM: Diseño y creación de enemigo Razor (parte 1)

  1. Saludos marcos…. tengo un problemita en esta parte .. XD….
    es un erro de los q mencionastes anerior mente por lso parametros.. pero aun no lo eh podido solucionar =/ ….

    te dejare el error en este caso
    “http://subefotos.com/ver/?4b1d292018859cf532d35ddc27db310do.png#codigos”

    gracias por todo ^^

    • cmo hago para q nextdest exista en mi PFMEnemy ….
      tengo q crearle alguna variable aparte o hacer q lo reconosca en el default propertys del controler del razor….. pienso yo .. no se si estoy equivocado.

      estare esperando tu respuesta >_O b

    • Añade la variable en PFMEnemy:
      var Vector NextDest;
      Así estará accesible en PFMEnemyController
      Olvidé actualizar el código…

    • genial gracias….. si sirvio aunque el unico problema es q cuando lo mato el UDK deja de funcionar xD… en fin ya veremos como me ira en al parte dos estare esperando >_O b

  2. Pingback: PFM: Diseño y creación de enemigo Razor (y parte 2) | El Blog de Marcos

  3. Oye muy bueno,…tengo una duda, saliendome un poco del tema, es que estoy averiguando de que forma se pueden colocar dos enemigos distintos digamos en un mismo generador
    Gracias de antemano

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s