Godot #HO | Información General

B

#688 si sabes el ángulo el resultado sería

Vector2(Cos(angulo), Sin(angulo)) * radio

El ángulo debe ir en radianes. Para pasar grados a radianes usa deg2rad.

1 respuesta
kidandcat

Alguien le esta dando a Android con Godot? por casualidad con C#? Si hay alguien que si, que solución de almacenamiento local usáis? Estaba usando SQLite de nuget, pero me da que va a ser un poco rollo compilarla para android.

2 respuestas
Ridote

#692 Tú. Encontraste algo en el proyecto que no furule o qué?

1 respuesta
kidandcat

#693 Aunque ya no lo necesitemos, quiero ver si hay alguien en nuestra situación y ver qué usa para almacenamiento local

AikonCWD

#691 Muchas gracias, luego lo pruebo. El angulo me lo puedo inventar, así que genial
#692 No he tocado nada de android, pero imagino que si salvas algo en usr:// debería valer, no?

Una duda:

Supongamos que un juego tiene que tener 100.000 nodos/objetos, pero claro, cargar 100k se carga toda la memoria y rendimiento.
Me gustaría hacer que solo se carguen los objetos que están visibles en la pantalla. A medida que el jugador se desplace... descargar los que salen fuera d ela pantalla y cargar los nuevos.

Tengo un array en el que guardo el vector de posición de cada objeto. Cómo lo implementaríais vosotros? Veo que hay un método find() para buscar en el array, pero dudo que sea óptimo llamar a find() por cada píxel que mueva de la camara, no?

ejemplo:

1 respuesta
kidandcat

#695 Depende de lo que tengas en la escena, si no estan sobrecargadas, intenta hacerlo con escenas superpuestas. Imaginate una cuadricula de escenas, si te mueves hacia un lado y llegas al borde, cargas la siguiente escena.

EJ: Ahora, para que no se quede vacia la pantalla cuando te acercas a los bordes, un tramo de la escena A va a superponerse con la escena B (deberían de tener las mismas cosas), de forma que tienes que hacer el cambio de escena de A a B justo antes de que el borde de la escena A aparezca en la pantalla.

Si es dificil de entender te hago un dibujo, pero es que me da pereza subir imágenes a mv.

PD: viendo tu imagen, lo quieres hacer en 3D? eso cambia muchas cosas

2 respuestas
Ridote

#696 No, tienes por cada nodo una forma de ver si está o no en pantalla, y los puedes ir haciendo invisibles conforme salgan de pantalla y tienes thresholds para eso creo

1 respuesta
AikonCWD

#696 Entiendo tu solución con el tema de escenas, pero no sería mi caso.

Simplemente tengo una escena donde el jugador se mueve libremente. desde la posición (-10000, -10000) hasta (10000, 10000).
Luego con un bucle instancio 100 asteroides.tscn y los posiciono random por el mapa.

Con 100 va todo guay, con 100.000 asteroides va todo mal. Como es lógico.

Es 2D.

#697 Para ello, el nodo debería estar instanciado para poder llamar al VisibleNotifier2D

En lugar de:

for i in range(1000):
    var x = preload("objeto").instance()
    x.position = random()
    add_child(x)

Debería hacer algo así:

var array = []
for i in range(1000):
    array.append(random())

Y luego me faltaría la función que lea ese array e instancie (y haga queue_free) los objetos en función de la posición de la camara. Para ello debería buscar, comparar y localizar en el array cualquier objeto cuya posición se encuentre dentro d ela camara para instanciarlo o borrarlo.

Se os ocurre una forma más eficiente?

1 respuesta
Ridote

#698 Las señales se pueden conectar programáticamente, no te haría falta cambiar el primer pedazo de código ni tener que revisar todos los nodos a mano desde un manager, los nodos podrían revisarse a sí mismo conectando señales.

1 respuesta
AikonCWD

#699 Pero para ello deberían estar instanciados, dentro del tree(), no?

1 respuesta
Ridote

#700 add_child(x) + ready() y conectas

1 respuesta
AikonCWD

#701 Creo que no me he explicado bien.

El problema aparece cuando hago add_child(x) 100.000 veces. Tengo que evitarme el add_child() para los 99.990 nodos que NO están en pantalla. Y solo hacer add_child() de esos 10 nodos que sí están en pantalla.

Y mientras te muevas, liberar los nodos que salgan de la pantalla (con el visiblenotifier) y cargar (hacer add_child) de los nuevos. Evidentemente si retrocedes, se deberían cargar de nuevo los nodos ya cargados anteriormente.

