Noticias

¡RECUERDA QUE SI ERES UN NUEVO USUARIO, DEBES PRESENTARTE PARA PODER PUBLICAR MENSAJES! | TENEMOS CANAL OFICIAL DE TELEGRAM: t.me/unity3dspain

Pathfinder muy sencillo en Javascript

Iniciado por Mantis, Junio 15, 2012, 04:43:08 PM

Tema anterior - Siguiente tema
Entendido.

Muy buena explicación, con matrices y todo. Gracias de nuevo.

Pues exactamente eso es lo que he hecho y por eso he llegado a esos resultados, jeje. Ponérselo dificil al algoritmo, vaya, ya que le había puesto obstáculos en los bordes y también obstáculos en U...


Lo de los numeritos ya me di cuenta que sería por lo de tener un mapa más grande.

Intentaré mejorar el algoritmo en cuanto pueda ya que quiero seguir con mi idea de RTS. Me está gustando esto.

Un saludo!

Temo decir que el algoritmo que usas en totalmente erroneo, no he mirado el script - soy muy perrooo  , lo digo porque has puesto esto:

( 3, 3, 3, 3, 3, 3, 4, 5, 6, 7);
( 2, 2, 2, 2, 2, 3, 4, 5, 6, 7);
( 2, 1, 1, 1, 2, 3, 4, 5, 6, 7);
( 2, 1, T, 1, 2, 3, 4, 5, 6, 7);
(0,-1,-1,-1,-1,-1,-1,-1,-1,-1);
( 2, 2, 2, P, 2, 3, 4, 5, 6, 7);
( 3, 3, 3,-1,-1,-1,-1,-1,-1,-1);
( 4, 4, 4, 4, 4, 4, 4, 5, 6, 7);
( 5, 5, 5, 5, 5, 5, 5, 5, 6, 7);
( 6, 6, 6, 6, 6, 6, 6, 6, 6, 7);



Cuando el algoritmo correcto ha de dar como resultado:

( 3, 3, 3, 3, 3, 3, 4, 5, 0, 0);
( 2, 2, 2, 2, 2, 3, 4, 5, 0, 0);
( 2, 1, 1, 1, 2, 3, 4, 5, 0, 0);
( 2, 1, T, 1, 2, 3, 4, 5, 0, 0);
( 2,-1,-1,-1,-1,-1,-1,-1,-1,-1);
( 3, 3, 4, P, 0, 0, 0, 0, 0, 0);
( 4, 4, 4,-1,-1,-1,-1,-1,-1,-1);
( 5, 5, 5, 5, 0, 0, 0, 0, 0, 0);
( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);



Donde '0' son los cuadros donde el algoritmo no ha tenido que revisar, pues en el paso 5 se da de narices con el P, de echo he puesto de más, pues no revisaria tantos cuadros. La diferéncia es simple, no mira los adyacentes en -1 pues son obstáculos no transitables; como ves ni siquiera necesita mirar todas las casillas pues se para en cuanto encuentra el objetivo, de no encontrarlo significa que no hay camino posible y jamás se equivoca; de echo el método correcto seria:


(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1);
(-1, 3, 3, 3, 3, 3, 3, 4, 0, 0, 0,-1);
(-1, 2, 2, 2, 2, 2, 3, 4, 0, 0, 0,-1);
(-1, 2, 1, 1, 1, 2, 3, 4, 0, 0, 0,-1);
(-1, 2, 1, T, 1, 2, 3, 4, 0, 0, 0,-1);
(-1, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1);
(-1, 3, 3, 4, P, 0, 0, 0, 0, 0, 0,-1);
(-1, 4, 4, 4,-1,-1,-1,-1,-1,-1,-1,-1);
(-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1);
(-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1);
(-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1);
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1);


Pues con este método -poner intransitable alrededor- no es necesario comprobar si estás en el los límites de la zona y es mucho más rápido que poner if() para comprobar si está o no dentro de la zona cada vez que mires las 8 casillas adyacentes.

Recuerdo que un if es lentísimo para la CPU pues no existe un circuito que haga if, en realidad son comparaciones y compara bit a bit.

