Godot, 1000 cositas

Motor Godot recientemente descubierto, un motor de juego de código abierto. Comparto algunos trucos y notas, principalmente del área 3D, código o puntos generales.





Godot en su conjunto tiene una reputación más bien como un motor 2D, que ha funcionado bastante bien, pero no hace mucho tiempo las capacidades 3D que han aparecido le permiten crear juegos tridimensionales. Especialmente si puedes optimizar algunas cosas tú mismo, no hagas que el juego sea demasiado pesado y complejo, y también estás contento con las opciones de renderización actuales. O puede esperar futuras optimizaciones y la aparición de vulkan.



"Fuera de la caja" en el motor hay algo de física, incluidas las articulaciones y los vehículos con ruedas. No hay un editor de terreno incorporado, pero puede usar un complemento, importar desde programas especializados o simplemente como una malla desde un paquete 3D. En este último caso, por el bien del rendimiento, tendrá que cortar de forma independiente el paisaje en fragmentos, y lo más probable es que se conviertan en mallas separadas para colisiones. En cuanto a las mallas para la forma de la colisión del paisaje, para que no haya inconsistencias visuales, debe triangular el modelo durante la exportación desde el paquete 3D. Por ejemplo, una de las formas más simples de hacer esto en Blender es exportar la malla en formato collada (.dae), hay una casilla de verificación triangulada por defecto.

A veces, el modelo Blender tendrá que voltearse 180 grados dentro de Godot, así que no se sorprenda si su terreno no es visible, lo más probable es que las normales lo roten en la dirección incorrecta.



Godot practica el enfoque de "todo es una escena" y está orientado a la estructura de elementos de los árboles. En la práctica, esto significa que se agregan nuevos objetos al nivel como ramas de los nodos que ya existen en él, pueden convertirse en prefabricados y abrirse por separado, como si fuera su pequeño mundo local separado. Por lo tanto, es muy conveniente editar todo tipo de objetos compuestos guardados, lo único es que si la luz se expuso a tu nivel, entonces, por ejemplo, al entrar al personaje, en su escena local, no verás esta iluminación y al configurar sus materiales no entenderás cómo se ven. ligero. Este problema se puede resolver de diferentes maneras, por ejemplo, cambiando a la ventana de nivel y evaluando los cambios que tienen lugar con el personaje, después de guardar su escena allí. O simplemente tira temporalmente la fuente de luz dentro del prefabricado con el personaje.





theEnergy, . Area, , , .



En cuanto a los lenguajes, aparte del método de bajo nivel, las opciones más comunes son los lenguajes de scripts GDScript y C #, así como los scripts visuales para algo simple. GDScript está mejor integrado en el motor, tiene más ejemplos, no requiere el lanzamiento de un entorno externo y, en términos de la estructura general, todo sucederá aquí como en la versión C #: declarar variables, llamar a una función de inicialización, un ciclo de proceso, un ciclo de proceso físico, etc. Por lo tanto, elegir GDScript como su principal lenguaje de programación de desarrollo tiene sentido. Cambiando a C # local, solo obtendremos mayor precisión y detalles del registro, perdiendo concisión, pero aumentando la inteligibilidad y el control sobre la situación: llaves en lugar de usar pestañas, marcas de final de línea, tipeo más formal.





Código adjunto al objeto mencionado (en GDScript). Se configura un identificador variable, cuyo valor se puede configurar en el editor, luego una función de inicialización única, en la que no sucede nada especial (y se puede borrar). A continuación se describe un método de manejo de señal que eliminará un objeto.



En cuanto a las variables globales, para usarlas tanto en GDScript como en C #, debe agregar un script / scripts globales para iniciar en los parámetros del proyecto, cuyas variables se pueden acceder globalmente.

También en Godot hay una limitación: no puede haber más de un script en cada objeto. Pero este momento se puede eludir, por ejemplo, colgando el segundo script en el objeto secundario.



Señales



Para intercambiar datos entre nodos en Godot, también puede usar la jerarquía, porque los objetos están unidos entre sí, como ramas de un árbol. Es cierto que este enfoque tiene sus dificultades, porque en nuestro juego la jerarquía puede ser cambiada dinámicamente. Además, referirse a la jerarquía dentro de una escena es una cosa, pero cuando tiene una escena dentro de una escena dentro de una escena, entonces surgen algunas dificultades con esto, aunque solo sea para comprender lo que está sucediendo.

Una forma de gestionar todo esto y no apegarse demasiado a una jerarquía actual específica es a través de señales. Ya se ha preinstalado un cierto número de señales comunes: puede mirar en el panel de señales del objeto para adjuntar una línea con el procesamiento de recibir una de ellas en un guión del mismo objeto u otro objeto con un guión dentro de la escena. Si necesita hacer su propia señal, puede hacerlo así:





