PFM: Interfaz en UDK – Menú de Pausa

En un post anterior ya empezamos a experimentar con el sistema de interfaz de UDK, concretamente con las posibilidades que ofrece el Canvas. Hoy crearemos un menú de pausa ingame, que se activará al pulsar la tecla Escape. Al hacerlo se pausará el juego y veremos un par de botones con opciones, que podremos activar utilizando el ratón.

Esta entrada es larguísima :lol:, así que…

Vayamos por partes… pausando el juego

Lo primero que haremos es pausar el juego al pulsar la tecla Escape. Es sencillo pero requiere varias modificaciones y algunos ajustes.

En primer lugar deberemos modificar PFMPlayerController:

Agregaremos la siguiente variable

var bool bInMenu;               // Indica al controlador que se encuentra en un menú.

Inicializándola a false en la sección de defaultproperties

bInMenu=false   //Inicialmente no estamos en menú

Añadimos las siguientes funciones:

// Llamada al pulsar ESC. Informa al HUD
exec function ShowMenu()
{
    PFMHUD(myHUD).PressedESC();
}

// Cambios al entrar en menú. Se llamará desde el HUD
function SetInMenu(bool inMenu)
{
    SetPause(inMenu);
    bInMenu = inMenu;
}

Como vemos la función ShowMenu invoca a PressedEsc del HUD, deberemos modificar ahora PFMHUD, quedando de la siguiente manera:

class PFMHUD extends UDKHUD;

var const Texture2D CrosshairTexture;

var bool bShowMenu;         // Mostrar menú
var bool bShowInGameHUD;    // Mostrar HUD ingame

event DrawHUD()
{
    Super.DrawHUD();

    // Se pinta el HUD ingame
    if(bShowInGameHUD)
    {
        if(PlayerOwner != none && PlayerOwner.Pawn != none)
        {
            // Salud
            Canvas.DrawColor = WhiteColor;
            Canvas.Font = class'Engine'.Static.GetLargeFont();
            Canvas.SetPos(Canvas.ClipX * 0.01, Canvas.ClipY * 0.85);
            Canvas.DrawText("HEALTH:"@PlayerOwner.Pawn.Health);

            // Mirilla
            Canvas.SetPos(Canvas.ClipX * 0.5 - CrosshairTexture.SizeX/2, Canvas.ClipY * 0.5 - CrosshairTexture.SizeY/2);
            Canvas.DrawColor = WhiteColor;
            Canvas.DrawTile(CrosshairTexture, CrosshairTexture.SizeX, CrosshairTexture.SizeY, 0.0f, 0.0f, CrosshairTexture.SizeX, CrosshairTexture.SizeY,, true);
        }
    }

    // Menú de pausa
    if(bShowMenu)
    {
        // Fondo negro
        Canvas.SetPos(0,0);
        Canvas.SetDrawColor(10,10,10,64);
        Canvas.DrawRect(Canvas.SizeX,Canvas.SizeY);
    }
}

event PostRender()
{
    Super.PostRender();
}

// Activa/Desactiva el menú Ingame
function ToggleMenu()
{
    bShowMenu = !bShowMenu;             //Activa/Desactiva Menu
    bShowInGameHUD = !bShowMenu;        //Activa/Desactiva HUD
    PFMPlayerController(PlayerOwner).SetInMenu(bShowMenu);  //Informa a PlayerController
    //PFMPlayerInput(PlayerOwner.PlayerInput).ResetMousePosition(0,0);      //Resetea posición del ratón
}

// Llamada al pulsar ESC desde PFMController. Qué hacer dependerá de cada caso
function PressedESC()
{
    // De momento se activa el menu
    ToggleMenu();
}

defaultproperties
{
    bShowMenu=false
    bShowInGameHUD=true

    CrosshairTexture=Texture2D'PfmInterface.Crosshair.Crosshair'
}

Podemos ver que la función PressedEsc invocada por el controlador únicamente activa y desactiva el menú con ToggleMenu (que a su vez le indica al controlador que pause el juego con la función SetInMenu). En DrawHUD de momento se ha añadido un cuadro negro semitransparente que ocupa toda la pantalla para que sirva de comprobación visual.