Temo decir que el algoritmo que usas en totalmente erroneo, no he mirado el script - soy muy perrooo  ,
[/quote]

Temo decirte Hosuko que estas totalmenet equivocado.  Esta claro que no has mirado siquiera el algoritmo..

El algoritmo del que hablas es otro distinto de este. Este NO ES el que tu esbozaste en otro post.

Este tiene sus limitaciones que ya se han explicado, pero pienso que se pueden corregir.

El que tu has puesto parece muy interesante pero támbien mucho más complejo a la hora de construir la matriz.

saludos

FNK Games  Games Developer  -  Juegos realizados en Unity para iOS y Android



Ya he dicho que no lo he mirado por perro   . Yo creía que el algoritmo que has puesto hace esto:

1.- Mira las 8 casillas adyecentes y les da un valor dependiendo de lo lejos que esté del inicio primero sería 1, luego 2...

2.- Luego mira las 8 casillas adyacentes de las miradas anteriormente. De modo que si miras dese una casilla con valor 1 pones valor 2 y si miras desde una con valor 7 pones valor 8.

3.- Cuando ya has acabado el algoritmo -en mi caso cuando ya no hay más casillas o encuentras el destino- haces el camino inverso:
      3a- Miras las 8 casillas del objetivo y te quedas con la del valor más pequeño y lo añades como punto de paso -Waypoint-.
      3b- Miras las 8 casillas del valor más pequeño del punto anterior y te quedas con el más pequeño y lo añades como punto de paso.
      3c- Repites el paso 3b hasta llegar a la casilla de origen  -o de destino según como lo hayas echo-.
      3d- Ya tienes los Waypoints que ha de seguir el objeto para llegar a su destino.

Realmente eso es también lo que hace el mio, solamente que yo no miro los puntos intransitables y eso lo hace más rápido y que nunca se equivoque, pero la base es exactamente la misma. Creo que me pusiste un enlace al sistema que usas y solo lo miré de refilón y era igual que el mio pero voy a mirarlo mejor ahora

EDITADO: Vale el algoritmo que yo uso al parecer se llama BrushFire, no eras tu quien lo puso, aquí pongo un enlace que lo explica:
BrushFire explicación

aquí varios articulos en español, creo que valen la pena leerlos
PathFinders

El algoritmo , como ya dije en el primer post, es una traducción de uno escrito en C++. Lo posteó Hasho. Este es el enlace:

http://www.catsoft-studios.com/article/index.php?artid=74

Muy bueno el enlace que has puesto.

FNK Games  Games Developer  -  Juegos realizados en Unity para iOS y Android



He leído el artículo del enlace, realmente el sistema es más simple que el que yo expuse pero no me gusta pues puede que aunque encuentre el camino correcto, y no tiene porque encontrarlo aunque exista, podría dar mucho rodeo.

Voy a ver si me bajo tu código y lo miro pero si que es practicamente idéntico al que puse yo, la pequeña diferéncia entre uno y otro es lo que hace que el que puse sea efectivo, mientras que el del enlace que me has puesto no lo es pudiendo llegar a callejones sin salida.

Me he bajado tu código y lo estoy probando y repasando, dios que pesado que soy  :evil: .

1.- Desconocia las instrucciónes: String.Substring y parseInt, gracias a tí ya las conozco   .

2.- No puede encontrar el camino si hay alguna "calle" cortada. Primero vuelve al principio en vez de intentar buscar otro camino, algo que con tu código no sería muy difícil de hacer, solo has de recalcular la ruta con tu función ActualizarMatriz(Target) donde Target sigue siendo el mismo de antes, creo que así funcionaría.

Cuando llega al punto 0, recalcula el camino pero si vuelve a encontrar un problema vuelve al punto inicial y ya no hace nada, por lo menos en el escenario que le impuse yo  :evil: .

3.- He visto que en el Start(), después de Escanear el Terreno, llama a la función ActualizarMatriz(Target) con Target en (0,0) -la posición inicial del jugador, lo cual es totalmente prescindible pues no va a hacer nada y estás perdiendo tiempo, ya se que para un ordenador moderno no es na de na.

