lunes, 14 de abril de 2014

Tutorial Galería 3D en Unity

Hoy vamos a aprender a hacer una sencilla galería de personajes para nuestro videojuego. Lo haremos mediante Unity3D.



Para ello colocaremos tres modelos 3D en diversas posiciones de un plano mediante el Editor.
Una vez en sus posiciones hay que crear un script para el movimiento de la cámara. Dentro del script podemos distinguir 3 elementos:

  • Función Start
  • Función Update
  • Función OnGUI
 Antes de revisar el script vamos a echar un vistazo a las variables:

// Object to show in gallery
var objects : GameObject[];
// Current object showed by camera
var current : int = 0;
// is camera position chaging to next object?
var onChange : boolean = true;
// Smooth in camera movement
var cameraSmoothing : int = 5;
// Textures for GUI
var arrowNextTexture : Texture;
// Textures for GUI
var arrowPrevTexture : Texture;
// Delta in camera rotation
var deltaMine : float = 1;
// Is camera rotating?
var rotating : boolean = false;



objects tendrá un array que se rellenerá desde el Editor.
current tendrá el índice del personaje mostrado por la cámara.
onChange servirá para detectar si la cámara puede empezar a rotar sobre el personaje.
cameraSmoothing será la suavidad con la que se mueva la cámara.
arrowNextTexture y arrowPrevTexture serán las texturas del GUI.
deltaMine será el factor delta con el que rote la cámara.
rotating un flag para saber si la cámara está rotando al rededor del personaje.

La función Start inicializará las variables antes descritas y mostrará en cámara el primer personaje del array objects.

En la función Update se hace lo siguiente:

Primero se obtiene la diferencia de movimiento de la cámara en el eje X. Con esto sabremos que la cámara se esta moviendo hacia otro personaje. Se setean los flags para decidir si la cámara tiene que empezar a rotar o no.

function Update () {
 
 var diff = Mathf.Abs(target.position.x - transform.position.x); 

 // Offset movement to decide if camera starts rotating
 
 if (!rotating && diff > 0.001) {
 
  onChange = true;
  rotating = false;
  
 } else {
 
  onChange = false;
  rotating = true;
 
 }


Después si no está cambiando de objetivo la cámara se empieza a rotar sobre el personaje actual.
Si está cambiando de objetivo entonces se fija en el tag del personaje. Si el tag es "Small" entonces se acerca más, si el tag es "Big" se aleja un poco del personaje y si no tiene tag queda la cámara en una posición intermedia. Se calcula la posición de la cámara y la rotación inicial mirando hacia el personaje. Por último se guarda la posición X actual de la cámara.
 

 // Smooth translate to target

 if (!onChange) {
  
  transform.RotateAround(target.position, Vector3.up, deltaMine);
  
  
 } else {

  // If the object is tagged with Small, camera will go close to the object
  // If object has Big tag, the camera will show object from distance
  // Else normal camera distance

  if (target.tag == "Small")
   transform.position = Vector3.Lerp(transform.position, target.position + currentCameraOffsetPlayers, Time.deltaTime * cameraSmoothing);
  else if (target.tag == "Big")
   transform.position = Vector3.Lerp(transform.position, target.position + currentCameraOffsetHuge, Time.deltaTime * cameraSmoothing);
  else
   transform.position = Vector3.Lerp(transform.position, target.position + currentCameraOffset, Time.deltaTime * cameraSmoothing);
 
 
  // Smooth transition to new rotation

      var relativePos = (target.position + currentFocusOffset) - transform.position;

     targetRotation = Quaternion.LookRotation(relativePos);

     transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, Time.deltaTime * cameraSmoothing); 

  // Track old x position to decide if camera starts rotating

  oldXPosition = transform.position.x;
  
 }
 
}

En la función OnGUI se muetran las dos flechas que permitirán pasar de un personaje a otro:
 
function OnGUI () {
 
  var width : int = 50;
  var height : int = 50;
  var rectNext : Rect = Rect((Screen.width * 0.85) - 50, Screen.height/2, width, height);
  
  // Next!
   if (GUI.Button(rectNext,arrowNextTexture)) {
    
    // Mod, from last to first and viceversa
    if (current == objects.length-1)
     current = -1;
   
   target = objects[++current].transform;
   rotating = false;
   onChange = true;
   
   }  
  
  
  var rectPrev : Rect = Rect((Screen.width * 0.15), Screen.height/2, width, height);
  
   // Previous!
   if (GUI.Button(rectPrev,arrowPrevTexture)) {
   
    // Mod, from last to first and viceversa
    if (current == 0)
     current = objects.length;
     
   target = objects[--current].transform;
   rotating = false;
   onChange = true;
   
   }       
 
} 


Aquí podeís encontrar el proyecto Unity completo:





jueves, 2 de mayo de 2013

Ayuda a Riot Area, un juego Online multijugador sobre manifestaciones a financiarse

RIOT AREA, será un juego Online de estrategia en el que se podrá luchar en manifestaciones virtuales con tácticas basadas en la realidad. 
Este juego se puede encuadrar en el género de los juegos de Estrategia en Tiempo Real. 
Las fuerzas policiales RPO (Riot Police), brazo ejecutivo del poder vigente, responsables de mantener la seguridad y la estabilidad social chocan contra los manifestantes SOW (Social Warriors) luchando en contra de la merma de los derechos y libertades sociales. 
El conflicto entre los dos bandos es directo. 

Ayuda a este proyecto:



martes, 23 de abril de 2013

