Version: 2017.2
Event Functions (Funciones de Evento)
Creando y destruyendo GameObjects.

Administrador del Tiempo y Framerate

La función Update le permite a usted monitorear inputs y otros eventos regularmente desde un script y tomar una acción apropiada. Por ejemplo, usted podría mover un personaje cuando la tecla “hacia adelante” esté presionada. Una cosa importante para acordarse cuando maneje acciones basadas en el tiempo coomo ésta es que el framerate del juego no es constante y tampoco lo es el periodo de tiempo entre llamados de funciones Update.

Un ejemplo de esto, considere la tarea de mover un objeto gradualmente hacia adelante, un cuadro a la vez. Podría parecer a primera que usted puede simplemente trasladar el objeto por una distancia fija cada cuadro:

//C# script example
using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    public float distancePerFrame;
    
    void Update() {
        transform.Translate(0, 0, distancePerFrame);
    }
}


//JS script example
var distancePerFrame: float;

function Update() {
    transform.Translate(0, 0, distancePerFrame);
}

Sin embargo, dado que el tiempo de cuadros (frame time) no es constante, el objeto va a aparecer moverse a una velocidad irregular. Si el frame time es 10 mili-segundos entonces el objeto se moverá hacia adelante por distancePerFrame cien veces por segundo. Pero, si el tiempo aumenta a 25 mili-segundos (debido a una sobrecarga de CPU, digamos) entonces solo va a ir hacia adelante cuarenta veces por segundo y por lo tanto va a cubrir menos distancia. La solución es escalar el tamaño del movimiento por el frame time que usted puede leer desde la propiedad Time.deltaTime:

//C# script example
using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    public float distancePerSecond;
    
    void Update() {
        transform.Translate(0, 0, distancePerSecond * Time.deltaTime);
    }
}


//JS script example
var distancePerSecond: float;

function Update() {
    transform.Translate(0, 0, distancePerSecond * Time.deltaTime);
}

Tenga en cuenta que el movimiento es ahora dado en distancePerSecond en vez de distancePerFrame. A medida que el framerate cambia, el tamaño de la etapa de movimiento cambiará de acuerdo y así la velocidad del objeto será constante.

Fixed Timestep (Timestep fijo)

A diferencia de la actualización principal del cuadro, el sistema de física de Unity funciona a un timestep fijo, el cual es importante para la precisión y consistencia de la simulación. Al comienzo de la actualización de física, Unity configura una “alarma” al agregar el valor del timestep fijo al tiempo dónde termino la última actualización de física. El sistema de física luego va a realizar cálculos hasta que la alarme se apague.

Usted puede cambiar el tamaño del timestep fijo desde el Time Manager

Máximo Timestep Permitido

El timestep fijo sigue la simulación de física de manera precisa en tiempo real pero puede causar problemas en casos dónde el juego hace un uso fuerte de física y el framerate del gameplay puede también volverse bajo (debido a un gran número de objetos en reproducción, digamos). El procesamiento de la actualización de cuadro(frame update) principal tiene que ser “apretado” entre las actualizaciones de física regulares y si hay mucho procesamiento entonces varias actualizaciones de física pueden tomar lugar durante un solo frame. Debido al frame time, posiciones de objetos y otras propiedades son congeladas en el comienzo del frame, las gráficas pueden perder sincronización con la actualización de física con más frecuencia.

Naturalmente, hay bastante poder de CPU disponible pero Unity tiene una opción que le permite a usted efectivamente disminuir el tiempo de física para permitir que el procesamiento de frame alcance. La configuración Maximum Allowed Timestep (en el Time Manager) pone un limite en la cantidad de tiempo Unity va a gastar procesando llamados de física y FixedUpdate durante un update (Actualización) del frame dado. Si una actualización del cuadro toma más que el Maximum Allowed Timestep para procesar, el motor de física va a “parar el tiempo” y le va a permitir al procesamiento de cuadros que alcance. Una vez la actualización de cuadro ha finalizado, la física va a resumir como si no hubiera pasado tiempo desde que paro. El resultado de esto es que los rigidbodies no se moverán perfectamente en el tiempo real como debería pero serán un poco más lentos. Sin embargo, el “reloj” de física va a comenzar hacer un seguimiento de estos como si se estuvieran moviendo de manera normal. La disminución del tiempo de física usualmente no se nota y es un cambio aceptable contra el rendimiento del gameplay.

Time Scale (Escala del tiempo)