Los ajustes…

Con esto ya se pausaría el juego al presionar la tecla Escape. El problema es que por algún motivo, el motor está programado para salir de la pausa cuando se dispara (clic con el ratón), se pulsa “saltar” (por defecto espacio) o se pulsa “usar” (por defecto tecla E). Por tanto para evitar que se salga del menú al realizar alguna de estas acciones hay que sobreescribir los métodos que las controlan.

Acción de disparar

Para evitar que al pulsar disparo se salga de la pausa, debemos sobreescribir los métodos StartFire y StopFire en el controlador (en el post “Mejorando la rotación del personaje” ya se hizo así que no sería necesario ahora). Si no los habíamos sobreescrito ya, copiaremos su código de UTPlayerController y eliminaremos la sección que hace que se salga de la pausa.

Acción de usar

Para solucionar esto, bastará sobreescribir el método PerformedUseAction en el controlador y eliminar la parte del código que desactiva la pausa, dejando el resto (En mi caso he quitado código inútil referente al uso de vehículos):

// Copiado de PlayerController para evitar que al 'Usar' se salga de pausa
simulated function bool PerformedUseAction()
{
    if ( Pawn == None )
	{
		return true;
	}

	// below is only on server
	if( Role < Role_Authority )
	{
		return false;
	}

	//SwitchWeapon(10);

	// try to interact with triggers
	return TriggerInteracted();
}

Saltar

Esto requiere un poquito más de trabajo pues el salto se controla en la función Jump de la clase UDKPlayerInput, así que deberemos crear nuestro propio PlayerInput y sobreescribir el método. PFMPlayerInput:

class PFMPlayerInput extends UDKPlayerInput within PFMPlayerController;

// Sobreescrita para evitar que se salga de la pausa al saltar
exec function Jump()
{
    if(WorldInfo.Pauser == None)
	{
        bPressedJump = true;
    }
}

Finalmente le indicaremos a PFMPlayerController que use este PlayerInput, escribiendo en su sección de defaultproperties:

InputClass=class'PFM.PFMPlayerInput'

Ahora sí, al pulsar Escape el juego se pausará completamente, y no saldremos de la pausa con el espacio o disparando, sino pulsando de nuevo Escape:

Mostrando el ratón

Lo siguiente que haremos será mostrar el ratón, que será una pequeña textura que se dibujará en la posición que determine la entrada de ratón. Para obtener su posición deberemos modificar la recién creada PFMPlayerInput, para que guarde las coordenadas del ratón y las haga accesibles a la clase PFMHUD.

Código completo de PFMPlayerInput:

class PFMPlayerInput extends UDKPlayerInput within PFMPlayerController;

var PrivateWrite IntPoint MousePosition;

// Capturamos las coordenadas del ratón sólo cuando estamos en menú
event PlayerInput(float DeltaTime)
{
    if(myHUD != none && bInMenu)
    {
        MousePosition.X = Clamp(MousePosition.X + aMouseX, 0, myHUD.SizeX);
        MousePosition.Y = Clamp(MousePosition.Y - aMouseY, 0, myHUD.SizeY);
    }

    Super.PlayerInput(DeltaTime);
}

// Función usada para resetear la posición del ratón
function ResetMousePosition(int X, int Y)
{
    MousePosition.X = X;
    MousePosition.Y = Y;
}

// Sobreescrita para evitar que se salga de la pausa al saltar
exec function Jump()
{
    if(WorldInfo.Pauser == None)
	{
        bPressedJump = true;
    }
}

Ahora deberemos modificar PFMHUD para obtener estas coordenadas y mostrar la textura del ratón en su posición. Código completo para mostrar el ratón:

class PFMHUD extends UDKHUD;

var const Texture2D CrosshairTexture;
var const Texture2D CursorTexture;

var bool bShowMenu;         // Mostrar menú
var bool bShowInGameHUD;    // Mostrar HUD ingame

