Consejo rápido: pausa, cámara lenta y doble tiempo en Unity
Spanish (Español) translation by Steven (you can also view the original English article)
Pausar un juego de Unity es fácil. Hay un par de cosas que debes tener en cuenta, pero las veremos al final de este consejo. Vamos a agregar algunos botones de GUI simples para controlar el tiempo dentro de un proyecto básico de Unity.
Vista previa del resultado final
Echemos un vistazo al resultado final en el que trabajaremos:
Paso 1: Crear un nuevo proyecto
Comencemos abriendo Unity y creando un nuevo proyecto. Es posible que desees agregar algún tipo de animación o algún tipo de acción a los procedimientos, para que puedas ver realmente un efecto cuando presionamos los botones. En el ejemplo proporcionado, acabo de hacer algunos cubos giratorios simples.
Abrir un nuevo proyecto es agradable y sencillo. Una vez que Unity haya terminado de cargarse, si lo tienes configurado para mostrar el Asistente de Proyectos, puedes hacer clic en la pestaña 'Crear nuevo proyecto' e ingresar un nombre de archivo. Unity se encargará del resto. Si la ventana del Asistente para proyectos no aparece al iniciar Unity, ve a Archivo > Nuevo proyecto.

Paso 2: Crear un nuevo script de JavaScript
Unity tiene su propio sistema GUI integrado, que va mucho más allá de lo que veremos aquí. Digamos que todo lo que sucede en la interfaz gráfica de usuario, es debido a una función llamada OnGUI y la clase GUI; ya que estas proporcionan un montón de cosas interesantes, como un botón.
Continúa y crea un nuevo script a través del menú Recursos - selecciona Recursos > Crear > JavaScript:


Tu nuevo script debería aparecer en la ventana del Proyecto. Haz clic una vez en el script y debería resaltarse para que puedas cambiarle el nombre. Nombra el script como "PauseScript" y presiona Enter. Ahora queremos comenzar a codificar, así que adelántate y haz doble clic esta vez. Eso debería abrir el editor predeterminado del script con la plantilla/código por defecto en Unity. Una vez que se carga el editor de scripts, elimina el código predeterminado y reemplázalo con el siguiente código:
1 |
|
2 |
function OnGUI() { |
3 |
// show a 'pause' button
|
4 |
if(GUI.Button(Rect(0,0,120,30),"TOGGLE PAUSE")){ |
5 |
// call our toggle function
|
6 |
doPauseToggle(); |
7 |
}
|
8 |
}
|
GUI.Button requiere un Rect (que contiene el x, y, ancho y alto de nuestro botón) y la cadena para mostrar dentro de él. Averiguar si se ha presionado o no el botón es tan simple como poner nuestro método GUI de dibujo en la declaración if de los botones.
Paso 3: Codificación de la función para alternar la pausa
Aquí, nos referimos a una función que llamaremos doPauseToggle(). Esta será una función simple que verifica si estamos en pausa o no, luego realiza la acción correcta. Agrega el siguiente código a la parte inferior de tu script PauseScript.js, debajo de la función OnGUI que agregamos en el paso 2:
1 |
|
2 |
function doPauseToggle() { |
3 |
// here we check to see if we are running at a time scale above 0
|
4 |
if(Time.timeScale>0){ |
5 |
// time scale is above zero, so we need to pause the game here
|
6 |
pauseGame(); |
7 |
} else { |
8 |
// time scale was less than zero, so we unpause the game here
|
9 |
unPauseGame(); |
10 |
}
|
11 |
}
|
Time.timeScale es cómo hacemos que se pause el juego. Esencialmente, cambiamos la escala a la que pasa el tiempo. Cuando timeScale es 1.0, el tiempo es en tiempo real. En cero (0), el tiempo está en pausa. Entonces, en nuestra función doPauseToggle, simplemente verificamos si el tiempo es mayor que cero, o sea que no esté en pausa. Si es así, llamamos a una nueva función pauseGame(). De lo contrario, se llama a unPauseGame().
Paso 4: Codificando las funciones Pause y Un-pause
Las funciones en el Paso 3, pauseGame() y unPauseGame(), simplemente manipulan el valor Time.timeScale en 0 o 1. Agrega el siguiente código al final de su script PauseScript.js, debajo del código que agregamos en el paso 3:
1 |
function pauseGame () { |
2 |
// set scale at which time passes to 0, freezing time(!)
|
3 |
Time.timeScale=0; |
4 |
}function unPauseGame () { |
5 |
// set scale at which time passes to 1, running at realtime again
|
6 |
Time.timeScale=1; |
7 |
}
|
Lo creas o no, eso es todo lo que necesitamos hacer para agregar un botón de pausa a un archivo de Unity. Si tienes alguna acción en tu escena de Unity, ¡ahora verás que se detiene y se detiene cada vez que hacemos clic en el botón! Ten en cuenta que si no tienes nada en tu escena, no verás que suceda nada cuando presiones en el botón.
Paso 5: Moverse en cámara lenta
¿Estás pensando lo que estoy pensando? Si 0 hace una pausa y 1 lo hace funcionar, ¿qué pasa con 0.5? ¡Piensas en el tiempo de una bala!
Primero, vamos a continuar y agreguemos un nuevo botón a nuestra función OnGUI(). Suelta esto en la parte inferior de la función, justo encima de la llave de cierre }.
1 |
// show a 'slowmo' button
|
2 |
if(GUI.Button(Rect(0,30,80,30),"SLOWMO")){ |
3 |
// call our toggle function
|
4 |
slowMo(); |
5 |
}
|
Ahora necesitamos una nueva función para ajustar el factor de tiempo a menos de 1. Desplázate hacia abajo hasta la parte inferior de tu script PauseScript.js y agrega esta nueva función:
1 |
function slowMo () { |
2 |
// set scale at which time 5asses to 0.1, running in slowmo
|
3 |
Time.timeScale=0.1; |
4 |
}
|
...¡demostrando así que no tienes que ser Neo para ver el tiempo de un bala en Unity!
Paso 6: ¡Tiempo doble!
Finalmente, por diversión, hagamos que todo se vuelva un poco loco jugando en el doble de tiempo. Aunque no he visto que esto se use en una mecánica de juego real, he visto escalar el tiempo temporalmente para poner en marcha un efecto de partículas: era un efecto de fuego y el autor quería que la pantalla se llenara de fuego rápidamente para mostrar el fondo de su pantalla del menú. Él aumentó el tiempo por un segundo luego de que el menú se cargó y el fuego llenó la pantalla. Luego redujo el tiempo a 1 para que las llamas se moviera correctamente y todo lo demás en el juego estuviera a velocidad regular.
Para agregar el doble de tiempo, seguiremos el mismo procedimiento que en el paso 5, agregando un nuevo botón que llamará a una nueva función. La nueva función simplemente establecerá nuestra escala de tiempo en 2. Busca la función OnGUI() en tu script PauseScript.js y agrega lo siguiente, arriba del final de la función y arriba de la llave de cierre }.
1 |
// show a 'double time' button
|
2 |
if(GUI.Button(Rect(0,60,120,30),"DOUBLE TIME")){ |
3 |
// call our toggle function
|
4 |
doubleTime(); |
5 |
}
|
Listo. Tenemos un botón, vamos a añadirle esa función doubleTime():
1 |
function doubleTime () { |
2 |
// set scale at which time passes to 0.5, running in slowmo
|
3 |
Time.timeScale=2; |
4 |
}
|
Para divertirte, intenta ajustar el timeScale hasta 100 y mira lo que sucede.
Echemos un vistazo a todo nuestro script. Aquí está el PauseScript.js por completo en caso de que algo malo haya sucedido en el trayecto.
1 |
function OnGUI() { |
2 |
// show a 'pause' button
|
3 |
if(GUI.Button(Rect(0,0,120,30),"TOGGLE PAUSE")){ |
4 |
// call our toggle function
|
5 |
doPauseToggle(); |
6 |
}
|
7 |
// show a 'slowmo' button
|
8 |
if(GUI.Button(Rect(0,30,80,30),"SLOWMO")){ |
9 |
// call our toggle function
|
10 |
slowMo(); |
11 |
}
|
12 |
// show a 'double time' button
|
13 |
if(GUI.Button(Rect(0,60,120,30),"DOUBLE TIME")){ |
14 |
// call our toggle function
|
15 |
doubleTime(); |
16 |
}
|
17 |
}
|
18 |
|
19 |
function doPauseToggle() { |
20 |
// here we check to see if we are running at a time scale above 0
|
21 |
if(Time.timeScale>0){ |
22 |
// time scale is above zero, so we need to pause the game here
|
23 |
pauseGame(); |
24 |
} else { |
25 |
// time scale was less than zero, so we unpause the game here
|
26 |
unPauseGame(); |
27 |
}
|
28 |
}
|
29 |
|
30 |
function pauseGame () { |
31 |
// set scale at which time passes to 0, freezing time(!)
|
32 |
Time.timeScale=0; |
33 |
}
|
34 |
|
35 |
function unPauseGame () { |
36 |
// set scale at which time passes to 1, running at realtime again
|
37 |
Time.timeScale=1; |
38 |
}
|
39 |
|
40 |
function slowMo () { |
41 |
// set scale at which time passes to 0.1, running in slowmo
|
42 |
Time.timeScale=0.1; |
43 |
}
|
44 |
|
45 |
function doubleTime () { |
46 |
// set scale at which time passes to 0.5, running in slowmo
|
47 |
Time.timeScale=2; |
48 |
}
|
¡Unas últimas palabras y un par de cosas!
Es importante tener en cuenta que Time.timeScale no afectará al código dentro de una función Update(). La actualización tiene lugar cada "instante" y ocurre fuera de la escala de tiempo, por lo que si necesitas que las cosas sucedan a medida que el juego está en pausa, como una animación en segundo plano, el lugar para ponerlo es más probable en Update. Consulta la documentación de Unity para obtener más información sobre esto.
Ten en cuenta que si cambias el valor de Time.timeScale, cualquier acción relacionada con el tiempo, como las llamadas a la función Invoke o cualquier temporizador que use valores de Time.time, también se verá afectada por el cambio. Si tu juego se ejecuta al doble de la velocidad, tendrás que reducir a la mitad la velocidad de tus acciones basadas en el tiempo (por ejemplo, si tienes un juego de carreras con un temporizador de vueltas y tu Time.timeScale está configurado en 2.0, deberás reducir la velocidad del temporizador de vuelta a la mitad para que puedas medir con precisión el tiempo).
Las reacciones físicas no se ven directamente afectadas, por lo que tu juego debería ejecutarse como normalmente lo haría con colisiones y física, solo en una escala de tiempo diferente.
¡Eso es! Gracias por leer mi consejo rápido. Juega con Time.timeScale y espero ver efectos geniales tipo Matrix en tus proyectos. ¡Diviértete haciendo juegos!




