martes, 21 de agosto de 2012

PathFinding

Después de un tiempo sin publicar nada... voy a escribir un poco acerca de un tema que he estado investigando.
Se trata de la búsqueda de caminos o en inglés "pathfinding".
Es un problema común en juegos de estrategia, así como juegos de laberintos tipo comecocos, etc.
En muchos de estos juegos, la inteligencia artificial de los entes móviles, puede que esté intentando buscar el camino óptimo para llegar de un sitio a otro. Incluso nuestro personaje, si le mandamos ir a un sitio, es probable que tenga que tener en cuenta los obstáculos que hay en el terreno y trace el camino más corto.
Para esto se usan los algoritmos de PathFinding.
Hay varios algoritmos populares, por ejemplo el A*, el WaveFront o BrushFire que es en el que yo me centraré con el código.
Antes deponerme con estos algoritmos que me resultaban algo difíciles, intenté empezar con un algoritmo publicado por un usuario en el foro de unity spain, el cual no precisaba de muchos conocimientos.
En realidad era un algoritmo de intuición ya que no buscaba el camino óptimo, si no que más bien hácía que el personaje fuera moviéndose por donde más posibilidades instantáneas había para llegar al objetivo.
Después de estar unas semanas mejorando este código, y consiguiendo algún resultado bastante convincente, llegué a la conclusión de que había algún problema que era imposible de esquivar con ese método.

Entonces miré el A*, y vi que era bastante lioso y usaba recursividad...

Pasé al wavefront que parecía más fácil y en efecto me qeudé con él.
También usa una función recursiva a la hora de buscar el camino óptimo pero me resultó bastante más fácil de implementar y de hecho la función la hice desde cero fijándome solo en el pseudocódigo del algoritmo.
Yo esta vez lo hice en C# ya que en ese momento me dió por aprender un poco de C#.
A su vez, un compañero del foro, lo implementó en Js.

Bueno os escribo la función ActualizarMatriz que es la básica. No está comentado así que hace falta un poco de imaginación para entender lo que se hace.

 void ActualizarMatriz(Vector2 NuevoTarget, intNuevoPeso){
  int i;
  int u;
  int v;
  for (i = 0; i < 8 ; i++){
   u = (int) NuevoTarget.x + X[i];
   v = (int) NuevoTarget.y + Y[i];
   if  (u >= 0 && u <10  && v >= 0 && v <10  ){
    if (Matriz[u,v] != -1 && NuevoPeso < Matriz[u,v]){
        if(u==PosicionPlayerActual.x&&v==PosicionPlayerActual.y)
        break;
    Matriz[u,v] = NuevoPeso;
    Vector2 Adyacente = new Vector2(u,v);
    ActualizarMatriz(Adyacente, NuevoPeso + 1);
    }
   }
  }
 }
 

Si tenéis dudas, contactad conmigo por email o dejando aquí un comentario y os ayudaré.

Podéis pedirme el código completo del fichero por si queréis probarlo en vuestro ordenador, o incluso os puedo dejar mi proyecto de unity con todo preparado.

Un saludo.

lunes, 22 de agosto de 2011

Script Romper Objetos

var fragilidad : float; //cuanto más elevado sea este valor, más fuerte tendrá que ser el choque para que se rompa.
var piedri: GameObject; //Usar el inspector para asignarle aquí el prefab del cacho de piedra que saldrá despues de romperse.

function OnCollisionEnter (collisionInfo : Collision) { // se ejecutará cada vez que colisione con algo
if (collisionInfo.relativeVelocity.magnitude > fragilidad){
//si la fuerza de colisión es mayor que la fragilidad
Instantiate (piedri, transform.position + Vector3(0,1,0), Quaternion.identity); // creamos 2 cachos
Instantiate (piedri, transform.position + Vector3(1,1,1), Quaternion.identity);
Destroy(gameObject); // Y destruimos la antigua
}
}

function Start()//Al inicio a piedri se le asigna directamente el prefab llamado "Piedrita" si no queremos hacerlo manualmente
{
piedri = GameObject.Find("Piedrita");
}


Este script hay que asignarlo a un objeto que tenga un Rigidbody y un Collider. Y aparte tendremos que tener creado en el proyecto un prefab que contenga un objeto igual pero más pequeño y así dará la impresión de que se rompe en dos al chocar.

martes, 16 de agosto de 2011

Mostrar Nombre de Objetos Cercanos

var texto : TextMesh; //creamos un 3dText y lo ponemos como hijo del player

function Update () {

if (Input.GetKey("e")) //si mantenemos pulsado "e"...
{
var hit : RaycastHit;
if (Physics.Raycast (transform.position, transform.forward, hit, 4)) { //lanzo un rayo hacia adelante
if (hit.collider.tag == "Leible") // si choca el rayo con algo marcado como leible (creamos el tag Leible)
{
texto.text = hit.collider.name; // aplicamos el nombre del objeto al texto 3d
texto.gameObject.active = true; // y activamos el texto 3d
}

}
else
texto.gameObject.active = false; // si dejamos de chocar mirar al objeto o nos alejamos...
o
}
else
texto.gameObject.active = false; // si dejamos de pulsar la tecla ... no se muestra el texto
}


function Start() { // al empezar el juego el texto 3d se oculta
texto.gameObject.active = false;
}

viernes, 12 de agosto de 2011

Personaje Low Poly gratis


Es un robot un poco feo pero al menos tiene 4 animaciones y sirve para ir probando cosas en unity.

Es un .fbx igual que la iglesia por tanto metedlo a la carpeta Assets y listo.

http://www.megaupload.com/?d=XGRE3H22





jueves, 11 de agosto de 2011

Leer Toque de Pantalla Táctil y Zoom de Pellizco con 2 Dedos

function LeerToque()
{
if (Input.TouchCount == 1)
var touch : Touch = Input.GetTouch(0);
else if (Input.TouchCount == 2)
{
var touch1 : Touch = Input.GetTouch(0);
var touch2 : Touch = Input.GetTouch(1);
var vectorDifActual : Vector2 = touch1.position-touch2.position;
var vectorDifAntiguo : Vector2 = (touch1.position - touch1.positionDelta)-(touch2.position - touch2.positionDelta);
var touchDelta : float = vecctorDifActual.magnitude - vectorDifAntiguo.magnitude;
}
}

Modelo de Iglesia en FBX

Aquí os dejo un archivo .fbx de una iglesia que modelé inspirándome en la de el pueblo madrileño Torres de la Alameda.

Las ventanas y las texturas las puse desde Unity por lo que no van en el modelo.



http://depositfiles.com/files/8pmra6c9a