event DrawHUD()
{
    local PFMPlayerInput PFMPlayerInput;

    Super.DrawHUD();

    if(PlayerOwner != none)
    {
        PFMPlayerInput = PFMPlayerInput(PlayerOwner.PlayerInput);
        if(PFMPlayerInput == none)
        {
            return;
        }
    }

    // Se pinta el HUD ingame
    if(bShowInGameHUD)
    {
        if(PlayerOwner != none && PlayerOwner.Pawn != none)
        {
            // Salud
            Canvas.DrawColor = WhiteColor;
            Canvas.Font = class'Engine'.Static.GetLargeFont();
            Canvas.SetPos(Canvas.ClipX * 0.01, Canvas.ClipY * 0.85);
            Canvas.DrawText("HEALTH:"@PlayerOwner.Pawn.Health);

            // Mirilla
            Canvas.SetPos(Canvas.ClipX * 0.5 - CrosshairTexture.SizeX/2, Canvas.ClipY * 0.5 - CrosshairTexture.SizeY/2);
            Canvas.DrawColor = WhiteColor;
            Canvas.DrawTile(CrosshairTexture, CrosshairTexture.SizeX, CrosshairTexture.SizeY, 0.0f, 0.0f, CrosshairTexture.SizeX, CrosshairTexture.SizeY,, true);
        }
    }

    // Menú de pausa
    if(bShowMenu)
    {
        // Fondo negro
        Canvas.SetPos(0,0);
        Canvas.SetDrawColor(10,10,10,64);
        Canvas.DrawRect(Canvas.SizeX,Canvas.SizeY);

        // Cursor
        Canvas.SetPos(PFMPlayerInput.MousePosition.X, PFMPlayerInput.MousePosition.Y);
        Canvas.DrawColor = WhiteColor;
        Canvas.DrawTile(CursorTexture, CursorTexture.SizeX, CursorTexture.SizeY, 0.f, 0.f, CursorTexture.SizeX, CursorTexture.SizeY,, true);
    }
}

event PostRender()
{
    Super.PostRender();
}

// Activa/Desactiva el menú Ingame
function ToggleMenu()
{
    bShowMenu = !bShowMenu;             //Activa/Desactiva Menu
    bShowInGameHUD = !bShowMenu;        //Activa/Desactiva HUD
    PFMPlayerController(PlayerOwner).SetInMenu(bShowMenu);  //Informa a PlayerController
    //PFMPlayerInput(PlayerOwner.PlayerInput).ResetMousePosition(0,0);      //Resetea posición del ratón
}

// Llamada al pulsar ESC desde PFMController. Qué hacer dependerá de cada caso
function PressedESC()
{
    // De momento se activa el menu
    ToggleMenu();
}

defaultproperties
{
    bShowMenu=false
    bShowInGameHUD=true

    CrosshairTexture=Texture2D'PfmInterface.Crosshair.Crosshair'
    CursorTexture=Texture2D'PfmInterface.menus.T_Cursor'
}

Ya tenemos ratón:

Mostrando el menú

A continuación veremos las clases y modificaciones necesarias para crear un menú de botones e interactuar con el mismo usando el cursor. Se va a crear una clase específica para los botones, que almacenará su posición, conjunto de texturas, tamaño, etc. Además se creará una clase para representar el menú, que contendrá el conjunto de botones y se encargará de gestionar las funciones activadas por los botones. Para esta prueba el menú de pausa tendrá dos botones, uno para continuar en el juego y otro para salir. Sin más dilación….

PFMHUDButton

class PFMHUDButton extends Object dependson(Canvas);

var float XT;   // Posición izquierda del botón
var float YL;   // Posición en altura del botón

var bool centerX;   // Centrar en X
var bool centerY;   // Centrar en Y

var float Width;    // Ancho del botón
var float Height;   // Altura del botón

var Material material[3];   // Materiales para el botón (0 = normal, 1 = hover, 2 = click)
var Texture2D texture[3];   // Texturas para el botón (0 = normal, 1 = hover, 2 = click)