Riot Area! un juego de estrategia sobre manifestaciones

La situación de la sociedad española actual es de conflicto: el aumento de los deshaucios, disminución del empleo, privatización de la sanidad...se refleja en continuas manifestaciones en la calle. En este escenario te proponemos tomar parte en la batalla.


Riot Area, juego de estrategia sobre manifestaciones

"RIOT AREA", es un juego online en el que podrás jugar contra otros jugadores bien en solitario o ayudado por amigos. Este juego se puede encuadrar en el género de los juegos de Estrategia en Tiempo Real mezclado con el género Tower Defense (defender la posición).







miércoles, 26 de diciembre de 2012

Unity 3D + Subversion

Aunque Unity 3D tiene un servidor de versiones integrado puede resultar útil en ocasiones integrar un proyecto Unity con un servidor de versiones externo como Subversion.

Para ello hay que seguir los siguientes pasos:

  1. Crear un proyecto de Unity. Por ejemplo MyUnityProject.
  2. Habilitar los metaficheros dentro de Unity: Edit->Project Settings->Editor
  3. Cierra Unity (así verificas que se guardan todos los ficheros).
  4. Borrar el directorio Library.
  5. Comitear el proyecto entero. Desde línea de comandos:
    svn import -m"Initial project import" InitialUnityProject svn://my.svn.server.com/MyUnityProject
  6. Check out del proyecto:
    svn co svn://my.svn.server.com/MyUnityProject
    Chequea que los directorios Assets y ProjectSettings están versionados.
  7. Abre el proyecto subido al repositorio. Una vez abierto el proyecto se recrearán todos los metadatos en el directorio Library borrado en el paso 4.
  8. Opcional: Configura un filtro para ignorar el directorio Library y no versionarlo:
    svn propedit svn:ignore MyUnityProject/
    Subversion abrirá un fichero de texto. Añade el directorio Library.
  9. Finalmente comitea los cambios. Tu proyecto está subido y sincronizado!
    svn ci -m"Finishing project import" MyUnityProject


Fuente: http://docs.unity3d.com/Documentation/Manual/ExternalVersionControlSystemSupport.html

lunes, 12 de noviembre de 2012

Cambiar icono en una ventana mediante el API Windows

A veces es interesante personalizar tu aplicación y más si es un videojuego. Una manera de lograr esto es cambiar el icono de la ventana de tu aplicación.

Bien, pues algo "sencillito" como cambiar el icono de una ventana en Windows utilizando su API se puede convertir en algo infernal si una guía de como hacerlo.

Después de googlear bastante he llegado a la conclusión de que la mejor forma es mandar un mensaje a la ventana pidiendole un cambio de icono (WM_SETICON):

mInstance = GetModuleHandle(NULL);

HANDLE icon_small = LoadImage(mInstance, "C:\\crosshair.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);

HANDLE icon_big = LoadImage(mInstance, "C:\\crosshair32.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);

Los dos tamaños son para el icono que aparece arriba a la izquierda de la ventana y el grande es para la barra de tareas.

Una vez hecho esto y después de crear la ventana:

    // Create The Window
    mWnd = CreateWindowEx( lExStyle,
       lProperties.macApplicationName.c_str(),  // Class Name            
       lProperties.macApplicationName.c_str(),  // Window Title
       lStyle |                                                      // Defined Window Style
       WS_CLIPSIBLINGS |                            // Required Window Style
       WS_CLIPCHILDREN,                           // Required Window Style
       0, 0,                                                         // Window Position
       lWindowRect.right-lWindowRect.left,       // Calculate Window Width
       lWindowRect.bottom-lWindowRect.top,   // Calculate Window Height
       NULL,                                                     // No Parent Window
       NULL,                                                     // No Menu
       mInstance,                                                // Instance
       NULL);


Tenemos que enviar el mensaje de cambio de icono:

  SendMessage(mWnd, (UINT)WM_SETICON, ICON_SMALL, (LPARAM)icon_small);
  SendMessage(mWnd, (UINT)WM_SETICON, ICON_BIG, (LPARAM)icon_big);


Con esto ya tendríamos personalizado el icono ;-)


 

domingo, 2 de septiembre de 2012

Resolución de errores, tip #2

Usando VC++ 2008 y DirectX.

Error:

  • error LNK1181: no se puede abrir el archivo de entrada 'dxguid.lib'
Tu proyecto está utilizando DirectX SDK y o no lo tienes instalado en tu equipo o tienes que incluir en los directorios de VC++.

Solución:
Instala DirectX SDK por ejemplo DirectX DSK Febrero 2010 (que todavía incluia Direct Input).

Ve a:

Herramientas->Opciones->Proyectos y soluciones->Directorios de VC++



y añade el directorio correspondiente para las librerias de DirectX, en mi caso $(DXSDK_DIR)/Lib/x86

sábado, 17 de septiembre de 2011

Resolución de errores, tip #1

Usando VC++ 2008 y DirectX.

Error:

  • error C2440: '=' : no se puede realizar la conversión de 'const char *' a 'LPCWSTR'
  • error C2664: no se puede convertir el parámetro 2 de 'const char [X]' a 'LPCWSTR' 
Estos errores de conversión se producen debido a que DirectX por defecto usa el juego de caracteres UNICODE mientras que el resto de tu proyecto no.

Solución:

Ve a:

Propiedades de proyecto->Propiedades de configuracion->General->Juego de caracteres

y cambia "Utilizar juego de caracteres Unicode" por "Utilizar juego de caracteres multibyte".