jueves, 24 de octubre de 2013

4) Dale al diseñador lo que quiere. Arquetipos para todos

¡Muy buenas!

Aquí nos encontramos de nuevo en el mágico mundo Digimon de la programación en UnrealScript. Hoy con nosotros: ¡Arquetipos! ¿Y qué narices es esto? Instancias de objetos referenciadas que se pueden tocar en tiempo real para el disfrute y frote de la gente que tiene que montar el juego. De este modo, desde el Content Browser, guardaremos en un paquete nuestros propios Pawn con una configuración determinada, que podremos modificar mientras el juego está funcionando. En el código, referenciaremos ese Pawn para que lo lea tal y como lo queramos.
Igualmente, haremos un "fake" de arquetipo para nuestras cámaras, ya que, de momento, y aunque pueden ser actores también en las escenas, nosotros creamos una clase que no tiene "materialización" en la escena hasta que no comienza el juego. Crearemos una clase NULLCameraTDAttributes, cuyas variables leeremos desde nuestra cámara NULLCameraTopDown, para poder modificar en tiempo real sus características. ¡Al lío!

Nuestra aventura de hoy nos lleva a adentrarnos en el magico mundo del editor. En el Content Browser, pestaña Actor Classes, buscamos bajo la categoría NULLGame, nuestro NULLPawn. Botón derecho y crear Arquetipo. Nos pide un Paquete, un nombre de agrupamiento y el nombre del arquetipo. Podemos poner NULLCharacters como nombre del paquete, de agrupamiento Characters y como nombre de arquetipo arc_NULLTestPawn.

Ahora si volvemos al content browser, bajo el apartado Packages abajo a la izquierda por defecto, hay una carpeta llamada NewPackages. La desplegamos y vemos nuestro paquete. Botón derecho y guardar. Lo lleváis a la carpeta Content/NULLContent/ y lo guardáis con la jerarquía de carpetas que queráis como os sintáis más cómodos y ordenados.

Ya tenemos nuestro arquetipo. Tendremos que buscarlo en el content browser después para conocer su Full Name y dárselo a una de nuestras variables de NULLGameInfo.

En primer lugar, GameInfo tiene una función encargada de "spawnear" un Pawn por defecto para que PlayerController lo posea (no me pongo érotico, es que PlayerController tiene una función UnPossess y Possess cual espíritu maligno para controlar los Pawns que le indiquemos). Dicha función es "function Pawn SpawnDefaultPawnFor(Controller NewPlayer, NavigationPoint StartSpot)"

Mi recomendación es que le echéis un ojo en la clase base. Ahora colocamos esta función en la clase que ya tenemos de GameInfo

NULLGameInfo.uc

...
/**
 * Returns a pawn of the default pawn class
 *
 * @param    NewPlayer - Controller for whom this pawn is spawned
 * @param    StartSpot - PlayerStart at which to spawn pawn
 *
 * @return    pawn
 */