var bool bUseTextures;      //Usar texturas o materiales

var float U,V,UL,VL;    // Coordenadas de textura

var bool bHover;        // Cursor encima del botón
var bool bClick;        // Clicando sobre el botón

// Comprueba si el ratón está sobre el botón, devuelve true si se ha clicado sobre él
function bool CheckHoverAndClick(Canvas Canvas, float RatioX, float RatioY,IntPoint MousePosition, bool bMousePressed, bool bMouseReleased)
{
    local float OriX;
    local float OriY;
    local float FinalX;
    local float FinalY;

    // Coordenadas reales según el Ratio
    if(centerX)
        OriX = Canvas.ClipX * 0.5 - (Width * RatioX) * 0.5;
    else
        OriX = XT * RatioX;
    if(centerY)
        OriY = Canvas.ClipY * 0.5 - (Width * RatioY) * 0.5;
    else
        OriY = YL * RatioY;

    FinalX = OriX + Width * RatioX;
    FinalY = OriY + Height * RatioY;

    if(MousePosition.X >= OriX && MousePosition.X <= FinalX &&
        MousePosition.Y >= OriY && MousePosition.Y <= FinalY)
    {
        bHover = true;
        if(bMousePressed)
        {
            bClick = true;
        }
        if(bMouseReleased && bClick)
        {
            bClick = false;
            // Se ha soltado el ratón estando dentro => clicado
            return true;
        }
    }
    else
    {
        bHover = false;
        bClick = false;
    }
    return false;
}

// Pinta el botón
function Draw(Canvas Canvas, float RatioX, float RatioY)
{
    local int matId;
    local float OriX;
    local float OriY;

    // Coordenadas reales según el Ratio
    if(centerX)
        OriX = Canvas.ClipX * 0.5 - (Width * RatioX) * 0.5;
    else
        OriX = XT * RatioX;
    if(centerY)
        OriY = Canvas.ClipY * 0.5 - (Width * RatioY) * 0.5;
    else
        OriY = YL * RatioY;

    // Material
    matId = (bClick ? 2 : (bHover ? 1 : 0));

    Canvas.SetPos(OriX, OriY);

    if(bUseTextures)
    {
        Canvas.DrawTile(texture[matId], Width*RatioX, Height*RatioY, U,V,Width,Height,,true);
    }
    else
    {
        Canvas.DrawMaterialTile(material[matId], Width*RatioX, Height*RatioY, U,V,UL,VL);
    }
}

defaultproperties
{
    material(0)=Material'PfmInterface.menus.TestButton'
    material(1)=Material'PfmInterface.menus.TestButton_hover'
    material(2)=Material'PfmInterface.menus.TestButton_click'
    XT=200
    YL=200
    Width=150
    Height=150
    U=0
    V=0
    UL=1.0
    VL=1.0
}

CheckHoverAndClick: Se le pasa las coordenadas del ratón y se encarga de comprobar si este está sobre el botón, para hacer que cambie su material o textura. Si se hace clic sobre este botón, la función devolverá true.

Draw: Se encarga de pintar el botón en las coordenadas adecuadas. Tiene en cuenta un Ratio de pantalla para mantener las proporciones independientemente de la resolución

A continuación…

PFMHUDMenuScene

Esta clase almacena los botones que se deben pintar y se encarga de invocar las funciones pertinentes cuando se hace click sobre alguno de ellos.

class PFMHUDMenuScene extends Object;

var PFMHUD myHUD;       // Referencia al HUD

var array<PFMHUDButton> Buttons;    // Array de botones del menú

function init(PFMHUD PFMHUD)
{
    myHUD = PFMHUD;
}