Iniciamos la señal. La emitimos



en el mismo guión cuando hace clic en un botón u otras condiciones.



Todo está bien con esto, hasta que necesite transferir señales de una escena a otra. Por ejemplo, porque codifica un nivel de escenas y necesita saber cuándo necesita destruir el nivel actual y, por ejemplo, ensamblar el siguiente.

En este caso, puede adjuntar un controlador de señal al objeto que enviará una señal a la escena raíz justo en el momento en que el código construya el nivel. Por lo tanto, nosotros, por así decirlo, conseguimos un agente espía en este hilo generado y escuchamos lo que nos dice.





En el momento del ensamblaje de nivel, encontramos una nave espacial y le adjuntamos un oyente de señal, indicando el método en el que procesaremos los mensajes de esta señal.



También puede adjuntar algunas variables a la señal, lo que puede ser bastante útil. Por ejemplo, en lugar de generar diferentes señales en el objeto, podemos salir adelante con uno, pero lo enviaremos con diferentes parámetros y, adicionalmente, lo procesaremos al recibirlo.





Y aquí está la descripción del método en sí, que comenzamos anteriormente. Al recibir una señal, procesa la variable enviada con ella.



Otra cosa útil que reduce la cantidad de señales innecesarias es que, en lugar de enviar una señal personal, un objeto puede tocar a otro para que envíe la señal ya enrollada en él. Por ejemplo, una explosión recibe una señal de que tocó a un jugador, y en el controlador de señales descubre si el jugador tiene un método de autodestrucción, y lo lanza si se encuentra. El jugador, en este método llamado suyo, envía una señal a la escena raíz de que ha muerto. En el guión de la escena raíz, el controlador de la señal de muerte del jugador borra el mundo y recoge el menú del juego.





Ocurre un evento y vemos si el objeto que ingresó a la zona tiene el método requerido.





, , . , , .



CSG-





Una de las herramientas 3D útiles en Godot son las primitivas constructivas de geometría sólida. En pocas palabras, estos son objetos que admiten operaciones booleanas: intersección, exclusión, unión. Además del conjunto de primitivas, existe una malla universal CSG, para la cual se puede establecer una malla arbitraria como forma.







Se requerirá el maniquí CSG Combiner para su uso en una jerarquía para controlar la prioridad de las operaciones cuando sea necesario ensamblar alguna estructura compleja.





Un par de esferas de las cuales se cortan las esferas hijas.



La aplicación principal de CSG es la conveniencia y la simplicidad del nivel de creación de prototipos estáticos y algunos de sus elementos. De hecho, puede hacer una malla en un paquete 3D y repetir las mismas formas resultantes, a menos que tenga que hacer esto fuera del editor del juego.



El siguiente uso de CSG estático es simular la destructibilidad y el daño. para hacer esto, necesita organizar primitivas CSG en el modo de exclusión, como agujeros, "trozos" y abolladuras, y luego esconderse temporalmente, incluida la visibilidad en el momento adecuado. La limitación aquí es que solo podemos "dañar" la superficie del objeto CSG, además, el "daño" se debe adjuntar inicialmente a él como un niño, o adjunto a través del código como un niño. Pero esta opción en términos de flexibilidad de personalización ya gana significativamente en comparación con el objeto destructible preparado en el paquete 3D.





Hay 3 cilindros integrados en el puente en el modo de exclusión. Mientras están ocultos todo el puente.



Si está habilitado, el área que excluyen se corta.



A continuación tenemos CSG en movimiento. Mediante código o animación grabada. En general, a través de este método puede implementar algunos efectos, pero es muy deseable que tales animaciones no giren en el escenario en un bucle. Varios CSG animados pueden afectar significativamente el rendimiento, y Godot no optimiza todas las cosas, y si no elimina usted mismo los CSG animados, continuarán consumiendo el rendimiento fuera de la visibilidad de la cámara.

Sin embargo, los efectos de los CSG animados ya son difíciles de reemplazar con soluciones de paquetes 3D, por lo que puede estar interesado en usarlos (al menos si no va a dibujar 3D avanzado a través del código). Lo principal es encontrarles la aplicación correcta, lo mejor es usarlos puntualmente, en ciertos lugares, incluida la animación de disparo. Como el efecto de abrir un pasaje u otro efecto especial de una sola vez. Naturalmente, cuanto más simple sea la forma de los objetos CSG, mejor. Y ejercen la carga computacional principal precisamente en el proceso de contacto en movimiento, además, no hay diferencia especial de qué objeto mover en relación con otro.