3.- Lo de:

X = new Array( 0,  0,  1, -1,  1,  1, -1, -1);
Y = new Array( 1, -1,  0,  0, -1,  1, -1,  1);
....
u = P.x + X
;
v = P.y + Y
;

me parece muy bueno, nunca lo había pensado de hacerlo de esa manera, gracias creo que lo pondré en el mio y me ahorraré algunas líneas de código  
.

4.-
Bloque 1 y Bloque 2. He entendido que ese código mira si se está o no en movimiento, de no estarlo llama a la función de movimiento teniendo en Cuadricula la posición donde ha de ir. La función Moverse(Cuadrícula) -llamada desde el Bloque 2- se encarga de ver si ha llegado al siguiente nodo. La verdad esta parte, junto con la función  Moverse(Cuadrícula) la he encontrado algo liosa.

Conclusión:
 Es un pathfinder correcto si, tal y como está ese código, lo usas en un juego title donde no hay callejones sin salida, de lo contrario no encontraría su destino casi nunca y solo lo encontraría si tan solo se encuentra un callejón sin salida y además de una forma muy irreal, pues vuelve al punto de origen para volver a probar suerte -cambia eso  :kiss: .

En otro tipo de juego lo que veo es la forma de encontrar los nodos, pues el suelo está formado de objetos cuya posición hacen de nodos, ¿te imaginas un escenario de 500x500?, tendrías que crear 250.000 objetos, que burrada. De todas formas es un cambio tan simple como hacer una array bidimensional o tridimensioal con las coordenadas y listo.

Buen trabajo, mucho mejor que los que acuden a la Assest Store cada vez que quieren hacer algo.

Muy buena la página de Starco, si señor. Qué de información sobre PathFinding!

Yo voy a seguir con este script... Esta mañana en el trabajo traté de hacerme un script que me creara todo el conjunto de planos que conforman la cuadrícula, para así no tener que ir poniendo nombres tipo 0103 a cada plano. Ya casi lo tenía pero me vi con un lío de arrays así que ya lo tocaré otro día.

Como dices Hosuko, es limitado y servirá para pocos juegos, pero si se investiga un poco más sobre él, creo que puede valer perfectamente para un mapa complejo.

Un saludo!

Buenas, he escrito unos scripts para crearme el escenario con solo decir un número de filas y de columnas en el inspector.

El problema es que me lo crea de abajo a arriba y de izquierda a derecha... y luego el pathfinding no funciona, creo que debido a eso.

Puede ser esa la causa? Que no empiecen por arriba a la izquierda?


De todos modos os dejo aquí los scripts por si os interesan.
Solo necesitáis tener 2 prefabs; uno de PuntoMatriz y otro de Obstaculo. Con sus tags y todo lo necesario para que se vean.

CrearTablero.js // Este yo lo pongo en el player, por ejemplo.

var plano : GameObject;
var obstaculo : GameObject;
var alto: int;
var ancho  : int;

function Start () {

for (var i : int = alto; i >=0; --i)
{
        for (var j : int = 0; j 12)  
           Instantiate(plano,Vector3(i,0,j),Quaternion.identity);
           else
           Instantiate(obstaculo,Vector3(i,0,j),Quaternion.identity);
   }
}

}



RenombradoCelda.js  // ponedlo en los 2 prefabs que hablé antes.

private var nameaux : String;
private var cero : int;