// Pinta el menú
function Draw (Canvas Canvas, IntPoint MousePosition, bool bMousePressed, bool bMouseReleased)
{
    local int i, clickedButtonId;
    local float RatioX;
    local float RatioY;

    clickedButtonId = -1;   // Inicialmente a -1 => no corresponde a ningún botón

    // Se calcula el ratio para mantener la proporción al dibujar el menú
    RatioX = Canvas.ClipX / 1280;
    RatioY = Canvas.ClipY / 720;

    //Botones
    for(i=0; i<Buttons.Length; i++)
    {
        if(Buttons[i] != none)
        {
            if(Buttons[i].CheckHoverAndClick(Canvas,RatioX,RatioY,MousePosition,bMousePressed,bMouseReleased))
            {
                clickedButtonId = i;
            }
            Buttons[i].Draw(Canvas,RatioX,RatioY);
        }
    }

    // Si se ha clicado un botón
    if(clickedButtonId != -1)
    {
        // Se ejecuta la función asociada
        RunButtonFunction(clickedButtonId);
    }
}

// Ejecuta una función según el índice de botón
function RunButtonFunction(int id)
{
    if(id == 0)
    {
        // Volver al juego
        myHUD.ToggleMenu();
    }
    else if(id == 1)
    {
        // Salir del juego
        myHUD.PlayerOwner.ConsoleCommand("Quit");
    }
}

defaultproperties
{
    Begin Object Class=PFMHUDButton Name=But1
        texture(0)=Texture2D'PfmInterface.menus.T_Button_Resume'
        texture(1)=Texture2D'PfmInterface.menus.T_Button_Resume_hover'
        texture(2)=Texture2D'PfmInterface.menus.T_Button_Resume_click'
        bUseTextures=true
        XT=400
        YL=200
        centerX=true
        centerY=false
        Width=300
        Height=100
        U=0
        V=0
        UL=1.0
        VL=1.0
    End Object
    Buttons(0)=But1

    Begin Object Class=PFMHUDButton Name=But2
        texture(0)=Texture2D'PfmInterface.menus.T_Button_Quit'
        texture(1)=Texture2D'PfmInterface.menus.T_Button_Quit_hover'
        texture(2)=Texture2D'PfmInterface.menus.T_Button_Quit_click'
        bUseTextures=true
        XT=400
        YL=350
        centerX=true
        centerY=false
        Width=300
        Height=100
        U=0
        V=0
        UL=1.0
        VL=1.0
    End Object
    Buttons(1)=But2
}

Draw: Va recorriendo la lista de botones y los pinta, en caso de que se haya hecho clic en alguno, ejecuta su función asociad con RunButtonFunction.

RunButtonFunction: Ejecuta la función asociada al botón con el Id pasado. En este caso con el botón 0 desactivamos el menú y con el 1 salimos del juego.

Como se ve en la sección de defaultproperties, es ahí donde se definen los botones de los que va a consistir el menú. Los materiales o texturas habrá que haberlos importado previamente a UDK.

PFMHUD

De nuevo hay que modificar PFMHUD, para que inicialice y pinte el menú, además de indicarle cuándo se hace clic. Código completo (ahora sí):

class PFMHUD extends UDKHUD;

var const Texture2D CrosshairTexture;
var const Texture2D CursorTexture;

var bool bShowMenu;         // Mostrar menú
var bool bShowInGameHUD;    // Mostrar HUD ingame

var bool bMousePressed;     // Ratón pulsado
var bool bMouseReleased;    // Ratón soltado

var PFMHUDMenuScene menu;