function Pawn SpawnDefaultPawnFor(Controller NewPlayer, NavigationPoint StartSpot)
{
    //local class<Pawn> DefaultPlayerClass;
    local Rotator StartRotation;
    local Pawn ResultPawn;

    //Comentamos esta línea ya que no vamos a utilizar una clase para el jugador
    //Si no nuestro propio arquetipo
    //DefaultPlayerClass = GetDefaultPlayerClass(NewPlayer);

    // don't allow pawn to be spawned with any pitch or roll
    StartRotation.Yaw = StartSpot.Rotation.Yaw;

    //ResultPawn = Spawn(DefaultPlayerClass,,,StartSpot.Location,StartRotation);
    //Aquí podéis ver la diferencia entre el original de la función
    //Y como spawneamos nuestro arquetipo.
    //Nos faltará declarar la variable
    //var const archetype Pawn DefaultPawnArchetype;
    //Al inicio de nuestra clase
    ResultPawn = Spawn(DefaultPawnArchetype.Class,,,StartSpot.Location,StartRotation,DefaultPawnArchetype);

    if ( ResultPawn == None )
    {
        `log("[NULLGameInfo] Couldn't spawn player of type "$DefaultPawnArchetype.Class$" at "$StartSpot);
    }
    return ResultPawn;
}
...


Bien, como indico en los comentarios nos faltará añadir la variable:

var const archetype Pawn DefaultPawnArchetype;

y darle un valor en nuestro DefaultProperties. El cual, iremos al editor, buscaremos nuestro Pawn creado en su paquete y copiaremos su nombre total Copy Full Name to Clipboard y lo pegaremos de este modo

DefaultProperties
{
  DefaultPawnArchetype=<IntroduzcaAquí SuTabacoGracias>
}

Comentamos la línea: //DefaultPawnClass=class'NULLGame.NULLPawn' ya que ya no usamos un Pawn normal, si no un arquetipo.

Y Voilá. Podremos ejecutar en el Editor nuestro juego y modificar mediante el content browser y seleccionando el arquetipo con F4 sus propiedades.

Podemos hacer la prueba y buscar otra skeletal Mesh y ver cómo cambia en tiempo real :D

¡Por cierto! Si no sabéis ejecutar un tipo de juego concreto en el Editor, es en la pestaña View->WorldProperties->GameType y allí en DefaultGameType y GameType for PIE colocáis vuestra clase de juego NULLGameInfo. Luego le dáis a la flechita verde que hay en la barra de arriba o en la venta que queráis ejecutar el juego y a disfrutar.

Tened en cuenta, que la malla se carga al iniciar el juego. Si desligáis el skeletalMeshComponent actual mientras se ejecuta, la malla desaparecerá pero no se cargará la nueva hasta volver a iniciar. Al ser placeable, un diseñador puede arrastrar a la escena el arquetipo y comprobar el aspecto final que desee en el juego.

Ahora podemos, colocar las variables de nuestra cámara en una clase que herede de las más básicas en UDK, que es Object, ocultar todo componente que no nos interese y dejar sólo al descubierto las variables y valores que queramos modificar.

Para ello generamos una clase llamada NULLCameraTDAttributes:

NULLCameraTDAttributes.uc

class NULLCameraTDAttributes extends Object
HideCategories(Object);

var (Camera) float altitude;

defaultproperties
{
    altitude=500.0f
}

HideCategories es un flag que oculta las categorías indicadas separadas por comas que no queramos mostrar en las propiedades desde el editor (con F4). De este modo, creamos una categoría camera (al colocar entre paréntesis en una variable como se indica), con la variable altitude.

Vamos al editor y creamos nuestro arquetipo de NULLCameraTDAttributes (ojo que seguramente tendréis que desactivar algun booleano de los que aparecen en la pestana Actor Classes del Content Browser para poder ver esta clase) y siguiendo pasos parecidos a los que hemos realizado antes con el Pawn.

Ahora en nuestra cámara deberemos consultar este valor. Creamos una variable:
var const NULLCameraTDAttributes CameraAttributes;

En la funcion UpdateViewTarget(out TViewTarget OutVT, float DeltaTime) cambiamos donde teníamos a pelo la altura de la cámara en unidades de Unreal por CameraAttributes.altitude.

Ahora nos faltará colocar en nuestra cámara en default properties en valor de la variable CameraAttributes.

IMPORTANTE: En DefaultProperties de vuestro Pawn, debéis colocar Mesh=NameDelSkeletalMesh para poder modificar la malla del mismo mediante el arquetipo.

¡Y ya podemos en tiempo real cambiar la altura de nuestra cámara!

¡Nos vemos en el siguiente tutorial!





viernes, 11 de octubre de 2013

3) Triunvirato ganador: PlayerController, Camera y Pawn.

¡Muy buenas!

Como vimos anteriormente, en el fichero de configuración DefaultGame.ini,  tenemos que especificar, qué clase se encarga de controlar los "pawns", representaciones físicas en UDK de personajes, puesto que la clase Pawn se encarga de manejar sus atributos y también tenemos un "GameManager" encargado de controlar qué tipo de juego estamos jugando, y cómo funciona el mismo. Para ello heredamos de la clase base de UDK GameInfo.

Sin más dilación, pasamos a modificar nuestros ficheros base del juego: NULLGameInfo,  NULLPawn, NULLPlayerController.

NULLGameInfo.uc

class NULLGameInfo extends GameInfo;

auto State PendingMatch
{
Begin:
    StartMatch();
}

defaultproperties
{
    //Más adelante podremos crear nuestra propia clase para HUD.
    //La especificaremos aquí
    HUDType=class'GameFramework.MobileHUD'
    //La clase que controlará nuestro Pawn. Claramente la que ya tenemos
    PlayerControllerClass=class'NULLGame.NULLPlayerController'
    //Qué tipo de Pawn aparecerá al iniciar el juego por defecto.
    //Más tarde cuando veamos los arquetipos cambiaremos esto
    DefaultPawnClass=class'NULLGame.NULLPawn'
    //Un flag para que no espere al comenzar el juego
    bDelayedStart=false
}

Como veis, es sólo un esqueleto y básicamente, está todo explicado con pequeños comentarios.

NULLPawn.uc

  class NULLPawn extends Pawn
    //Si queremos poder colocarla en el editor, debemos
    //marcar esta clase como placeable
    placeable
    //Como vimos antes, hace referencia a un fichero de
    //configuración del que se podrá configurar variables
    //Bajo el apartado [NULLGame.NULLPlayerController]
    config(Game)
    //ClassGroup nos sirve para que en la pestaña del
    //Content Browser "classes" nos aparezca bajo
    //Un apartado con este nombre <NULLGame> en este caso
    ClassGroup(NULLGame);

defaultproperties
{

//Componente Skeletal Mesh.Malla del personaje con esqueleto
Begin Object Class=SkeletalMeshComponent Name=MyPawnSkeletalMesh
    //Un SkeletalMesh de la instalación con Unreal Tournament. Si tenéis la limpia
    //Creo que hay otra que debéis buscar en el editor y botón derecho y copiar
    //su Full Name to Clipboard para copiarlo aquí
    SkeletalMesh=SkeletalMesh'UTExampleCrowd.Mesh.SK_Crowd_Robot'
    //AnimSets son colecciones de animaciones para usar con esta malla
    //The udk package should be under UDKGame/Content.
    //Right click on the animset in the content  browser and
    //copy full name to clipboard.
    //There is no animset in the custom installation ready
    //AnimSets(0)=AnimSet’EternalCrisis_Characters.Female.Human_Athletic_AnimSet’
    //The same for the animtree
    //AnimTreeTemplate=AnimTree’EternalCrisis_Characters.Human_Test’
    HiddenGame=FALSE
    HiddenEditor=FALSE
End Object

//Add it to the Actor’s components
Components.Add(MyPawnSkeletalMesh)

//Very important if we don’t want our character embracing the shadows forever
Begin Object Class=DynamicLightEnvironmentComponent Name=MyLightEnvironment
    //Different flags from the component
    bUseBooleanEnvironmentShadowing=false
    bIsCharacterLightEnvironment=TRUE
    bSynthesizeSHLight=TRUE
End Object

//Adding the component again
Components.Add(MyLightEnvironment)

}
Como veis en esta clase, también he colocado comentarios. Algunos en inglés, ya que he sido un poco perro y los he utilizado de mi antiguo blog. Igualmente, está actualizado con respecto a dicha página.

Cosillas interesantes en este caso. En primer lugar, el flag placeable en la declaración de la clase, hace que se pueda colocar este tipo de actor en las escenas a través del Editor. También he añadido el flag ClassGroup, que sirve principalmente para tener un poco ordenado el código y poder encontrar más facilmente las clases que creemos a través del Conter Browser, en la pestaña Classes, bajo el nombre NULLGame en nuestro caso.

Y después entramos en las DefaultProperties. En las clases de UDK, toda variable se coloca en el principio de la clase, declarando básicamente "var tipoDeVar nombreDeVar". Recalco el básicamente, que como ya sabéis hay ciertas estructuras que requieren otra nomenclatura para ser declaradas y que pueden ser Const, Static... Cosas de programadores rancios, ya sabéis a lo que me refiero.

En vez de poder iniciar dichas variables allí mismo como podríais hacer en C, debéis hacerlo en el interior de las llaves de DefaultProperties. ¡Sed cuidadosos! Colocad exactamente DefaultProperties y debajo la apertura de llave (símbolo {) ya que si la colocáis al lado de DefaultProperties, el compilador, mágico y especialito, se quejará y os dirá una línea de otro lugar como el problema, dándoos más de un quebradero de cabeza. Igualmente, DefaultProperties siempre debajo de todas las funciones de código o el compilador ignorará que está delante a la hora de marcaros la línea donde se producen errores, volviéndonos claramente a un estado primario de primate que arranca teclas de un instrumento que no comprende.

Con respecto a cómo están formados los actores, se rigen por una composición de componentes. Es algo parecido a Unity pero sin ser visual. Lo cual da más quebraderos de cabeza. Básicamente un actor se forma con piezas (componentes), que disponen de sus propios atributos y variables que configurar. Un componente se crea mediante la fórmula:

Begin Object Class=<ClaseDelComponente> Name=<NombreQueMeSalgaDelHigo>
<Valores de variables>
End Object

Y posteriormente, posee el actor una estructura llamada Components (básicamente una lista), a la que le "añadimos" los componentes que deseemos. Más información la tenéis en este apartado de la UDN: UDN Components

Y ahora vamos con NULLPlayerController, controlador de nuestro recién creado Pawn.

NULLPlayerController.uc

class NULLPlayerController extends PlayerController
    //Como vimos antes, hace referencia a un fichero de
    //configuración del que se podrá configurar variables
    //Bajo el apartado [NULLGame.NULLPlayerController]
    config(Game);

Como podéis ver, de momento, no vamos a tocar mucho esta clase. Simplemente me aseguro de heredar de la clase más básica de PlayerController con la que contamos (que a su vez hereda de Controller, pero eso ya es otra historia... Que podéis investigar en la carpera Development/Src/Engine/Classes como ya comenté...).

Si nos vamos ahora a nuestro IDE, y ejecutamos, veremos que ya está funcionando nuestro Pawn con una cámara que está dentro de él (mirad hacia abajo con el ratón para descubrir las vergüenzas de la malla elegida para vuestro pawn en el SkeletalMesh).

¡Ya estamos a medio camino de tener una base decente para trastear! Como indico en el título, la cámara que tenemos es un tanto "limitada". Y nos gustaría poder vernos de algún modo.

La primera solución se encuentra en configurar nuestro NULLPlayerController un poco más para indicarle que no queremos una cámara por defecto, si no una propia. Primero confeccionaremos la cámara con funcionalidad TopDown y luego la aplicaremos a nuestro "juego". ¡Al ataquerrrl con la cámara! (Que por cierto, la tenéis que crear en Development/Src/NULLGame/Classes por si se os ha olvidado a alguno).

NULLCameraTopDown.uc

   class NULLCameraTopDown extends Camera;

    /**
    * Query ViewTarget and outputs Point Of View.
    *
    * @param    OutVT        ViewTarget to use.
    * @param    DeltaTime    Delta Time since last camera update (in seconds).
    */
    function UpdateViewTarget(out TViewTarget OutVT, float DeltaTime)
    {

    // Don’t update outgoing viewtarget during an interpolation
    if( PendingViewTarget.Target != None && OutVT == ViewTarget && BlendParams.bLockOutgoing )
    {
    return;
    }

    //AQUÍ colocamos dónde queremos que se coloque la cámara.
    //Esta función nos da una estructura como parámetro de tipo
    //TViewTarget que en su interior tiene un objeto POV
    //Que es el Point of view de la cámara.
    //Tiene un vector Location para modificarla
    //Y también Rotation con el clásico
    //Roll, Pitch y Yaw en unidades de UnrealRotation
    OutVT.POV.Location.Z = 500;
    //Following target in XY plane
    OutVT.POV.Location.X = OutVT.Target.Location.X ;
    OutVT.POV.Location.Y = OutVT.Target.Location.Y ;
    OutVT.POV.Rotation.Pitch = -90 * DegToUnrRot; //DegToUnrRot is a constant to transform degrees to UnrealRotation units
    //UnrRotToDeg exists too

    // Apply camera modifiers at the end (view shakes for example)
    ApplyCameraModifiers(DeltaTime, OutVT.POV);

    }

    DefaultProperties
    {

    }
Bien, simplemente es para ir dando un pequeño bocado a la cámara y su funcionamiento. Básicamente como explico en los comentarios, sobreescribimos la función de la clase base Camera UpdateViewTarget que es la encargada de colocar la cámara donde debería. Las cámaras tienen muchas otras funciones y dependiendo de lo que necesitéis realizar en vuestro proyecto, tendréis que tocar más cosas. Pero ahora estamos con lo básico :)
En este caso, tenemos una Top Down camera (vista cenital) a 500 unidades de Unreal de distancia de nuestro Pawn. Ahora sólo falta indicarle a nuestra clase de PlayerController que queremos utilizar esta cámara.

NULLPlayerController.uc

class NULLPlayerController extends PlayerController
    //Como vimos antes, hace referencia a un fichero de
    //configuración del que se podrá configurar variables
    //Bajo el apartado [NULLGame.NULLPlayerController]
    config(Game);
   
defaultproperties
{
CameraClass=class'NULLGame.NULLCameraTopDown'

Simple, sencillo y para toda la familia: Modificamos la variable CameraClass heredada de la clase base PlayerController y le indicamos que es la clase que acabamos de crear.

Ejecutamos en nuestro IDE ;) Y disfrutamos de la magnificencia de lo logrado (si no es así, toca repasar los pasos anteriores :P).

Como podéis ver, ya tenemos una base para hacer cosas. Sin embargo, necesitamos el poder del Editor para poder configurar la cámara como deseemos o nuestro propio Pawn. Sobretodo si trabajamos con diseñadores o artistas que les gusta jugar con sliders, valores y demás historias que para nosotros son matemática fría :D

Pero eso tendrá que ser en la próxima entrega de "4) Dale al diseñador lo que quiere. Arquetipos para todos".

¡Un saludo!




2) Config que te config

¡Muy buenas!

Ya tenemos nuestro flamante UDK en nuestro disco duro, listo para ser trasteado. Si utilizáis la opción de instalación sin assets, os vendrá todo ya configurado para que abráis el IDE y le déis a ejecutar y ya funcione una cámara muy precaria libre, con un mapa por el que puedas moverte.

Si por el contrario, os gustan las cosas bonitas y brillantes y no sois unos urraquillas, entonces tendréis que configurar algunos ficheros para tener un proyecto propio.

Lo primero que debemos hacer es abrir el editor y guardar un mapa para poder trastear con él. En la pestaña File arriba a la izquierda podéis guardar con un nombre el que viene por defecto con el nombre NULLDefaultMap.udk. Más adelante lo utilizaremos para iniciar nuestro proyecto con él. Por favor, aseguraos que tiene un PlayerStart y al menos una fuente de Luz. Mi recomendación es que seleccionéis la escena que tiene luz de atardecer o día de las que te permite al principio antes que una escena vacía si no controláis el uso del Editor. Guardad dicho nivel en la carpeta UDKGame/Content y allí donde prefiráis.

En primer lugar, deberemos pensar un prefijo para nuestro juego. En nuestro caso es NULL y por ende, crearemos en la carpeta Development/Src/ una carpeta llamada NULLGame y dentro de la subcarpeta a su vez Classes [Development/Src/NULLGame/Classes].

Allí crearemos unos ficheros .uc básicos de funcionamiento, copiados tal cual, de los que genera con la instalación vacía. Os los dejo por aquí:

 NULLGameInfo.uc
class NULLGameInfo extends GameInfo;

auto State PendingMatch
{
Begin:
    StartMatch();
}

defaultproperties
{
    HUDType=class'GameFramework.MobileHUD'
    PlayerControllerClass=class'NULLGame.NULLPlayerController'
    DefaultPawnClass=class'NULLGame.NULLPawn'
    bDelayedStart=false
}


NOTA: Nótese que todo aquello que tenga el prefijo NULL en el código, debe cambiarse por el prefijo de nuestro juego. Al igual que ser modificado en el nombre de los ficheros que contienen el código.

NULLPlayerController.uc

class NULLPlayerController extends GamePlayerController
    config(Game); 
NULLPawn.uc

class NULLPawn extends GamePawn
    config(Game); 

Bien, en estos momentos, ya tenemos un "juego" básico, con la cámara libre como tendríamos en una instalación "limpia" de UDK.

 Ahora nos toca en el IDE de Real Script o bien "a pelo" en la carpeta UDKGame/Config modificar algunos ficheros .ini listados a continuación.


DefaultEngine.ini

Aquí veremos que hay diferentes "apartados" colocados entre []. Se refieren a clases que "leen" de ficheros de configuración. Suele estar compuesto del siguiente modo: <CarpetaDentroDeDevelopment>.<ClaseDondeSeVaAModificarLasVariablesQueColoquemosDebajo>

Sabiendo esto, buscamos [Engine.ScriptPackages]
Debajo, modificamos para que sea:

[Engine.ScriptPackages]
+NonNativePackages=NULLGame

Lo que estamos diciendo al motor es que tenemos una carpeta llamada NULLGame en Development/Src con scripts que queremos utilizar. Continuamos con más apartados

[UnrealEd.EditorEngine]
+EditPackages=NULLGame
Queremos que se pueda utilizar en el editor los scripts de nuestro juego.

[Engine.StartupPackages]
+Package=FX_HitEffects
+Package=UDKFonts
+Package=NULLGame
Pues lo mismo, añadimos nuestro juego a la carga de paquetes que se cargan al iniciarse.

Como último retoque, es necesario que indiquemos un mapa para iniciar. Para eso, bastaría con iniciar el editor de UDK y guardar el mapa por defecto en nuestra carpeta NULLContent/Maps con el nombre que queráis. En mi caso, NULLDefaultMap:

[URL]
MapExt=udk
; Any additional map extension to support for map loading.
; Maps without an extension always saved with the above MapExt
AdditionalMapExt=mobile
Map=NULLDefaultMap.udk
LocalMap=NULLDefaultMap.udk
TransitionMap=EnvyEntry.udk
EXEName=NULLGame.exe
DebugEXEName=DEBUG-NULLGame.exe

Como mencioné antes, hay que modificar una pequeña cosilla en DefaultEngineUDK.ini

DefaultEngineUDK.ini

[UnrealEd.EditorEngine]
EditPackagesOutPath=..\..\UDKGame\Script
FRScriptOutputPath=..\..\UDKGame\ScriptFinalRelease
+EditPackages=UDKBase
+EditPackages=UTEditor
+EditPackages=NULLGame
;ModEditPackages=MyMod
AutoSaveDir=..\..\UDKGame\Autosaves
InEditorGameURLOptions=?quickstart=1?numplay=1


Una vez hecho esto, pasamos al fichero DefaultGame.ini. Modificamos el tipo de juego con el que queremos iniciar:

DefaultGame.ini

 [Engine.GameInfo]
DefaultGame=NULLGame.NULLGameInfo
DefaultServerGame=NULLGame.NULLGameInfo
PlayerControllerClassName=NULLGame.NULLPlayerController
GameDifficulty=+1.0
MaxPlayers=32
DefaultGameType=NULLGame.NULLGameInfo
 De este modo, ya estaremos listos para utilizar nuestro "juego" con los assets de UT. Igualmente, si queréis utilizarlos, seguramente tengáis que añadir posteriormente en alguno de los ficheros anteriormente mencionados.

¡Nos vemos en el siguiente paso!



1) Pasitos de bebé UDK Julio 2013

¡Muy buenas!

Lo prometido es deuda, y después de una breve comparativa al más puro estilo "el guerrero más letal" (sobretodo por mi rigor científico) entre UDK y Unity, vuelvo al ataque con los primeros pasos con UDK. Y lo principal es instalar UDK y un IDE para poder trastear con los scripts que queramos crear.
Si queréis saber cómo instalar una versión gratuita de Visual Studio 2010 y con la versión de prueba gratuita de nFringe, podéis consultar en el antiguo blog:

The Udknown. Pasitos de bebé. Enlaces de instalación
The Udknown. Instalación de Visual Studio express 2010 y nFringe

En esta ocasión, voy a proceder a instalar la versión más actual de UDK junto a un magnífico IDE que creo que tiene una de las funcionalidades más interesantes que muchos de los que siguieron el otro blog, seguro habrían aprovechado gratamente: La capacidad de debuggear.

Si, decid adiós al mágico mundo de `log("Cada vez que invoco log, Unreal mata un gatito") para poder saber el valor de las variables. ¡Ojo! Seguro que más de uno le ha cogido el gustillo y en alguna ocasión hace uso de ello. Imagino que algunos, en estos momentos, no comprendáis esta magnífica gracia, pero tened paciencia, pronto sabréis de lo que estoy hablando.

Sin más dilación, os coloco los enlaces de descarga, que, seguramente, con el tiempo, se quedarán obsoletos. Pero creo que todos podemos utilizar Google u otro motor de búsquedas para encontrar sus equivalentes o nuevas versiones. ¡Ahí voy!

Unreal Development Kit Julio 2013 UDK Beta:
UDK descargas

Pues eso, el motor UDK para descargar.

Real Script IDE:
Real Script IDE página inicial

La página oficial de un interesante IDE gratuito basado en Visual Studio 2010.

Como control de versiones yo os recomendaría crear un repositorio en https://bitbucket.org/
Os permite crear los repositorios privados que os de la gana, con su wiki y su issue tracking. Además tiene para poder seleccionar UnrealScript como lenguaje.
Se de buena fe, que a mucha gente le gusta utilizar HG Mercurial como control de versiones. Yo en su defecto, como simple anotación utilizo uno creado por los mismos que bitbucket: Sourcetree

Yo lo utilizo porque Git se utiliza también con Mac. Y por si acaso, mato dos pájaros de un tiro ;) (Por si algún día me da por morder la manzana prohibida... En precio).

Una vez que hayamos descargado todo, podemos seguir algunos pasos como en The Udknown, Welocme to the jungle. Instalación UDK

INSTALACIÓN DE UDK

Comenzamos instalando UDK. En nuestro caso, la versión de Julio de 2013.
    1.  Contrato de licencia que aceptar nos toca. Por supuesto su lectura es recomendada (aunque yo no la lea)
    2. ¡Tenemos dos opciones!
      1. PSGameUT3Title: Instala UDK con paquetes de Unreal para su uso completo y para poder utilizar los assets que nos proporciona gratuitamente. Es interesante para poder trastear después con los modelos, pero nos tocará configurar algo más de sus ficheros de configuración para que podamos disfrutar de nuestro proyecto.
      2. PSGameEmptyTitle: Pues esta opciçon te instala UDK pelao. Creo que viene una triste Mesh (modelo 3D de malla) sin huesos (si no sería SkeletalMesh, para que os vaya sonando).
    3. Si elegís la primera opción, simplemente os pedirá que indiquéis la ubicación para la instalación del motor. 
    4. Con la segunda opción, UDK nos generará los ficheros necesarios para tener un juego "custom" y para ello, nos pedirá un nombre en IOProjectOptions, en la cajetilla IOProjectNameLab. Yo siempre coloco las iniciales que identificarán los ficheros de mi juego posteriormente. En este caso yo utilizaría NULL (Esto generará luego una carpeta NULLGame y en su interior los ficheros de scripts con el prefijo NULL como por ejemplo, NULLGameInfo o NULLPawn).
    5. UDK en este paso ya se pone a instalar los ficheros del motor en la ubicación seleccionada. Finalmente te da opciones para instalar Perforce, otro control de versiones, que la verdad, no se manejar. Si tenéis ganas, valor y tiempo libre, no dudéis en contarme qué tal fue la experiencia (y lo digo sin ironía).
    6. En este punto, ya tendremos UDK instalado en nuestro ordenador. Como siguiente paso, explicaré brevemente la jerarquía de carpetas del mismo para que empecemos a hacernos una idea de dónde tendremos que toquetear cosas en el futuro.

Analicemos ahora la jerarquía de carpetas en el directorio de instalación donde se encuentra UDK.
Binaries: Aquí tendremos los ejecutables para nuestro proyecto. En la carpeta WIN32 se encuentra UDK.exe, el ejecutable del motor. Aquí también hay un fichero llamado UDKLift, que al ejecutarlo, nos llama a la versión de UDK que considere más conveniente. Si tenemos que hacer un acceso directo, utilizad "UDKLift.exe editor -log" con la ruta donde se encuentre ese fichero. De este modo, activaremos también el log (si, tiene relación con ese comando `log del que he hablado por encima de guasa antes) para cosillas que queramos informar y poder enterarnos desde el editor.

Development: Como su nombre indica, se encuentran los ficheros relacionados con el desarrollo del proyecto. Básicamente scripts de todo tipo, incluso cosillas de scaleform para los más atrevidos. En su interior se encuentra la carpeta Src, y dentro de ella, las carpetas con todos los scripts del motor. En Core los más básicos, en Engine los del propio motor, que tendremos que consultar muy a menudo, al basarse UnrealScript principalmente en la herencia. UDKBase, es una vuelta de tuerca más, un escalón más de clases que heredan de las más básicas con algo más de funcionalidad. Y también tendremos que tener una carpeta con el nombre de nuestro proyecto. Si no la tenemos es un buen momento para hacerlo.
Como nota, dentro de dicha carpeta (en nuestro caso NULLGame), debéis tener otra llamada Classes dentro, que es donde colocaremos los scripts .uc de nuestro juego (Y como dije antes, con prefijo seleccionado con relación a nuestro proyecto, por ejemplo NULLGameInfo, NULLPawn...).

Engine: Ficheros del motor. No tocar si no sabes lo que haces (es que si no lo único que puedes hacer es liarla muy parda y tener que volver al punto 1 de instalación xD).

UDKGame: Aquí colocaremos los paquetes de nuestro proyecto, así como modificaremos los ficheros de configuración para el mismo. Se divide a su vez, en varias subcarpetas:

  • Carpeta Config: 
    • Aquí volveremos más adelante para configurar en el motor, dónde encontrar nuestros scripts para el juego y sobretodo con qué clase que herede de GameInfo, empezará. Esta carpeta es, también muy importante, a la hora de configurar asignación de teclas concretas a través del fichero DefaultInput.ini que luego utilizaremos en el juego. Se "bindean" (Asocian) teclas a functions exec que colocaremos más adelante en una clase que herede de PlayerController o bien de PlayerInput. No os preocupéis ahora de ello, sólo para que os suene.
    • DefaultEngine.ini es otro fichero muy importante, ya que en él, colocaremos qué paquetes de ficheros cargaremos al comienzo del motor. Lo mismo ocurre con DefaultGame.ini para indicar qué tipo de juego ejecutará por defecto y qué mapas. 
    • NOTA IMPORTANTE: Incluso aquí, UDK vuelve a utilizar la herencia. La primera línea de los ficheros de configuración indica de que otro fichero .ini heredan. En alguna ocasión, es posible que tengáis que cambiar el orden de paquetes de algún fichero de configuración como UDKDefaultEngine.ini si queréis utilizar alguna clase de tipo UDKBase (ya que en el apartado StartupPackages se encuentra añadido posteriormente a lo que sería el nuestro si tomamos la opción de instalación "pelada" anteriormente. [Punto 2.2]).
  • Carpeta Content: 
    • En esta carpeta, guardaremos los mapas y paquetes de nuestro proyecto (con sus magníficas texturas, modelos, sonidos y demás dentro). Es importante tener las cosas ordenadas, de modo que una carpeta NULLContent dentro con la jerarquía que deseéis después con la que os aclaréis y tengáis todo ordenado, es más que necesaria. 

Una vez hemos estudiado un poco la instalación de UDK, podemos proceder a instalar Real Script IDE.

Lo podéis instalar donde queráis. Y una vez indicada la ruta para su instalación, os pedirá que indiquéis dónde se encuentra la carpeta WIN32 de la instalación de UDK que queréis utilizar. Simplemente se la colocáis (será del tipo C:\UDK\UDK-2013-07\Binaries\Win32\ ). Si tenéis varias versiones de UDK tened cuidadín. Una de las desventajas de este IDE es que sólo se instalar para una versión de UDK por lo que he podido comprobar. Seguramente por dentro, al ser Visual Studio podéis configurar más cosas. Como estamos realizando un tutorial para no complicarnos la vida, lo ideal es que sigáis estos pasos y lo utilicéis con una instalación de UDK.

Esperáis a que termine de instalar ... .. . .

Y seguramente ya tengáis un enlace en vuestro escritorio windowsero para poder disfrutar de este IDE de MR. O Duzhar.

Lo chulo si lo iniciáis, es que tiene separados por un lado los ficheros ini de configuración y por otro los uc de la carpeta Development/Src para que podamos modificarlos a nuestro antojo y poder hacer las pruebas que queramos con la versión del motor instalada concreta.

Ahora dejaremos descansar un poco la máquina para dejar en el tutorial siguiente, el cómo configurar vuestros ficheros ini principales para poder hacer funcionar y que se ejecute vuestro proyecto en caso de que hayáis instalado la versión de UDK que tiene Unreal Tournament de base para tener todos sus assets para trastear.

¡Nos vemos!



sábado, 5 de octubre de 2013

0) Esqueleto base de una clase. Actor y sus ActorComponents

¡Muy buenas!

Antes de comenzar nada, me he dado cuenta que tenemos que hablar de la clase Actor y del esqueleto que tiene una clase en unrealscript.

Para comenzar, la clase más básica de la que debemos heredar teniendo funcionalidad de objeto que se encuentre en escena, es la clase Actor. También existe la clase Object, pero esta es más abstracta y no se utiliza para objetos que colocaremos en la escena, si no para clases auxiliares y otras funciones.

Lo primero y principal, es saber que una clase de UDK se declara del siguiente modo:

class <nombredelaclase> extends <nombredelaclasepadre>;

Como veis, debéis cambiar lo que hay entre <> por el nombre de vuestra clase y la clase que debéis heredar. Si hacéis un objeto básico, como estamos hablando quedaría del modo:

class MyObjeto extends Actor;

Esto es lo más sencillo que podemos declarar una clase. Existen "flags" que podemos declarar, o bien crear interfaces en UDK (con el flag abstracto o usar within para crear una especie de clases "amigas"). Es recomendable buscar un libro (por ejemplo un Cookbook) que os cuente más sobre el propio lenguaje Unrealscript.

Los flags se colocan después de extends <ClasePadre> y antes del ;

Algunos muy interesantes son:

ClassGroup(<CategoríaEnElContentBrowserActorClasses>)

- Sirve para clasificar nuestras clases bajo un grupo (una categoría o etiqueta) en la pestaña Actor Classes del Content Browser (el botoncito en el editor que tiene una U de unreal).

placeable

- Sirve para hacer que un objeto se pueda colocar en la escena. Se puede seleccionar desde la pestaña Actor Classes del Content Browser y colocar directamente en un mapa arrastrando o con botón derecho del ratón en una posición de la escena, addActor del tipo que tengáis seleccionado. Un Pawn, una caja de vuestro juego, un enemigo, son ejemplos más sencillos de clases que son "placeables".

Config(<NombreDeUnFicheroIni>)

- Podemos inicializar nuestras variables desde un fichero .ini alojado en UDKGame/Config en nuestra instalación de UDK. Para ello, basta con crear un fichero ini allí con el nombre DefaultNombreDeUnFicheroIni.ini que hayamos colocado en el flag y dentro del fichero de texto, colocar
[<NombreDeLaCarpetaDondeEstánNuestrosScripts>.<NombreDeLaClaseQueQueremosTenerUnaVariableEnEsteFichero>]

Por ejemplo, si mi clase es MyPawn y mis scripts de juego están en la carpeta Development/Src/MyGame, tendría que escribir en el fichero ini [MyGame.MyPawn]. Debajo de esa linea, ya podré inicializar una variable de la clase siguiendo el mismo formato que tendremos en DefaultProperties como veremos más adelante.

Una vez llegados a este punto vemos el esqueleto base de una clase:

class MyClass extends Actor placeable;
 
var float fMyFloat;

//Declaración de una función. Tiene un parametro normal, uno por referencia, y uno opcional
function MyFunction(float myParam, out float myParam2, optional float myParam3=3.0f)
{
local float myFloatLocal;

//Las variables dentro de funciones se declaran siempre debajo de la declaración de la función y se utiliza //local. Si no os dará fallo.
}

//Tened cuidado de colocar la llave (símbolo {) debajo de defaultProperties o tendréis un fallo de //compilación raruno.
defaultproperties
{
//Aquí se declaran las variables que tenemos arriba, debajo de la declaración de la clase
//Tened cuidado y no colocad ; al final ni procurad dejar espacios.
fMyFloat=3.0f
}

Como podéis ver, la manera básica de crear una clase es esta. Pero no termina todo aquí, nos falta una parte fundamental y básica del comportamiento de las entidades en UDK: los ActorComponents.

ActorComponents

Un actor en UDK tiene funcionalidad básica dentro de un mapa cargado. Para que nos hagamos una idea, está preparado para funcionar en UDK, pero es básicamente un punto en el espacio con una rotación (tipo Rotator y se llama Rotation) y una posición en el mundo (Vector y se llama la variable Location).

Actor funciona como un "Mr Potato". Le añadimos a esa posición y rotación diferentes piezas. Las más básicas son los ActorComponents (CylinderComponent) que actuarán como colisión, los que le darán una forma (SkeletalMeshComponent, StaticMeshComponent, que son mallas con huesos y sin ellos respectivamente) y algún componente para que pueda reaccionar con las luces dinámicas (DynamicLightComponent).

La documentación sobre ellos es bastante clara en la UDN, de modo que no me enredaré, en el tutorial y os dejaré que echéis un vistazo y comprobéis cómo se inicializan los mismo. IMPORTANTE: Es necesario hacer ese esfuerzo y comprender bien los ActorComponents antes de avanzar en los tutoriales u os volveréis locos.



miércoles, 2 de octubre de 2013

Apéndice 1) Sourcetree, control de versiones

¡Muy buenas!

Con esta entrada del blog, mi intención es que tengáis configurado un control de versiones y un repositorio para vuestro código. Igualmente, es conveniente que aquellos seres que viven entre nosotros, llamados artistas, posean este conocimiento para poder tener el código más actualizado en nuestros proyectos y favorecer el hermoso fluir del trabajo.

He basado mi tutorial de otro en inglis' que os explica las bondades de porqué utilizar Git y hacer uso de BitBucket y el entorno SourceTree (Adam Single Unity GIT Tutorial). Básicamente, con lo que yo me quedé es lo siguiente:

  • Git se puede utilizar en Mac y muchos artistas trabajan con Mac.
  • BitBucket es gratuito y te da muchas opciones y posibilidades.
  • Sourcetree es de los creadores de Bitbucket así que la compatibilidad será buena. 

Os dejo inicialmente los enlaces a los diferentes sitios:

Bitbucket                    Repositorio para colocar vuestro código (e incluso assets)
SourceTree                 Entorno visual para trabajar con Git o Mercurial (Para Mac y Windows).

Para empezar, comenzaré con la creación de un repositorio en UDK. Al final, comento que carpetas se deben utilizar en un proyecto de Unity y cómo prepararlo antes de crear el repositorio. Los pasos son idénticos a los de UDK exceptuando las indicaciones mostradas allí.

NOTA: Aquellos que vayáis a utilizar exclusivamente para descarga, podéis saltaros esta parte  y pasar directamente a Repositorio Git para UDK sólo lectura (Clonar repositorio).
.

Repositorio Git para UDK

En primer lugar, crearemos una cuenta en Bitbucket.
Una vez que la tengamos creada podemos acceder a nuestra cuenta, y en portada tendremos una "Overview" de todos los repositorios que dispongamos. Os coloco un ejemplo visual:


Arriba tenéis un botón "mágico" que cuya etiqueta es Create. Si lo pulsáis os aparecerá para crear un repositorio. Veamos sus campos y cómo los he rellenado para mi proyecto:



Como veis, tenéis varias opciones. Podéis hacer el repositorio que sea público o privado. Utilizar Mercurial o Git y si queréis utilizar un sistema de seguimiento de problemas y wiki para ese repositorio concreto. El lenguaje de programación os deja seleccionar tanto UnrealScript como UnityScript como C#,etc...

Pulsamos Create Repository y procedemos a tener nuestro flamante repositorio.

En la pantalla que nos aparece a continuación debemos indicarle que queremos crear el repositorio desde el principio ("I'm starting from Scratch").

Allí nos da instrucciones de qué comandos debemos escribir para poder iniciar nuestro repositorio y dónde.
En nuestro caso, debemos iniciar un cmd (consola de comandos en windows) y navegar hasta la carpeta de nuestro proyecto de UDK. En mi caso:

C:\UDK\UDK-2013-07

Una vez allí,

git init git remote add origin
https://JDKnight@bitbucket.org/JDKnight/nullgame.git


Eso es para mi repositorio. Para el vuestro será siguiendo esta plantilla: 

git remote add origin
ssh://<BBUserName>@bitbucket.org/<BitBucketUserName>/<RepoName>.git


¡Ya tenemos preparado nuestro proyecto de UDK para ser utilizado por SourceTree y subir nuestro
código!

Instalamos SourceTree.

Una vez instalado y habiéndolo ejecutado, tendremos una pantalla de este estilo. Podemos añadir un
repositorio desde diferentes sitios marcados en la siguiente imagen:





 
 
Una vez lo pulsemos nos aparecerá la siguiente ventana:
 
 
Buscamos la misma carpeta en la que hemos realizado antes git init pulsando en el botón "..." a la derecha. Le ponemos nombre al repositorio en Name: y pulsamos Add.

Ahora aparecerá en los Bookmarks nuestro repositorio. Debemos seleccionar que ficheros deseamos en el mismo. Para ello, en la ventana Working Copy Changes, debemos seleccionar ficheros y subirlos arriba con las flechitas (arriba son los ficheros que se incluirán en nuestro repositorio).

Podemos ignorar ficheros haciendo botón derecho en ellos (ignore) y una vez hecho, podemos incluso ignorar carpetas enteras (Ignore everything beneath...). ¡Tened cuidado con ello!

Para nuestro proyecto de UDK debéis seleccionar las carpetas Development/Src/<VuestroGame>, UDKGame/Config/ Al menos de momento.
 
Una vez que sólo queden esas carpetas podéis pulsar el botón con dos flechitas hacia arriba.
Si os habéis equivocado ignorando ficheros, podéis consultar en esa carpeta el fichero .gitignore y modificarlo quitando aquellas rutas o ficheros que no queréis ignorar.
 
Una vez hecho esto, podéis pulsar el botón Commit, colocar los cambios realizados y proceder a pulsar Push. Elegid la rama que queréis pushear y palante.
 
Por último, es necesario que compartas tu proyecto con gente. En la página de BitBucket del administrador, puedes pulsar en Share (con un iconito de carta):
 
Si lo pulsas te aparecerá la siguiente ventana:

 Si pulsas en Manage this repository podrás acceder a mayor control de las personas que pueden leer, escribir o ser administradores de este repositorio. Es bastante intuitivo, así que no me enredaré mucho más aquí.
 

Repositorio Git para UDK sólo lectura (Clonar repositorio)


Si váis simplemente a bajar el código en vuestro equipo, el procedimiento es similar al anterior.  En primer lugar necesitáis saber dónde se encuentra vuestro repositorio en la nube.
Vuestros amigos programadores os podrán obsequiar con dicha dirección consultando desde la página de BitBucket del administrador del proyecto. Aquí:

Existe como podéis observar un botón que pone Clone in SourceTree que os la clonará directamente sin tener que pulsar en SourceTree en el siguiente botón:

Elijáis la opción que elijáis llegaréis a esta ventana:


En Destination Path tenéis que colocar la carpeta de UDK donde tenéis el proyecto. Del mismo modo, podéis colocar un nombre para vuestros repositorios en Name para identificarlos con más facilidad posteriormente.

Una vez realizado esto, podéis pulsar el botón Fetch para comprobar si hay nuevas versiones de vuestros proyectos teniéndolos seleccionados a la izquierda. Os aparecerán en el medio, las diferentes ramas y demás información. Seleccionando la rama más antigua (la que esté más arriba, en el camino de puntitos), podéis pulsar Pull para empezar a descargar los cambios que existan en vuestro proyecto. Si no los hay, al pulsar Fetch os habrá indicado que estáis actualizados.
 

Carpetas que debemos incluir en un proyecto de Unity y su Setup


En Unity debemos realizar un pequeño paso antes para dejar preparado nuestro proyecto.
En Edit->Project Settings->Editor en
  • Version Control Mode debemos colocar la opción Meta files. 
  • Asset Serialization Mixed.
Las carpetas que tenemos que incluir en estos repositorios son :
  • Assets  
  • ProjectSetting 
El resto de carpetas en el interior de tu proyecto de Unity puedes ignorarlas.

¡Ya estás listo para usar las bondades de un control de versiones como la copa de un pino!
¡ENHORABUENA!