2 respuestas
kidandcat

#702 por que no simplemente generas solo los nodos cercanos? en vez de generar random en un area muy grande, genera random justo por los bordes de la pantalla, de hecho creo que uno de los primeros tutoriales de godot hacía eso, movía una entidad invisible por los bordes de la pantalla y esa entidad iba spawneando enemigos.

PD: de todas formas tu problema es más conceptual que de Godot, lo mismo en otro hilo con más gente consigues alguna solución que se adapte mejor a lo que quieres. (no lo digo de malas formas, solo que Godot no va a tener una solución milagrosa, es más pensar en cómo simular lo que quieres que realmente parezca, al final de eso se trata la programación de videojuegos)

1 respuesta
AikonCWD

#703 Porque entonces tendría un mapa "cuántico" xd.

Imagina que genero random, tal y como propones, mientras me muevo:

Estoy en la posición 10 y voy a la 20, y se me genera un asterioide en 35
Retrocedo y vuelvo otra vez de la posición 10 a la 20 y ahora el estaroide está en 45, o no está o hay 2 asterioides... quedaría muy raro y falso.

#703kidandcat:

PD: de todas formas tu problema es más conceptual que de Godot, lo mismo en otro hilo con más gente consigues alguna solución que se adapte mejor a lo que quieres.

Correcto, de todas formas no sé si los otros engines usan esta filosofia de nodos en un árbol, etc...

1 respuesta
kidandcat

#704 Da igual si usan nodos en un arbol, que mapaches, al final el problema no es que godot se laggee por tener 100k nodos, se lagea tu pc por tener 100k modelos/sprites en memoria (aunque no los veas en la pantalla).

Sé a lo que te refieres, pero no estoy yo seguro de que en esos típicos juegos random las cosas estén siempre en el mismo sitio, pero otra solución: en vez de instanciar los nodos, mantén solo un array bidimensional con la posición, y los instancias solo cuando te acerques, si no van a moverse de su sitio, eso te funcionará.

Mantener un array con la posición e ir consultandolo no te debería dar ningún problema, 100k items no son muchos si solo son booleanos en un array bidimensional.

1 respuesta
AikonCWD
#705kidandcat:

en vez de instanciar los nodos, mantén solo un array bidimensional con la posición, y los instancias solo cuando te acerques, si no van a moverse de su sitio, eso te funcionará.

Eso! Eso es lo que llevo diciendo desde el principio.

Ya tengo un array con la posición de cada nodo. Pero no sé picar la función que itere todo el array y devuelva aquellos cuya posición esté dentro de un rectángulo...

Voy a seguir pensando.

Y sí, los nodos numerosos no se mueven, así que con el array y un manager debería poder hacerlo

1 respuesta
kidandcat

#706 "Pero no sé picar la función que itere todo el array y devuelva aquellos suya posición esté dentro de un rectángulo..."

https://math.stackexchange.com/questions/190111/how-to-check-if-a-point-is-inside-a-rectangle

1 respuesta
Ridote

#702 estoy un poco liado no puedo leerme todos los mensajes pero te dejo un par de opiniones:

  • Si sacas del árbol un nodo, las señales no harán trigger por lo que el visibility notifier queda descartado
  • Con hacer los nodos invisibles y hacerles un return en el process (si tuvieras un process o ph_process) ya te ahorraslas lógica, no es perfecto, pero es lo mejor que puedes hacer.
  • Algunos nodos el hacerlos invisibles igual no te sirve. Haz lo correspondiente en cada nodo.
  • Haz profiling con y sin esta funcionalidad, metiendo misma escena y mismos nodos en ambos casos, a ser posible con muchísimos nodos.
AikonCWD

#707 this! pero joder qué complejo. Voy a leer

1 respuesta
B

#709 lo menos costoso para calcular delimitaciones es usar una esfera...

Los asteroides en la zona roja seguirán activos a pesar de estar fuera de cámara... pero a cambio el cálculo se reduce a una simple comparación de longitudes/distancias.

// radio de la esfera contenedora
radio = Vector2(anchoCuadrado / 2, altoCuadrado / 2).lenght

asteroide = Vector2(x, y)

function comprueba(asteriode: Vector2, radio: number) { 

    return asteriode.length < radio;

}




Para delimitar exactamente el área del rectángulo, si no está girado la forma simple es:

let cuadrado: { x: number, y: number, base: number, altura: number };