event DrawHUD()
{
    local PFMPlayerInput PFMPlayerInput;

    Super.DrawHUD();

    if(PlayerOwner != none)
    {
        PFMPlayerInput = PFMPlayerInput(PlayerOwner.PlayerInput);
        if(PFMPlayerInput == none)
        {
            return;
        }
    }

    // Se pinta el HUD ingame
    if(bShowInGameHUD)
    {
        if(PlayerOwner != none && PlayerOwner.Pawn != none)
        {
            // Salud
            Canvas.DrawColor = WhiteColor;
            Canvas.Font = class'Engine'.Static.GetLargeFont();
            Canvas.SetPos(Canvas.ClipX * 0.01, Canvas.ClipY * 0.85);
            Canvas.DrawText("HEALTH:"@PlayerOwner.Pawn.Health);

            // Mirilla
            Canvas.SetPos(Canvas.ClipX * 0.5 - CrosshairTexture.SizeX/2, Canvas.ClipY * 0.5 - CrosshairTexture.SizeY/2);
            Canvas.DrawColor = WhiteColor;
            Canvas.DrawTile(CrosshairTexture, CrosshairTexture.SizeX, CrosshairTexture.SizeY, 0.0f, 0.0f, CrosshairTexture.SizeX, CrosshairTexture.SizeY,, true);
        }
    }

    // Menú de pausa
    if(bShowMenu)
    {
        // Fondo negro
        Canvas.SetPos(0,0);
        Canvas.SetDrawColor(10,10,10,64);
        Canvas.DrawRect(Canvas.SizeX,Canvas.SizeY);

        Canvas.DrawColor = WhiteColor;

        // Menú
        if(menu == none)
        {
            menu = new class'PFMHUDMenuScene';
            menu.init(self);
        }
        else
        {
            menu.Draw(Canvas,PFMPlayerInput.MousePosition, bMousePressed, bMouseReleased);
            // Una vez dibujado y procesado el ratón, se ponen los flags a falso
            bMousePressed = false;
            bMouseReleased = false;
        }

        // Cursor
        Canvas.SetPos(PFMPlayerInput.MousePosition.X, PFMPlayerInput.MousePosition.Y);
        Canvas.DrawColor = WhiteColor;
        Canvas.DrawTile(CursorTexture, CursorTexture.SizeX, CursorTexture.SizeY, 0.f, 0.f, CursorTexture.SizeX, CursorTexture.SizeY,, true);
    }
}

event PostRender()
{
    Super.PostRender();
}

// Activa/Desactiva el menú Ingame
function ToggleMenu()
{
    bShowMenu = !bShowMenu;             //Activa/Desactiva Menu
    bShowInGameHUD = !bShowMenu;        //Activa/Desactiva HUD
    PFMPlayerController(PlayerOwner).SetInMenu(bShowMenu);  //Informa a PlayerController
    //PFMPlayerInput(PlayerOwner.PlayerInput).ResetMousePosition(0,0);      //Resetea posición del ratón
}

// Llamada al pulsar ESC desde PFMController. Qué hacer dependerá de cada caso
function PressedESC()
{
    // De momento se activa el menu
    ToggleMenu();
}

// Llamada desde PFMPlayerController
function MousePressed()
{
    bMousePressed = true;
}

// Llamada desde PFMPlayerController
function MouseReleased()
{
    bMouseReleased = true;
}

defaultproperties
{
    bShowMenu=false
    bShowInGameHUD=true

    CrosshairTexture=Texture2D'PfmInterface.Crosshair.Crosshair'
    CursorTexture=Texture2D'PfmInterface.menus.T_Cursor'
}

Además de inicializar y pintar el menú se han añadido las funciones MousePressed y MouseReleased. Estas serán invocadas desde PFMPlayerController cuando se pulse el botón izquierdo del ratón y cuando se suelte respectivamente. Sólo falta añadir esa invocación en PFMPlayerController, en las funciones StartFire y StopFire:

exec function StartFire( optional byte FireModeNum )
{
    if(bInMenu && FireModeNum == 0)
    {
        PFMHUD(myHUD).MousePressed();
    }
	else if ( Pawn != None && !bCinematicMode && !WorldInfo.bPlayersOnly && !IsPaused())
	{
        lastFireModeNum = FireModeNum;      // Se guarda el modo de disparo para los disparos retardados.
        if(CheckIfCanFire(FireModeNum))     // Si se puede disparar directamente:
        {
            Pawn.StartFire( FireModeNum );  // se hace.
        }
	}
}

exec function StopFire(optional byte FireModeNum)
{
    if(bInMenu && FireModeNum == 0)
    {
        PFMHUD(myHUD).MouseReleased();
    }
    else
    {
        Super.StopFire(FireModeNum);
        if(bTurningToFire)              // Si se ha dejado de pulsar el botón de disparo mientras se gira,
        {
            bPendingStopFire = true;    // se activa el flag para tenerlo en cuenta.
        }
    }
}