Hay un momento en el video en el que el automóvil cae por un agujero en el puente, cuando una cápsula CSG animada pasa a través de una malla CSG con un modelo del puente.



Multimesh





Si necesita replicar una malla en grandes cantidades, por ejemplo, esparciendo piedras o árboles a través del nivel, entonces el nodo MultimeshInstance es útil aquí.

Después de agregar la malla múltiple a la escena, debe especificar sobre qué objeto dispersar las copias y qué tomar como muestra para los clones. En el camino, puede elegir el tamaño de los clones y su número. Cuando la mezcla múltiple se “hornea”, representa muchos clones, y los objetivos que utilizó para su generación se pueden eliminar si ya no son necesarios.





Un botón para seleccionar objetivos multimedia aparece en la ventana del editor en la parte superior derecha cuando se selecciona. Si lo presiona, esta ventana con la configuración de generación se cerrará.





Aquí tenemos dos objetos agregados a la escena como nodos MeshInstance. A continuación, dejamos el objeto izquierdo a la derecha.





Nos ponemos multimesh. En esta situación, se configuraron 10.000 clones en la configuración. Por cierto, si hubiera 3-4 mil de ellos, visualmente el resultado no sería muy diferente.



El multimesh "horneado" se puede mover a cualquier lugar y, además, tiene un parámetro de instancia visible que muestra inicialmente el número de clones especificados durante la generación. Al cambiar este valor, puede controlar cuántos clones se muestran actualmente. Por defecto hay -1, pero este es un valor especial para mostrar el máximo de clones. Si pones 10, habrá 10 clones, si 100, luego 100. Si el máximo fue 50, entonces a 100 y a 1000, y a -1 habrá 50 de ellos.

Puede usar esta capacidad multimesh para crear efectos especiales animando el parámetro de instancia visible a través de código o animación grabada. Para un control más preciso sobre la densidad de los clones, puede usar el paquete 3D para hacer una malla separada con una malla sólida exactamente en aquellos lugares donde se necesita la densidad máxima de clones, y aquellos lugares donde no deberían estar, no cubra con polígonos o haga roturas en ellos.





Establecemos la Instancia visible en 500 y la densidad de relleno cae dramáticamente.



Diverso





El control en Godot se puede configurar abriendo el elemento Proyecto en el panel superior del editor. Siguiente configuración del proyecto , pestaña Lista de acciones .





Puede ver cómo se llaman los botones predeterminados para que sepa a qué nombres referirse mediante el código. Y también agrega el tuyo.



Por ejemplo, el nombre predeterminado para el botón PgUP es "ui_page_up", y puede manejar su presión en el código escribiendo la siguiente línea en GDScript - si Input.is_action_pressed ("ui_page_up"):

si se requiere una acción para una sola pulsación, is_action_pressed debe reemplazarse por is_action_Just_pressed. El final de presionar - presionado cambia a liberado.



# #



Si necesita animar el parpadeo de un material, puede hacerlo a través de un sombreador personalizado. Para hacer esto, seleccione New ShaderMaterial como el material del objeto.









Luego, seleccione VisualShader en el campo vacío.





Haga clic en él, el editor visual se abrirá debajo del editor.



Agregue un par de nodos, primero Input - All - Time , luego Scalar - Common - ScalarFunc , configurándolo en su lista desplegable, por ejemplo, Pecado. En principio, dicho diseño ya dará algo así como un parpadeo entre blanco y negro, pero para mejor, agregue otro nodo Escalar - Común - ScalarFuncy elige Abs allí. Conectamos los nodos entre sí (tenga en cuenta que al hacer clic en el ojo cerrado de cada nodo, puede abrirlo y ver cómo cambia la imagen en cada etapa) y conectarlos al canal Alfa, Emisión o Albedo. Eso es todo, nuestro objeto ahora parpadea.







Naturalmente, esto está lejos de ser la única forma, pero es una de las opciones más simples. Y si desea que el parpadeo sea de color, necesitará hacer un par de nodos con color, mezclarlos en un nodo especial (yendo a Albedo) y adjuntar la salida de la cadena de nodos que recopilamos anteriormente. Por lo tanto, esta cadena actuará como un factor de mezcla para estos colores.



# #



Para convertir el nodo seleccionado en una escena separada, haga clic derecho sobre él y seleccione la opción "Guardar rama como escena". Luego establece un nombre para esta escena. Después de eso, el ícono "Abrir en el editor" aparecerá junto al nombre del nodo, desde donde puede proceder a editar la escena resultante en una nueva ventana.