function comprueba(punto, cuadrado) {

     return

            punto.x > cuadrado.x &&
            punto.x < cuadrado.x + cuadrado.base &&
            punto.y > cuadrado.y &&
            punto.y < cuadrado.y + cuadrado.altura;

}




Si está girado entonces hay varios métodos para hacerlo... pero en este punto tiraría de la implementación que aporta Godot.

Según la docu te debería servir esto (nunca he usado Godot)

Rect2(Vector2(), Vector2()).has_point(Vector2())




edit: Rect2 no serviría porque se supone que va alineado al eje de coordenadas, no se puede girar. Supongo que habrá algo equivalente.

1 2 respuestas
AikonCWD

#710 muchas gracias. Lo de la esfera ya lo había pensado, ya que la idea es cargar no solo lo que va a salir en pantalla, si no un poco más allá. Para que de tiempo a todo.

1
AikonCWD

#710 http://aikoncwd.ovh/spaceship/

Bueno pues así lo dejo. Me quedo con lo mucho que he aprendido optimizando juegos (o al menos no programando como un burro) y sabiendo manejar escenas con un montón de objetos instanciados.

La versión web/html5 la he compilado bajo GLES2 con el nuevo proceso de batching. Partículas pasadas de GPU a CPU y todo lo que hemos hablado de cargar solo los nodos visibles.

Lo he probado en mi cutre-móvil y el juego carga (aunque no es jugable porque no tiene GUI para móvil). En un PC debería funcionar decentemente bien.
Los binarios compilados de win/mac/linux deberían ir fetén.

Por el momento dejo el proyecto aparcado aquí. A ver que os parece

2 1 respuesta
B

#712 va un pelín sobrecargado en html... está chulo.

Al ritmo que vas igual te compensa currarte un devlog para esto y después juntar estos minidesarrollos en un blog.

7 días después
AikonCWD

Por cierto, hoy sale Primal Light

Un juego hecho en Godot, por 2 hermanos. 3 años de desarrollo.
A destacar el enorme trabajo de pixel art. Se trata de un plataforma lineal 2D.

Tiene muy buena pinta!!

13 días después
B

Buenas.

Un par de dudas... una ¿Actualmente Godot soporta exportación a html5 usando c#?

Otra, cuando creas un CubeMesh va sin uv2 (algo que me parece extraño al ser una primitiva), entonces uso "Desenvuelva UV2" y da error "La malla contenedora no es del tipo ArrayMesh".

Veo que tengo la opción de cambiar el CubeMesh por un ArrayMesh pero claro, entonces ya no tengo un Cubo y en todo caso debería ¿cargar la data por código? lo cuál no es lo que busco.

También leo que se puede crear por código... que tampoco es lo que trato de resolver.

La duda exacta es ¿Como se añade uv2 a un CubeMesh? (Cube o cualquiera otra de las primitivas)

2 respuestas
Ridote
#715dKode:

Un par de dudas... una ¿Actualmente Godot soporta exportación a html5 usando c#?

Me voy a lanzar a la piscina y voy a decir que sí. Pero repito que el soporte de c# creo que es experimental aún. De hecho en la 3.2.2 https://godotengine.org/article/maintenance-release-godot-3-2-2 dijeron que había soporte para IOS también.

#715dKode:

Otra, cuando creas un CubeMesh va sin uv2 (algo que me parece extraño al ser una primitiva), entonces uso "Desenvuelva UV2" y da error "La malla contenedora no es del tipo ArrayMesh".

Ni idea. Ando haciendo cosas en 3D pero cargo mis modelos desde blender, no he probado nada más básico.

1 1 respuesta
AikonCWD

#715 Me has matado con lo del unwrap uv2 sobre una primitiva... lo he probado y me ocurre lo mismo (no tenía ni idea). En cambio si es un modelo importado desde blender, lo hace sin problema.

No puedo ayudarte :(

1 respuesta
B

#716 vale, confirmo... soporta exportación html5 con c# gracias

#717 si me estanco demasiado acabaré importando un cubo. Pero vamos, al ser una primitiva debería crearse por defecto el uv2 o en todo caso habilitar un modo claro para generarlo. Seguiré investigando tratando de no pararme demasiado.

1 1 respuesta
Ridote

#718 Pero qué ves exactamente en la pantalla. Puedes poner un gif reproduciendo los pasos y señalando el problema?

1 respuesta
B

#719 es un CubeMesh lo seleccionado, no hay uv2 no se puede crear uv2