Siga leyendo para aprender a mejorar su proceso de control de calidad y depuración con la clase Debug de Unity.
Si bien es posible que ya esté familiarizado con el archivo Debug.Log la clase Unity Debug soporta muchas otras funciones útiles que pueden ayudarle a acelerar sus pruebas y depuración. Esta página explica cómo usar la clase Debug para la visualización de gizmo en las vistas Scene y Game, para pausar el modo Play en el Editor desde script, y más consejos.
Si usted tiene experiencia con Unity, entonces probablemente ha utilizado la ventana de Consola para mostrar errores, advertencias y otros mensajes generados por el Editor. Seguro que también has impreso tus propios mensajes en la Consola utilizando la clase Debug.
Pero no está limitado sólo al mensaje Debug.Log. Cuando crea cadenas de salida para la ventana de la Consola, puede especificar uno de los tres tipos (error, advertencia y mensaje), cada uno con su propio tipo de icono.
Las tres variantes son:
- Debug.Log ("Esto es un mensaje de registro.")
- Debug.LogWarning ("Este es un mensaje de advertencia.")
- Debug.LogError ("Esto es un mensaje de error.")
Puede utilizar la ventana de la consola para filtrar los mensajes en función de sus preferencias. Usted también puede tomar ventaja de tener la Pausa de Error habilitada en la ventana de la Consola, ya que cualquier error que usted escriba en la Consola vía la clase Debug causará que el modo Play de Unity se detenga.
Todo lo que sale a la ventana de Consola, ya sea por Unity o sus propios mensajes, es agregado a un Archivo de Registro que usted puede referenciar para ver donde ocurrieron los problemas en su aplicación. Cada sistema operativo almacena los archivos de registro en ubicaciones diferentes, así que consulta la documentación para ver las especificaciones de cada sistema.
Cuando se lanza un error o una excepción, la ventana de la consola muestra el seguimiento de la pila junto con el mensaje de error para ayudarle a entender cómo se produjo el error y dónde se originó. Aunque Debug.Log le permite enviar un mensaje a la Consola, también puede configurar el nivel de detalle que se muestra en el seguimiento de pila.
Por defecto, la salida en la Consola enlaza con la línea de código que generó el mensaje, lo que facilita la identificación de la línea, método o secuencia de llamadas a funciones que provocó la aparición de la entrada.
Si el script no se abre en el IDE elegido, vaya a Archivo > Preferencias > Herramientas externas y seleccione "Editor de scripts externo" en el menú desplegable.
Puede configurar la información mostrada en el seguimiento de pila a través de Archivo > Configuración de compilación... > Configuración del reproductor ... > Otras configuraciones en el Editor.
Las siguientes opciones están disponibles para cada tipo de registro:
- Ninguna: No se enviará ningún seguimiento de pila al registro.
- ScriptOnly: Sólo se mostrará el seguimiento de la pila gestionada. Esta es la opción por defecto si no has cambiado la configuración.
- Lleno: Se registrará el seguimiento de la pila nativa y gestionada.
Utiliza la función de búsqueda de la Consola si tu registro se llena. Al escribir un término de búsqueda, la Consola filtra los mensajes para mostrar sólo los que contienen el texto coincidente.
Controle cuántas líneas de cada entrada son visibles en la lista haciendo clic en el botón de menú Consola y seleccionando Entrada de registro > [X] Líneas en el menú, donde [X] es el número de líneas a mostrar para cada entrada.
La dirección String.Format de C# permite crear una cadena con datos variables formateados incrustados. La clase Debug tiene Debug.LogFormatque utiliza la misma sintaxis.
El primer parámetro es la cadena de mensajes formateada. Al incluir un valor de índice entre llaves, éste será reemplazado por el parámetro índice-1 utilizando su método ToString, si existe, o la conversión de cadenas de System. En el ejemplo de código anterior, línea 14, {0} se sustituirá por origin.ToString().
Un ejemplo más complejo es el siguiente:
Debug.LogFormat("Al inicio transform.position={0}, transform.rotation={1}", transform.position, transform.rotation);
{0} será sustituido por el parámetro 1, transform.position y {1} será sustituido por el parámetro 2, transform.rotation. En cada caso se utilizará el método ToString de las propiedades Vector3 y Quaternion. El resultado será el siguiente:
"El origen es (0.00, 0.00, 0.00)
UnityEngine.Debug:LogFormat (string,object[])”
También puede proporcionar un segundo parámetro opcional a estos métodos de registro para indicar que el mensaje está asociado con un GameObject en particular:
Debug.LogWarning("¡Vengo en son de paz!", this.gameObject);
Cuando se muestran datos variables formateados, existen versiones de advertencia y error de Debug.LogFormat:
- Debug.LogWarningFormat("El valor de Cubo.posicion.x es {0:0.00}", transform.posicion.x)
- Debug.LogErrorFormat("El valor de Cubo.posicion.x es {0:0.00}", transform.posicion.x)
Si envía un valor flotante a la Consola utilizando Debug.Logformat, la pantalla por defecto mostrará seis números después del punto decimal. Puede controlar este comportamiento con una cadena de formato numérico personalizada.
Debug.LogFormat("pi = {0:0.00}", Mathf.PI);
Utilizando dos puntos, la cadena de formato 0.00 mostrará la parte entera de un valor, el separador decimal y dos números a continuación del separador. El último número se redondeará en función del siguiente valor utilizando el conocido método 4 al suelo, 5 al cielo.
En este ejemplo, la salida sería: pi = 3.14
Cómo ejecutar pruebas automatizadas para tus juegos con Unity Test Framework
Debug.Assert() es similar al método Debug.Log(), pero en lugar de registrar un mensaje en la consola, comprueba una condición y muestra un mensaje de error si la condición es falsa. Sirve para validar hipótesis y detectar errores durante el desarrollo.
Las aserciones son una buena forma de comprobar que tu programa no entra en un estado inesperado. Son como incrustar un Log dentro de una sentencia if. Cuando se trabaja en un método que depende de la asignación de una propiedad de la clase, una aserción puede ayudar a localizar errores.
Cuando se llama a Debug.Assert(), toma dos parámetros: una condición a probar y un mensaje opcional a mostrar si la condición es falsa. Si la condición es verdadera, no ocurre nada y el programa continúa ejecutándose. Si la condición es falsa, el programa deja de ejecutarse y se muestra un mensaje de error en el Editor.
void SetColor(Color color)
{
Debug.Assert(material != null, "CambiarColor: material no asignado");
material.SetColor("_Color", color);
}
Si llama a SetColor y el material no está asignado, se mostrará 'SetColor: material no asignado' en la Consola.
Debug.Break() es un método proporcionado por la clase Debug de Unity que se utiliza para pausar la ejecución de su juego y entrar en el depurador en el punto actual de su código. Te permite inspeccionar el estado de tu juego y recorrer tu código línea por línea para encontrar y corregir errores.
Cuando se llama a Debug.Break(), se detiene la ejecución del juego y se abre la ventana Debugger. Esto le permite examinar el estado de su juego y depurar su código según sea necesario. Puede utilizar el depurador para recorrer el código, establecer puntos de interrupción e inspeccionar variables y objetos en memoria.
Por ejemplo, es posible que desee detener un juego cuando un NPC se encuentra dentro de la distancia objetivo del personaje del jugador. Cuando el juego se rompe, puedes examinar su estado en el Inspector:
float dist = Vector3.Distancia(transform.posición, npc.posición);
if ( dist < 5) Debug.Break();
Debug.DrawLine y Debug.DrawRay son dos métodos proporcionados por la clase Debug de Unity que son utilizados para depuración visual. Son útiles para probar y visualizar código relacionado con la física, como colisiones y emisiones de rayos. Ambos permiten dibujar una línea de color que es visible tanto en la vista Juego como en la vista Escena. Por ejemplo, puedes utilizar Debug.DrawRay para visualizar la trayectoria de una bala o el recorrido de un rayo láser y utilizar Debug.DrawLine para visualizar los límites de un colisionador o el movimiento de un objeto.
Debug.DrawLine se utiliza para dibujar una línea recta entre dos puntos de la escena:
Debug.DrawLine(transform.position, target.position, Color.white, 0, false);
Toma de dos a cinco parámetros: un punto inicial, un punto final y un color opcional. Por ejemplo, el siguiente código dibujaría una línea blanca entre los puntos inicial y final:
public static void DibujarLínea(Vector3 inicio, Vector3 fin, Color color = Color.blanco, float duración = 0.0f, bool depthTest = true);
Parámetros
- empezar: Punto del espacio mundial donde debe comenzar la línea
- fin: Punto del espacio mundial donde debe terminar la línea
- color: El color de la línea
- duración: Tiempo en segundos para mostrar la línea. 0 muestra la línea para una sola trama
- depthTest: En caso de que la línea esté oculta por objetos en primer plano
En el ejemplo de código, el método Update de un script MonoBehaviour adjunto al GameObject Skeleton resulta en la imagen vista arriba. La línea sólo es visible en la vista Juego si los gizmos están activados. Haz clic en el botón Gizmo situado en la parte superior derecha del panel de vista Juego para activarlos. La línea también es visible en la vista Escena.
La alternativa a DrawLine es DrawRay. Debug.DrawRay se utiliza para dibujar un rayo en la escena, partiendo de un origen especificado y extendiéndose en una dirección especificada. Por defecto, es un rayo infinito. Cuando el rayo dibujado por Debug.DrawRay() golpea un colisionador, se detendrá en el punto de intersección y no continuará más allá. Este comportamiento es el mismo que el de un raycast en Unity, utilizado para detectar colisiones entre objetos en una escena.
Aquí, el segundo parámetro define la dirección y la longitud de la línea. La línea se trazará de inicio a inicio + dir:
public static void DrawRay(Vector3 start, Vector3 dir, Color color = Color.white, float duration = 0.0f, bool depthTest = true);
Los parámetros en el ejemplo de código son:
- empezar: Punto del espacio mundial donde debe comenzar la línea
- dir: Dirección y longitud en el espacio mundial de la línea
- color: El color de la línea
- duración: Tiempo en segundos para mostrar la línea; 0 muestra la línea para una sola trama
- depthTest: En caso de que la línea esté oculta por objetos en primer plano
He aquí otro ejemplo de código:
Vector3 dir = transform.TransformDirection(Vector3.forward) * 3;Debug.DrawRay(transform.position, dir, Color.white, 0, false);
En este ejemplo de código, el método Update de un script MonoBehaviour adjunto al GameObject Skeleton resulta en la imagen de arriba. Un rayo con una longitud puede ser útil para depurar pruebas de proximidad. Aquí, la longitud del rayo es de 3 unidades de mundo. Si un ataque debe comenzar a las 3 unidades, entonces tienes una gran prueba visual de cuánto tiempo son 3 unidades en tu escena.
Consejos para probar y garantizar la calidad de los proyectos Unity
Los Gizmos son una poderosa herramienta para la depuración visual en Unity. Permiten dibujar formas sencillas en 2D y 3D, líneas y texto en la vista de escena, lo que facilita ver y comprender lo que ocurre en el mundo del juego.
Puede dibujar formas y líneas sencillas en la vista Escena con sólo unas líneas de código. Esto las convierte en una herramienta ideal para crear prototipos y probar rápidamente la mecánica de tus juegos. Se dibujan en tiempo real, para que pueda ver inmediatamente los resultados de sus cambios de código y realizar las modificaciones necesarias.
Los gizmos indican mecánicas de juego visualmente complejas que podrían ser difíciles de entender sólo a través del código. Por ejemplo, puede utilizar Gizmos para dibujar una línea que muestre la trayectoria de un proyectil o para visualizar los límites de una zona de disparo, como se ve en la imagen anterior.
Utiliza artilugios para crear ayudas visuales que faciliten a los demás miembros del equipo la comprensión de tu código y la mecánica del juego.
Los artilugios tienen poco impacto en el rendimiento, por lo que puedes utilizarlos libremente sin ralentizar el rendimiento.
El icono del gizmo se encuentra en la esquina superior derecha de las vistas Escena y Juego. Para añadir un gizmo personalizado, es necesario añadir un script que incluya una llamada de retorno OnDrawGizmos, como muestra el siguiente ejemplo de código. Este script dibujará un cubo wireframe posicionado 3 unidades de mundo adelante de la posición del GameObject. El tamaño del cubo viene definido por la propiedad de clase vsize del tipo Vector3: public Vector3 vsize = new Vector3(1f, 1f, 1f);
void OnDrawGizmos()
{
// Dibuja una esfera amarilla en la posición de la transformación
Gizmos.color = Color.yellow;
Vector3 position = transform.position + transform.TransformDirection(Vector3.forward) * 3;
Gizmos.DrawWireCube(position, vsize);
}
Controla la visibilidad haciendo clic en el desplegable de artilugios. Se listarán todos los scripts que tengan una llamada de retorno OnDrawGizmos.
Revisa la documentación para aprender más sobre otros métodos útiles con la clase Gizmo.
Lanzar una excepción es una técnica utilizada en programación para indicar que se ha producido un error o una situación excepcional durante la ejecución de un programa. Puede utilizar este método para detener la ejecución del hilo y evitar daños mayores.
En Unity, lanzar una excepción se utiliza de la misma manera que en otros lenguajes de programación.
Si se lanza una excepción y no es capturada y manejada en el código, la ejecución del programa normalmente se detendrá y serás lanzado fuera de la aplicación y de vuelta al sistema operativo. En Unity, la ejecución del programa se detiene inmediatamente y el entorno de ejecución busca un bloque "catch" que pueda manejar la excepción. Si no se encuentra ningún bloque catch, el programa terminará y la excepción se registrará en la consola.
Lanzar excepciones puede ser útil, ya que permite separar la lógica de gestión de errores del resto de la lógica del programa, lo que puede contribuir a escribir un código más limpio. Al lanzar excepciones, puede indicar a la persona que llama que algo ha ido mal sin tener que depender de los valores de retorno o del estado global para comunicar el error.
Para lanzar una excepción en Unity, usted puede usar la palabra clave throw seguida por un objeto de excepción. He aquí un ejemplo:
si (objetivo == null)
{
lanza una nueva System.NullReferenceException("¡objetivo no fijado!");
}
Cuando ejecuta su código en el Editor, captura los errores lanzados y hace un Debug.LogError() en lugar de bloquear Unity o la aplicación.
El uso de excepciones en Unity le permite atrapar errores tempranamente. También puede facilitar la depuración al proporcionarle más información sobre dónde se producen los errores y qué los ha provocado.
Aprende mucho más sobre pruebas, depuración y mejora del rendimiento de tu proyecto Unity en estos artículos:
- Cómo depurar código de juegos con Roslyn Analyzers
- Cómo ejecutar pruebas automatizadas para tus juegos con Unity Test Framework
- Acelere el flujo de trabajo de depuración con Microsoft Visual Studio Code
- Cómo depurar el código con Microsoft Visual Studio 2022
- Consejos para probar y garantizar la calidad de los proyectos Unity
Profundice en las mejores prácticas e instrucciones avanzadas para desarrolladores de Unity con estos libros electrónicos:
- Guía avanzada sobre la generación de perfiles de juegos de Unity
- Optimiza el rendimiento de tu juego para móviles
- Optimiza el rendimiento de tus juegos de consola y PC
Encontrará muchos más recursos avanzados en el centro de mejores prácticas de Unity.