Para realizar la manipulación inversa, si, por ejemplo, necesitamos llevar los objetos de la rama guardada a la escena actual para reconstruirlos o modificarlos de alguna manera, haga clic en el nodo que oculta la escena, haga clic con el botón derecho y seleccione "Convertir en local". La escena guardada, que él representó, no se destruye.



#



Para usar variables globales, debe crear un script y lanzarlo en carga automática: Proyecto -Configuración del proyecto - Inicio . La casilla de verificación "singleton" debe estar marcada.





El contenido del script SaveTheWorld, cuyas variables queremos usar como globales. Por el momento, aquí se anuncia un cierto indicador de salud y una serie de estados enemigos, que se completa en el paso de inicialización.



Para acceder a estas variables globales desde el código, primero debe obtener un enlace al singleton, luego usar sus variables:





encuentre nuestro SaveTheWorld y luego verifique si el estado de este enemigo en particular es cero. Si es así, el enemigo es eliminado.



UPD Puede acceder a las variables de un singleton directamente a través de su nombre, es decir, en el ejemplo anterior, no tendríamos que tomar un enlace, y en lugar de main.enemy_arr [myID] nos referiríamos a SaveTheWorld.enemy_arr [myID]. Pero debe estar seguro de que este nodo tiene una marca en la columna "singleton" al inicio.



#



Se agrega un nodo AnimationPlayer a la escena para grabar y reproducir animaciones. Se puede ubicar en cualquier lugar de la jerarquía. Para darle la oportunidad de grabar animaciones, debe hacer clic en el botón "Animación" sobre la línea de tiempo abierta y crear una nueva animación.

Después de eso, en cada nodo seleccionado en la escena actual, aparecerán iconos clave a la derecha en el inspector. Si hace clic en la tecla, el animador le ofrecerá agregar una nueva pista de animación.







Luego, mueva el control deslizante de la línea de tiempo a los puntos deseados, y en cada uno de ellos cambiaremos ese valor animado en el inspector de objetos, presionando nuevamente la tecla para que este punto aparezca en la línea de tiempo. Puede expandir el calendario disponible en el campo con el reloj, a la derecha, por defecto hay 1 segundo. A la derecha del reloj está el botón de bucle de animación. A continuación, la primera en la línea es una de las opciones de uso frecuente, que establece la animación suave discreta o continua.

A la derecha del panel central con el nombre de la animación está el botón de ejecución automática; si lo presiona, la animación seleccionada se reproducirá cuando se inicie la aplicación. Si necesita varios objetos animados que se reproducen en un bucle constantemente, puede crear sus pistas en un AnimationPlayer creando una animación común para ellos. Si necesita cambiar animaciones para un objeto específico, puede crear un AnimationPlayer separado para él y crear varias animaciones para diferentes estados allí, mientras que solo una de ellas se puede marcar como iniciando automáticamente.



#



Para varios nodos, por ejemplo, MeshInstance o CollisionShape, en el campo Mesh (Shape), puede elegir entre una lista preparada de primitivas (incluida la carga de su modelo personalizado, en el caso de MeshInstance).







Para MeshInstance, una de las primitivas más caras será la esfera y la cápsula, ya que probablemente contengan muchos polígonos. Por lo tanto, para las partículas 3D, es mejor elegir algo como un polígono, un cubo o un prisma. Para colisiones, por el contrario, la forma de la esfera será más fácil de leer, ya que de los parámetros solo tiene un radio. En realidad, lo anterior se aplica no solo a Godot, sino también a otros motores de juego.

Godot también puede crear una forma de colisión para MeshInstance automáticamente haciendo clic en el botón Matriz que aparece en la parte superior derecha del editor cuando se selecciona MeshInstance. Luego, elija entre las opciones propuestas, pero como regla general, para el mismo terreno, este será el primer elemento: "Crear un cuerpo estático cóncavo" (después de lo cual un nodo StaticBody con una colisión exacta anidada se unirá al objeto). En todos los demás casos, cuando no se requieren colisiones especialmente precisas, puede prescindir de las primitivas CollisionShape expuestas de forma independiente, o recoger mallas óptimas para colisiones en el paquete 3D, luego agregarlas a través de MeshInstance y también crear una colisión en su forma a través del botón Array.



# #



Si en algunos de los campos numéricos en el inspector se requiere, por ejemplo, agregar un cierto número al parámetro, multiplicar el valor, etc., puede superarlo así: "315-180", "20 + 40", "64 * 5" ... el editor mismo calculará y sustituirá el resultado final de la operación en el campo.



All Articles