Ya está, después de todo este rollo por fin hemos conseguido un sencillo menú de pausa con un par de botones que podemos activar con el ratón:

🙂
Banner Blog

Anuncios

30 pensamientos en “PFM: Interfaz en UDK – Menú de Pausa

  1. Muy buen post Marcos, largo pero fácil de dirigir. Supongo que al igual que dale resume y quit al pausar se podría añadir alguna imagen o video, no?

    • Sip, de hecho los botones que yo he añadido son imágenes. No he probado a poner ninguna animación pero creo que habría que hacer algunos ajustes, ya que al estar pausado el juego, las animaciones también lo estarían.

  2. Pingback: PFM: Scripting de cinemáticas con Kismet y Matinee | El Blog de Marcos

  3. Pingback: PFM: Interfaz en UDK – Creando el menú principal | El Blog de Marcos

  4. Disculap eh intentado lo de la programacion modificando en el UTGame… los codigos q muestras… pero al compilar me sale con error….
    la dudas son…
    – se puede modificar con el UTGame? … o se pueden eliminar y crear unas nuevas…
    – o tengo q crear una nueva clase…..
    espero pronto tu respuesta o las respuestas de otros me ayudarian mucho.. apenas eh iniciado con esto de l aprogramacion de UDK ….

    y gracias por su paciencia xD …..

    • Hola Okazaki.

      Es muy poco recomendable modificar las clases que ya existen en UDK como UTGame. Para modificar sus comportamientos lo que se hace es crear clases nuevas que hereden de estas y ya modificar lo que queramos. Es decir, crear una nueva clase que extienda de UTGame, etc.

      De todas maneras, en esta entrada no utilizo ninguna clase de tipo Game, y si has metido el código tal cual en UTGame, es normal que no compile :lol:. Esta entrada es medianamente avanzada, y requiere conocimientos previos para saber dónde modificar y entender lo que estoy haciendo.

      Si estás empezando con UDK este artículo es mala elección para comenzar, pues como te digo es un poco avanzado. Si quieres empezar desde algo más básico te recomiendo que veas los primeros pasos con UDK y vayas viendo los artículos siguientes en esta página, donde voy poniendo las nuevas entradas que añado. Empieza por lo básico, crear un GameType propio, crear una cámara en tercera persona, etc. Así irás entendiendo poco a poco la estructura de UDK. Y si tienes cualquier problema, no dudes en preguntar que te intentaré ayudar en la medida de lo posible.

      Suerte y un saludo!

    • joooo muchas gracias .. eh estado buscando por un buen tiempo … alguna clase de ayuda basica XD… pero por lo general eh estado es pillando tutoriales y haciendo a imaginacion con el kismet xd… algunas cosas me han salido y otras no.. pero ya la parte de programar como tal escribeindo codigos si me da un poco duro…

      gracias por las paginas les echare un ojo >_O b ..
      alguna duda te pregunto gracias ^_^

  5. Saludos Marcos… molestandote en esta parte xD……
    tengo un problema con estos warnings…..
    “http://fotos.subefotos.com/60da060b9cd5a44038d28be292d46117o.png”

    los eh intentado reemplazar con materiales y testuras pero me siguen dando el mismo error no se si abra q reemplazarlo con algun otro formato diferente….

    Gracias >_O b

    • Fíjate que en esa propiedad debes meter un material. El material no es lo mismo que una textura, aunque un material puede usar texturas. Tanto los materiales como las texturas debes crearlas en el editor de UDK, importando imágenes para las texturas y creando los materiales. Una vez importados debes escribir en el código la ruta correcta con paquete.grupo.nombre del material o textura según el caso. En el ejemplo Material’PFMInterface.menus.testButtonPFMInterface es el paquete, menus es el grupo y testButon es el nombre del material.

    • ohh ya veo en este caso es escribiendo la ruta tal cual del paquete hasta donde este el archivo q vaya a usar…. muchas gracias ^_^ … lo intentare a ver….

      y otra duda.. provando con lso “playanousement” me di cuenta q quedaban centradas las letras y de color azul … como puedo modificar eso ? ..

      gracias >_O b

    • okay xD ….. solo q lo normal era q siempre estaba arriba y de color blanco .. pero se cambio a estar centrada y en azul xD… pense q habias modificado algo asi xD…

  6. hola que tal pues es buen codigo, pero tenia un problema, bueno en principio presiono pausa y va bien, pero el cursor no se mueve, in cluso en la linea donde declaro la variable: var PrivateWrite IntPoint MousePosition; el “MousePosition” me aparece subrayado y me sale parser extraneaus input al colocar el culsor sobre la palabra, me compila sin errores pero nada, no tengo ni idea que pasa, que crees que puede ser?

    • ¿Qué editor estás usando para desarrollo? Los únicos errores o warning de los que te debes fiar son los que te de el compilador, si este no se queja del MousePosition es que no hay nada mal a priori.
      El motivo de que no se mueva puede ser o que no está capturando correctamente las coordenadas del ratón, o que no estás usando las coordenadas para pintar la textura del cursor correctamente. Comprueba si en la función de captura del ratón (PlayerInput) está entrando en el bloque if o si las coordenadas de MousePosition varían.

  7. hola, estoy trabajando con el de 07/12, al final no encontré la solución, tampoco busque tanto, aun así, si que me sirvió para que al presionar pausa, aparezca el mapa del juego, modificando unas lineas de código y listo, no seguí buscando por que no tenia mucho tiempo, aun asi te felicito por el blog, en general es bastante explicito y asi es facil de aplicar al juego, ya subire un video con las mecanicas y tal del mio, pero si te quieres pasar a ver unas imagenes te dejo el enlace:
    http://www.behance.net/gallery/Lost-Homeland/7897285
    Hack and Slash con toques de sigilo, ambientación steampunk y retrofuturista.

  8. hola marcos ! tengo algunas dudas sobre los materiales y las texturas…
    los tres materiales los hice con la misma textura (una toda blanca )
    y las texturas de resume y quit las hice en photoshop con fondo transparente,
    cuando compila no me tira ni errores ni warnings solo que cuando pauso no aparese ningun cartel solo el cursor.. obviamente creo yo que son los materiales y quizas las texturas,
    si me podrias darme alguna indicacion de como preparar los materiales creo que terminaria sin problemas! gracias!!

    • Hola Yael. Fíjate que PFMHUDButton está preparado tanto para usar materiales como texturas simples. En PFMHudScene yo he usado texturas simplemente, por lo que no necesité crear materiales para el botón de resume o quit:

      Como ves al declarar el botón en defaultproperties, lo que uso son texturas, no materiales:

      Begin Object Class=PFMHUDButton Name=But1
      texture(0)=Texture2D’PfmInterface.menus.T_Button_Resume’
      texture(1)=Texture2D’PfmInterface.menus.T_Button_Resume_hover’
      texture(2)=Texture2D’PfmInterface.menus.T_Button_Resume_click’
      bUseTextures=true

      También acuérdate que en Width y Height debes poner el tamaño en pixeles de tu textura para que la muestre completa.

      Asegúrate de que estuvieses usando texturas para los botones y si sigue sin funcionar me comentas. 😉

  9. Hola marcos!.. era eso el tamaño de los pixeles pero tengo el siguiente problema..

    el mouse no lo puedo llevar a hasta arriba y los botones estan abajo y a un costado..
    sabras en que parte del codigo se ajusta eso ?
    Gracias!!

    • Mmmm.. revisa la parte del cursor, parece que se muestra desplazado y por eso los botones reaccionan mal. Siento no poder darte más pistas porque esto no me ha pasado la verdad xD

  10. Solucionado despues de quemarme la cabeza un poco ^^
    era la resolucion de la textura del cursor.. era muy grande ^^
    gracias!

  11. Hola! muy bueno pero tengo una duda, para que es skimlinks-unlinked ? al compilar me da error justo en las lineas en donde esta eso.

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