Para efectos especiales, como “bullet-time”, a veces es útil disminuir el tiempo de juego para que las animaciones y respuestas de script ocurran en una velocidad reducida. Adicionalmente, usted podría querer a veces congelar el tiempo del juego completamente, como cuando el juego es pausado. Unity tiene una propiedad Time Scale que controla qué tan rápido el tiempo de juego ocurre relativo al tiempo real. Si la escala está configurada a 1.0 entonces el tiempo de juego concuerda con el tiempo real. Un valor de 2.0 hace que el tiempo pase el doble de rápdio que en Unity (ie, la ación va a aumentar) mientras un valor de 0.5 va a disminuir el gameplay a la mitad de la velocidad. Un valor de cero hará que el tiempo “pare” completamente. Tenga en cuenta que la escala del tiempo no disminuye la ejecuciónpero simplemente cambia el time step reportado a las funcones Update y FixedUpdate vía Time.deltaTime y Time.fixedDeltaTime. La función Update es probable que sea llamada más a menudo que o usual cuando el tiempo de juego ha sido disminuido pero el step de deltaTime reportado cada cuadro va a simplemente ser reducido. Otras funciones de sript no están afectadas por la escala de tiempo por lo que usted puede, por ejemplo, mostrar un GUI con una interacción normal cuando el juego esté pausado.

El Time Manager tiene una propiedad que le permite a usted configurar la escala de tiempo globalmente pero por lo general es más útil configurarlo al valor desde un script utilizando la propiedad Time.timeScale.

//C# script example
using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    void Pause() {
        Time.timeScale = 0;
    }
    
    void Resume() {
        Time.timeScale = 1;
    }
}

//JS script example
function Pause() {
    Time.timeScale = 0;
}

function Resume() {
    Time.timeScale = 1;
}

Capture Framerate (Capturar el Framerate)

Un caso muy especial del time management (administrador de tiempo) es dónde usted quiere grabar el gameplay como un video. Debido a que la tarea de guardar las imágenes de pantalla toman un tiempo considerable, el framerate usual del juego será drásticamente reducido si usted intenta hacer esto durante un gameplay normal. Esto dará como resultado en un video que no refleja el rendimiento verdadero del juego.

Afortunadamente, Unity proporciona una propiedad Capture Framerate que le permite a usted solucionar este problema. Cuando el valor de la propiedad es configurado a cualquier cosa en vez de cero, el game time (tiempo de juego) será reducido y las actualizaciones de cuadro serán emitidas en intervalos regulares preciso. El intervalo entre cuadro es igual a 1 / Tiempo.captureFramerate, entonces si el valor es configurado a 5.0 entonces las actualizaciones ocurren cada quinto de segundo. Con las demanda de framerate efectivamente siendo reducida, usted tiene el tiempo en la función Update para guardar capturas de pantalla o realizar otras acciones:

//C# script example
using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    // Capture frames as a screenshot sequence. Images are
    // stored as PNG files in a folder - these can be combined into
    // a movie using image utility software (eg, QuickTime Pro).
    // The folder to contain our screenshots.
    // If the folder exists we will append numbers to create an empty folder.
    string folder = "ScreenshotFolder";
    int frameRate = 25;
        
    void Start () {
        // Set the playback framerate (real time will not relate to game time after this).
        Time.captureFramerate = frameRate;
        
        // Create the folder
        System.IO.Directory.CreateDirectory(folder);
    }
    
    void Update () {
        // Append filename to folder name (format is '0005 shot.png"')
        string name = string.Format("{0}/{1:D04} shot.png", folder, Time.frameCount );
        
        // Capture the screenshot to the specified file.
        Application.CaptureScreenshot(name);
    }
}

//JS script example

// Capture frames as a screenshot sequence. Images are
// stored as PNG files in a folder - these can be combined into
// a movie using image utility software (eg, QuickTime Pro).
// The folder to contain our screenshots.
// If the folder exists we will append numbers to create an empty folder.
var folder = "ScreenshotFolder";
var frameRate = 25;


function Start () {
    // Set the playback framerate (real time will not relate to game time after this).
    Time.captureFramerate = frameRate;

    // Create the folder
    System.IO.Directory.CreateDirectory(folder);
}

function Update () {
    // Append filename to folder name (format is '0005 shot.png"')
    var name = String.Format("{0}/{1:D04} shot.png", folder, Time.frameCount );

    // Capture the screenshot to the specified file.
    Application.CaptureScreenshot(name);
}

Aunque el video grabado utilizando esta técnica típicamente se ve muy bien, el juego puede ser difícil de reproducir cuando es disminuido drasticamente. Usted puede necesitar experimentar con el valor de Time.captureFramerate para permitirle a usted un tiempo de grabación más amplia sin excesivamente complicar la tarea del reproductor prueba.

Event Functions (Funciones de Evento)
Creando y destruyendo GameObjects.