function Start () {

cero = 0;

if(transform.position.z

Un saludo

Yo en mi programa para probar mi PathFinder lo que hago es que cree los obstáculos de forma aleatoria, en el editor puedo decir el tamaño de la tabla y el número de obstáculos; de ese modo veo muchas situaciones distintas, incluidas las que no puede llegarse al destino por estar encerrado y asi compruebo si da errores o no el código


//De forma aleatoria decidimos poner obstáculos
var nx : int;
var nz : int;
var NObstaculos : int = 10;  //se puede cambiar en el editor
var Correcto : boolean = false;
for(var nid = 0; nid

También tengo puesto el punto inicial y final de forma aleatoria todo para probar distintas combinaciones y que nunca sea igual


El problema es que me lo crea de abajo a arriba y de izquierda a derecha... y luego el pathfinding no funciona, creo que debido a eso.
[/quote]

Recuerda poner el Tag "PuntoMatriz" y "Obstaculo" a las cuadriculas. Puede que sea eso

FNK Games  Games Developer  -  Juegos realizados en Unity para iOS y Android





1.- Desconocia las instrucciónes: String.Substring y parseInt, gracias a tí ya las conozco   .

[/quote]

Las solia usar cuando programaba en Java. Supuse que también estarian en unityscript.




4.- Bloque 1 y Bloque 2. He entendido que ese código mira si se está o no en movimiento, de no estarlo llama a la función de movimiento teniendo en Cuadricula la posición donde ha de ir. La función Moverse(Cuadrícula) -llamada desde el Bloque 2- se encarga de ver si ha llegado al siguiente nodo. La verdad esta parte, junto con la función  Moverse(Cuadrícula) la he encontrado algo liosa.
[/quote]

Si es liosa esta parte. Lo que pasa es que la función te devuelve el siguiente punto, y en cuanto lo ha calculado, el player se dirige hacia él. Quiero decir que no se almacenan los puntos en un Array para después recorrerlo, que creo es lo que hacen los demás pathfinders. Va de punto en punto, calculando y moviéndose, caculando y moviéndose.

Está claro que es un pathfinder muy limitado.  Pero para el escenario donde iba a funcionar era suficiente.

Claro una cosa es escribir el código del algoritmo y otra es llevarlo a cabo en un escenario en Unity. Lo digo por el tema de la división del terreno. A mi se me ocurrió el tema de las cuadrículas pero he estado viendo otras formas en un post de foro de como escanear el terreno y dividirlo en cuadros. Seguro que lo conoceis. Es de un usuario que estaba trabajando en el A * Pathfinder.

Alñgoritmo A* para compartir

En cuanto tenga tiempo voy estudiar el algoritmo de Brushfire, y si consigo hacerlo funcionar lo subiré.

Es un tema apasionante esto de los pathfinders.

FNK Games  Games Developer  -  Juegos realizados en Unity para iOS y Android



Está bien, Hosuko, lo de poner os obstáculos aleatorios, aunque siendo totalmente aleatorio, la matriz te puede quedar muy liosa y difícil. Yo ahora me he hecho otro script que funciona en edit mode, y lo que hace es cambiar la casilla seleccionada de transitable a obstáculo, pulsando una tecla, para cambiar rápidamente el mapa sin tener que volver a meterme en scrips.

Por otro lado, sigo atascado con mi player, no se que pasa que desde que me creé la matriz con este método, con el que al final conseguí tenerla bien ordenada con el 0000 arriba a la izquierda, no he conseguido que trace bien los caminos. Todo el rato se me va al 0000, o incluso se pasa y se va fuera de la matriz y  se queda allí xD.

Seguiré investigando a ver por qué ahora no me va  :dry:  

Muy buena pinta tiene el A* de lonog.


Por otro lado, sigo atascado con mi player, no se que pasa que desde que me creé la matriz con este método, con el que al final conseguí tenerla bien ordenada con el 0000 arriba a la izquierda, no he conseguido que trace bien los caminos. Todo el rato se me va al 0000, o incluso se pasa y se va fuera de la matriz y  se queda allí xD.
[/quote]

Puede que por algún motivo las cuadrículas no esten ordenadas. Revisa  el nombre de las cuadrículas a ver si tienes alguna cambiada. (Es algo que me ocurrió a mi.)  y no me funcionaba.

Si quieres puedes colgar el proyecto para poder ayudarte mejor.

FNK Games  Games Developer  -  Juegos realizados en Unity para iOS y Android



Ok, gracias. En cuanto pueda cuelgo el proyecto.

No creo que puedan estár desordenados los puntos ya que los creo con un script

Etiquetas: