Diferencia entre revisiones de «UNITY Operaciones sobre objetos 3D»

De MediaWiki
Ir a la navegación Ir a la búsqueda
Línea 369: Línea 369:
  
  
 +
[[Imagen:Unity3d_mov_2.JPG|500px|center]]
  
  
 +
: Como vemos hemos movido el GameObject cubo a la posición indicada.
 +
 +
 +
* Podemos hacer que cualquier propiedad aparezca gráficamente en Unity estableciendo el tipo de acceso a public. Así, en nuestro caso podemos establecer las tres propiedades para que gráficamente puedan ser modificadas de la forma:
 +
 +
<syntaxhighlight lang="java" line highlight="">
 +
public class UD_Movim_basico_1 : MonoBehaviour {
 +
 +
    public Vector3 posInicial = new Vector3(0, 0, 0);
 +
    public Vector3 rotInicial = new Vector3(0, 0, 0);
 +
    public Vector3 escalaInicial = new Vector3(1, 1, 1);    // La escala no debería ser 0
 +
 +
    // Use this for initialization
 +
    void Start () {
 +
        transform.position = posInicial;
 +
        transform.Rotate(rotInicial);
 +
        transform.localScale = escalaInicial;
 +
    }
 +
 +
    // Update is called once per frame
 +
    void Update () {
 +
 +
    }
 +
}
 +
</syntaxhighlight>
 +
 +
 +
[[Imagen:Unity3d_mov_3.JPG|500px|center]]
 +
 +
 +
: Ahora podemos modificar los valores iniciales.
 +
 +
* '''<u>Nota:</u>''' El recurso de hacer public a propiedades se puede aplicar a cualquier propiedad en Unity. Por ejemplo, podríamos tener una propiedad que fuera un GameObject o un objeto de la clase Transform. De esta forma podríamos arrastrar gráficamente cualquier objeto y llevarlo al Inspector, copiándose todas sus propiedades.
 +
 +
 +
 +
* Ahora ha llegado el momento de hacer que el cubo se mueva. Como suponéis, debemos de modificar el valor de uno de los ejes.
 +
: El método donde se debe de escribir el código es el '''método Update'''.
 +
 +
: A dicho método se llama de forma continuada desde que comienza el juego.
 +
 +
<syntaxhighlight lang="java" line highlight="7,17-27">
 +
public class UD_Movim_basico_1 : MonoBehaviour {
 +
 +
    public Vector3 posInicial = new Vector3(0, 0, 0);
 +
    public Vector3 rotInicial = new Vector3(0, 0, 0);
 +
    public Vector3 escalaInicial = new Vector3(1, 1, 1);    // La escala no debería ser 0
 +
 +
    public float posFinalX = 5;
 +
 +
    // Use this for initialization
 +
    void Start () {
 +
        transform.position = posInicial;
 +
        transform.Rotate(rotInicial);
 +
        transform.localScale = escalaInicial;
 +
    }
 +
 +
    // Update is called once per frame
 +
    void Update () {
 +
 +
        if (transform.position.x <= posFinalX)
 +
        {
 +
            Vector3 temp = transform.position;
 +
            temp.x += .5f;
 +
            transform.position = temp;
 +
        }
 +
 +
 +
    }
 +
}
 +
</syntaxhighlight>
 +
 +
* Si ejecutáis el código veréis como el cubo se mueve rápidamente hacia posición indicada por la variable 'posFinalX'.
 +
 +
[[Imagen:Unity3d_mov_3.JPG|500px|center]]
 +
 +
 +
* El problema que tenemos es que no tenemos '''control de la velocidad'''.
 +
: Necesitamos <u>comprender el concepto del parámetro '''delta'''</u>
 +
 +
 +
* Lo que tenemos que tener que claro que cualquier movimiento se produce '''borrando toda la pantalla''' y volviéndola a dibujar.
 +
: Lo que pasa es que se hace tan rápido que para nuestros ojos solo se tiene la impresión del movimiento.
 +
 +
* La rapidez con que se borra todo y se vuelve a dibujar la establecemos mediante un parámetro denominado '''Fotogramas Por Segundo''' (fps).
 +
: Este parámetro va a depender de la máquina donde se ejecute el juego (capacidades hardware de la misma, como procesador, tarjeta gráfica,...) y de lo optimizado que esté nuestro juego.
 +
 +
 +
* Al depender de la máquina, no podemos hacer que los elementos del juego se muevan sin ningún control, ya que con el código anterior, en una máquina a 60fps se movería mucho más rápido que en una máquina a 30fps. '''Debemos hacer que la velocidad del movimiento sea <u>independiente</u> del tipo de máquina'''.
 +
 +
: Eso lo conseguimos con el parámetro '''delta'''.
 +
 +
* '''delta''' es el tiempo que transcurre desde que se llama a un método y vuelve a llamarse al mismo método.
 +
: La forma de obtener dicho valor es mediante la [https://docs.unity3d.com/ScriptReference/Time.html clase Time].
 +
 +
* Imaginemos que tenemos dos dispositivos Android, uno funcionando a 60fps y otro a 30fps.
 +
: Esto quiere decir que (más o menos) se va a llamar al método Update ese número de veces por segundo.
 +
: Si ejecutamos este código para mover el cubo:
 +
syntaxhighlight lang="java" line highlight="">
 +
    void Update () {
 +
      if (transform.position.x<100){
 +
        Vector3 temp = transform.position;
 +
        temp.x += 1f;
 +
        transform.position = temp;
 +
      }
 +
    }
 +
</syntaxhighlight>
 +
 +
* Como vemos se va a mover mientras X sea menor que 100 unidades.
 +
 +
Como temos no noso xogo un ancho de 300 unidades.
 +
 +
Vai suceder que:
 +
 +
    Máquina1:
 +
 +
        60fps => móvese 60 unidades por segundo => Tarda 300/60 en percorrer toda a pantalla => 5 segundos.
 +
 +
    Máquina2:
 +
 +
        30fps => móvese 30 unidades por segundo => Tarda 300/30 en percorrer toda a pantalla => 10 segundos.
 +
 +
Polo tanto moveríase máis rápido na primeira máquina e non parece moi xusto :).
 +
 +
Como podemos facer para que o movemento sexa independente do hardware da máquina ? Pois multiplicando a velocidade por delta, sendo delta o tempo que tarda en chamar ó método de actualización da posición.
 +
 +
 +
Por exemplo, seguindo o caso anterior:
 +
 +
    Máquina1: a 60 fps. Quere dicir que chama 60 veces nun segundo ó método update.
 +
 +
    Delta = 1/60
 +
    posición.x = posición.x + (1 * delta) :multiplicamos a velocidade por delta. Estamos a poñer unha velocidade de 1 unidade por segundo. Lembrar que o noso mundo mide 300 unidades de ancho.
 +
 +
    Canto tempo tarde en percorrer o noso mundo ?
 +
 +
    Nun segundo percorre:
 +
 +
        60 (fps = veces por segundo) * 1/60 (é delta) * 1 (a velocidade) = 1.
 +
        Polo tanto vai sumar unha unidade á posición x cada segundo.
 +
 +
        O noso mundo mide 300 unidades = 300 segundos.
 +
 +
 +
    Máquina2: a 30 fps. Quere dicir que chama 30 veces nun segundo ó método update.
 +
 +
    Delta = 1/30
 +
    posición.x = posición.x + (1 * delta) :multiplicamos a velocidade por delta. Estamos a poñer unha velocidade de 1 unidade por segundo. Lembrar que o noso mundo mide 300 unidades de ancho.
 +
 +
    Canto tempo tarde en percorrer o noso mundo ?
 +
 +
    Nun segundo percorre:
 +
 +
        30 (fps = veces por segundo) * 1/30 (é delta) * 1 (a velocidade) = 1.
 +
        Polo tanto vai sumar unha unidade á posición x cada segundo.
 +
 +
        O noso mundo mide 300 unidades = 300 segundos.
 +
 +
Como vemos tarda o mesmo. O que está facendo é axustar, diminuíndo a velocidade do en función de delta. Se delta é máis grande (chama moitas veces por segundo) fai que se mova máis lentamente.
  
  

Revisión del 11:03 27 jul 2018

Introducción

  • A todo objeto 3D se le pueden aplicar tres operaciones:
  • Escalado: Hacerlo más grande. Podemos hacerlo más grande en todos los ejes (x,y,z) o solo en alguno de ellos, provocando deformaciones.
  • Rotación: Podemos rotarlo en cualquiera de los tres ejes (x,y,z)
  • Traslación: Podemos trasladar el objeto en cualquiera de los tres ejes (x,y,z). Esto es, moverlo.


  • Como comentamos anteriormente, toda figura 3D se dibuja en el punto (0,0,0) y después se le aplican unas modificaciones para visualizarlo en la posición y forma correctas.
Esto es posible gracias a una serie de operaciones matemáticas con matrices.
Cada uno de los objetos 3D tiene asociado una matriz de modelado (una matriz matemática de 4x4).
Inicialmente, cuando dibujamos un objeto 3D se dibuja en el punto 0,0,0 y sin rotación ya que su matriz de modelado es la matriz identidad. Dicha matriz tiene unos en una de las diagonales.
Cuando indicamos que el objeto se tiene que desplazar, rotar o escalar, estamos modificando su matriz de modelado (para nosotros es transparente) y una vez modificada, se aplica dicha matriz sobre cada uno de los puntos del objeto 3D y por eso se dibuja en la posición correcta, con la escala y con la rotación indicada.



LIBGDX UD4 Animacion 4.jpg



  • En Unity3D accedemos a esta matriz en la ventana de Inspector, bajo la sección Transform:
Unity3d operaciones 1.jpg




Escalado

  • En la siguiente imagen podéis observar un cubo que mide 1x1x1 unidades (fijaros en la cuadrícula).
Unity3d escala 1.jpg


  • Al pulsar sobre el cubo aparece en el Window Inspector las propiedades del gameobject seleccionado (en este caso el cubo).
Unity3d escala 2.jpg


  • Ahora podemos modificar la escala. Lo podemos hacer de varias formas:
  • Tecleando la nueva escala en la caja de texto correspondiente.
  • Poniendo el ratón en la ventana Inspector, encima del eje que queramos cambiar la escala y manteniendo presionado el botón izquierdo mover a derecha o izquierda.


  • Seleccionado en la barra de herramientas la opción de escala y después, gráficamente sobre la figura, presionar el botón izquierdo del ratón sobre uno de los ejes de colores y sin soltar, mover el ratón.


Rotación

  • Podemos rotar una figura en cualquiera de los tres ejes.
La rotación viene determinada por un número que representa la rotación en grados.
Así, 90 grados sería un cuarto de circunferencia de rotación, 180 sería la mitad y 360 una vuelta entera.


  • Al pulsar sobre el cubo aparece en el Window Inspector las propiedades del gameobject seleccionado (en este caso el cubo).
Unity3d rotacion 11.jpg


  • Para saber como se rota, debemos de tener en cuenta la siguiente regla.
Debemos imaginar que nuestra cabeza está atravesada por un palo, en cada uno de los ejes:



  • Veamos en ejemplo con una figura de un tigre:


  • Para rotar un objeto debemos de seleccionar en la Ventana de Escena (Scene Window).


  • Podemos rotar de varias formas:
  • Tecleando el valor en la caja de texto correspondiente.
Unity3d rotacion 10.jpg


  • Poniendo el ratón en la ventana Inspector, encima del eje que queramos aplicar la rotación y manteniendo presionado el botón izquierdo mover a derecha o izquierda.


  • Seleccionado en la barra de herramientas la opción de rotación y después, gráficamente sobre la figura, presionar el botón izquierdo del ratón sobre uno de los ejes de colores y sin soltar, mover el ratón.
Nota: No os extrañéis sin al modificar uno de los ejes veis que se modifica la posición. Eso es normal, ya que estamos moviendo la figura.


Traslación

  • Podemos trasladar (mover) un objeto 3D en cualquiera de sus tres ejes.
Lo que haremos será desplazarlo un número de unidades siendo cada unidad uno de los cuadrados de la rejilla que conforman el 'suelo' del entorno de Unity3D.


  • Al pulsar sobre el cubo aparece en el Window Inspector las propiedades del gameobject seleccionado (en este caso el cubo).
Unity3d trasladar 2.jpg


  • Podemos trasladarnos de varias formas:
  • Tecleando el valor en la caja de texto correspondiente.
Unity3d trasladar 1.jpg


  • Poniendo el ratón en la ventana Inspector, encima del eje sobre el que queramos aplicar la traslación y manteniendo presionado el botón izquierdo mover a derecha o izquierda.


  • Seleccionado en la barra de herramientas la opción de traslación y después, gráficamente sobre la figura, presionar el botón izquierdo del ratón sobre uno de los ejes de colores y sin soltar, mover el ratón.





Avanzado: Conceptos para programadores

  • Lo que viene a continuación son unas explicaciones teóricas para los alumnos que realizan el ciclo de Programación de aplicaciones multiplataforma.
  • Como comentamos anteriormente, las figuras 3D están formadas por múltiples triángulos.


  • Cuando se dibuja una figura 3D, la estamos dibujando siempre a partir del punto (0,0,0).
Posteriormente, se utiliza una matriz denominada matriz de modelado que se aplica sobre cada uno de los vértices de la figura para obtener el valor x-y-z una vez movida la figura, rotada y escalada.
Las operaciones anteriores (traslación, rotación y escalado) modifican la matriz de modelado.
  • Una vez la figura se encuentra en la posición correcta en nuestro mundo 3D es necesario dibujarla. Quien decide como se dibuja es una cámara (viene a ser nuestros ojos en el mundo real). Esta cámara posee otra matriz denominada matriz de proyección, la cual se aplica a cada uno de los vértices y de esa forma obtenemos los puntos x-y para dibujar nuestra figura en nuestro monitor.



Posición

  • Como ya comentamos anteriormente, las figuras están compuestas por múltiples triángulos están formados por 3 vértices.
  • Cuando se define una figura 3D (Mesh) indicamos la posición 3D (x,y,z) de cada vértice de cada triángulo (existen otras formas de aprovechar los vértices comunes y disminuir el número total de vértices).
LIBGDX UD4 Animacion 2.jpg


Esta posición se define con respecto al punto (0,0,0) Esto quiere decir que todas las figuras 3D se dibujan en dicho punto. Después dependiendo de la posición que queramos darles, se multiplican por unas matrices (matriz de modelado) para obtener las posiciones x-y-z de nuestro mundo 3D.


  • Como vimos anteriormente, las operaciones que podemos realizar sobre una figura 3D son las de: Traslación - Rotación - Escala.
Dichas operaciones van a modificar una matriz denominada matriz de modelado:
LIBGDX UD4 Animacion 4.jpg
La imagen anterior muestra la matriz de identidad (matriz con todos 1 en su diagonal) y que viene a ser como el número 1 en la multiplicación (no afecta al modelo).




Ejemplo de código utilizado en el framework LIBGDX

Ejemplo de definición de matriz:

1 public Matrix4 matriz;


Para cargar la matriz de identidad tenemos que llamar al método idt():

1 public Matrix4 matriz;
2 ..........
3 
4 matriz.idt();

Ahora será necesario aplicar los 3 tipos de operaciones:

  • Traslación:
Método translate:
Ejemplo: matriz.translate(posicion);
Siendo 'posicion' un Vector3 que indica hacia donde se tiene que trasladar.
Es importante comprender que siempre debemos de partir de la matriz identidad y aplicar la nueva posición a la que queremos llegar. No lo podemos hacer a partir de la última posición guardada.

Ejemplo de código:

1 public Matrix4 matriz;
2 ..........
3 matriz.idt();
4 matriz.translate(10,1,0);
  • Rotación:
Método rotate:
Este método está sobrecargado e tenemos varias posibilidades.

Un ejemplo:

1 public Matrix4 matriz;
2 ..........
3 matriz.idt();
4 matriz.translate(10,1,0);
5 matriz.rotate(1,0,0,90);

En este caso estaremos rotando en el eje X la figura 90º. En este caso o método rotate lleva cuatro parámetros:

  • param1: Indica se o eje X debe rotarse. Si tiene valor 1 lo rota y si tiene 0 no hace nada en ese eje.
  • param2: Indica se o eje Y debe rotarse. Si tiene valor 1 lo rota y si tiene 0 no hace nada en ese eje.
  • param3: Indica se o eje Z debe rotarse. Si tiene valor 1 lo rota y si tiene 0 no hace nada en ese eje.
  • param4: Indica el número de grados de la rotación.

Aviso: Es importante primero hacer la traslación y después la rotación, ya que si lo hacemos al revés, el punto está rotado cuando aplicamos la traslación y por tanto se moverá a otro lugar diferente al que queremos. Si lo aplicamos a una esfera, tendríamos un efecto de traslación alrededor del punto (0,0,0).


  • Escala:
Método scale:

Podemos modificar la escala en cada uno de los ejes (X-Y-Z).

Por exemplo:

1 public Matrix4 matriz;
2 ..........
3 matriz.idt();
4 matriz.translate(10,1,0);
5 matriz.rotate(1,0,0,90);
6 matriz.scale(2,1,1);

En este ejemplo indicamos que el tamaño X de la figura debe de ser el doble que el tamaño Y y Z.


  • Consultar ahora como realizar una animación en LIBGDX (sobre todo entender los conceptos de la matriz de proyección-modelado) y como se 'construye' un Mesh a partir de los vértices de sus triángulos: Enlace a animación 3D con LIBDX.




Ejemplo de código utilizado en el UNITY

  • Este es un ejemplo de código de un script de nombre PruebaMatrix4x4 asociado a una esfera:
 1 public class PruebaMatrix4x4 : MonoBehaviour {
 2     public Vector3 translation;
 3     public Vector3 eulerAngles;
 4     public Vector3 scale = new Vector3(1, 1, 1);
 5     private MeshFilter mf;
 6     private Vector3[] origVerts;
 7     private Vector3[] newVerts;
 8 
 9     void Start()
10     {
11         mf = GetComponent<MeshFilter>();
12         origVerts = mf.mesh.vertices;
13         newVerts = new Vector3[origVerts.Length];
14     }
15 
16     void Update()
17     {
18         Quaternion rotation = Quaternion.Euler(eulerAngles.x, eulerAngles.y, eulerAngles.z);
19         Matrix4x4 m = Matrix4x4.identity;
20         m.SetTRS(translation, rotation, scale);
21         int i = 0;
22         while (i < origVerts.Length)
23         {
24             newVerts[i] = m.MultiplyPoint3x4(origVerts[i]);
25             i++;
26         }
27         mf.mesh.vertices = newVerts;
28     }
29 }
Líneas 2-4: Son propiedades públicas y por tanto van a aparecer en la ventana 'Inspector' de Unity. Se definen los vectores para la posición, rotación y escala.
La rotación se define con ángulos Euler que es la forma más 'humana' de entenderlo. Internamente se guardan en un objeto de la clase Quaternion.
Línea 18: Definimos un objeto de la clase Quaternion para guardar la rotación del objeto en forma de ángulos de Euler.
Línea 19: Definimos la matriz de modelado igualándola a la matriz identidad.
Línea 20: Asignamos los tres vectores a la matriz.
Después de eso, el siguiente código aplica a cada uno del vértices del GameObject asociado los datos de la matriz.
Si ejecutáis el programa podéis ver como aparecen las propiedades public en el inspector y podéis modificar sus valores viendo como cambia la posición-escala-rotación de la esfera.




Manipular la posición en Unity

  • Nota: Vamos a partir de que a nivel de diseño tenéis un Cubo en la posición (0,0,0) con la cámara mirando hacia él.
Asociado a dicho cubo vamos a tener un script de nombre 'UD_Movim_basico_1.cs'.


Unity3d mov 1.JPG



  • Todo visto en los puntos anteriores sirve como información de qué es lo que hace realmente Unity.
  • Pero existe una forma mucho más sencilla (que es la que usaremos nosotros) para manejar los objetos.
Es haciendo uso de la clase Transform.
Todo objeto de Unity tiene un objeto de la clase Transform asociado.
Dicho objeto nos va a permitir modificar la rotación-escala-posición del objeto.


1         posicion = gameObject.transform.position;   // Aparece en Unity en la ventana Inspector debajo de la sección 'Transform'
2         rotacion = gameObject.transform.rotation;   // Aparece en Unity en la ventana Inspector debajo de la sección 'Transform'
3         escala = transform.localScale;              // No hace falta poner gameObject
  • IMPORTANTE: Lo que estamos guardando es una copia de los valores que guarda el GameObject. Por lo tanto si realizamos modificaciones tendríamos que volver a asignarlas a las propiedades del GameObject.
Recordar: Cada vez que hagáis uso de transform.position, transform.rotation y transform.localScale estáis trabajando sobre una copia y por tanto hacer esto: transform.position.Set(5,5,5) no modifica la posición del GameObject.


  • Si quisiéramos manipularlas, podemos hacerlo directamente de la forma:
(Escribir este código en el script 'UD_Movim_basico_1.cs' creado anteriormente)
 1     // Use this for initialization
 2     void Start () {
 3 
 4         transform.position = new Vector3(2,2,2);    // Mueve el gameobject a la posición (2,2,2)
 5         transform.Rotate(30, 45, 90);       // Rota 30º en X, 45º en Y 90º en Z
 6         transform.localScale = new Vector3(2, 2, 5);  // Escala por 2 en X e Y y por 5 en Z
 7     }
 8 
 9     // Update is called once per frame
10     void Update () {
11 
12     }


Unity3d mov 2.JPG


Como vemos hemos movido el GameObject cubo a la posición indicada.


  • Podemos hacer que cualquier propiedad aparezca gráficamente en Unity estableciendo el tipo de acceso a public. Así, en nuestro caso podemos establecer las tres propiedades para que gráficamente puedan ser modificadas de la forma:
 1 public class UD_Movim_basico_1 : MonoBehaviour {
 2 
 3     public Vector3 posInicial = new Vector3(0, 0, 0);
 4     public Vector3 rotInicial = new Vector3(0, 0, 0);
 5     public Vector3 escalaInicial = new Vector3(1, 1, 1);    // La escala no debería ser 0
 6 
 7     // Use this for initialization
 8     void Start () {
 9         transform.position = posInicial;
10         transform.Rotate(rotInicial);
11         transform.localScale = escalaInicial;
12     }
13 	
14     // Update is called once per frame
15     void Update () {
16 		
17     }
18 }


Unity3d mov 3.JPG


Ahora podemos modificar los valores iniciales.
  • Nota: El recurso de hacer public a propiedades se puede aplicar a cualquier propiedad en Unity. Por ejemplo, podríamos tener una propiedad que fuera un GameObject o un objeto de la clase Transform. De esta forma podríamos arrastrar gráficamente cualquier objeto y llevarlo al Inspector, copiándose todas sus propiedades.


  • Ahora ha llegado el momento de hacer que el cubo se mueva. Como suponéis, debemos de modificar el valor de uno de los ejes.
El método donde se debe de escribir el código es el método Update.
A dicho método se llama de forma continuada desde que comienza el juego.
 1 public class UD_Movim_basico_1 : MonoBehaviour {
 2 
 3     public Vector3 posInicial = new Vector3(0, 0, 0);
 4     public Vector3 rotInicial = new Vector3(0, 0, 0);
 5     public Vector3 escalaInicial = new Vector3(1, 1, 1);    // La escala no debería ser 0
 6 
 7     public float posFinalX = 5;
 8 
 9     // Use this for initialization
10     void Start () {
11         transform.position = posInicial;
12         transform.Rotate(rotInicial);
13         transform.localScale = escalaInicial;
14     }
15 	
16     // Update is called once per frame
17     void Update () {
18 
19         if (transform.position.x <= posFinalX)
20         {
21             Vector3 temp = transform.position;
22             temp.x += .5f;
23             transform.position = temp;
24         }
25 
26 		
27     }
28 }
  • Si ejecutáis el código veréis como el cubo se mueve rápidamente hacia posición indicada por la variable 'posFinalX'.
Unity3d mov 3.JPG


  • El problema que tenemos es que no tenemos control de la velocidad.
Necesitamos comprender el concepto del parámetro delta


  • Lo que tenemos que tener que claro que cualquier movimiento se produce borrando toda la pantalla y volviéndola a dibujar.
Lo que pasa es que se hace tan rápido que para nuestros ojos solo se tiene la impresión del movimiento.
  • La rapidez con que se borra todo y se vuelve a dibujar la establecemos mediante un parámetro denominado Fotogramas Por Segundo (fps).
Este parámetro va a depender de la máquina donde se ejecute el juego (capacidades hardware de la misma, como procesador, tarjeta gráfica,...) y de lo optimizado que esté nuestro juego.


  • Al depender de la máquina, no podemos hacer que los elementos del juego se muevan sin ningún control, ya que con el código anterior, en una máquina a 60fps se movería mucho más rápido que en una máquina a 30fps. Debemos hacer que la velocidad del movimiento sea independiente del tipo de máquina.
Eso lo conseguimos con el parámetro delta.
  • delta es el tiempo que transcurre desde que se llama a un método y vuelve a llamarse al mismo método.
La forma de obtener dicho valor es mediante la clase Time.
  • Imaginemos que tenemos dos dispositivos Android, uno funcionando a 60fps y otro a 30fps.
Esto quiere decir que (más o menos) se va a llamar al método Update ese número de veces por segundo.
Si ejecutamos este código para mover el cubo:

syntaxhighlight lang="java" line highlight="">

   void Update () {
      if (transform.position.x<100){
       Vector3 temp = transform.position;
       temp.x += 1f;
       transform.position = temp;
      }	
   }

</syntaxhighlight>

  • Como vemos se va a mover mientras X sea menor que 100 unidades.

Como temos no noso xogo un ancho de 300 unidades.

Vai suceder que:

   Máquina1:
       60fps => móvese 60 unidades por segundo => Tarda 300/60 en percorrer toda a pantalla => 5 segundos.
   Máquina2:
       30fps => móvese 30 unidades por segundo => Tarda 300/30 en percorrer toda a pantalla => 10 segundos.

Polo tanto moveríase máis rápido na primeira máquina e non parece moi xusto :).

Como podemos facer para que o movemento sexa independente do hardware da máquina ? Pois multiplicando a velocidade por delta, sendo delta o tempo que tarda en chamar ó método de actualización da posición.


Por exemplo, seguindo o caso anterior:

   Máquina1: a 60 fps. Quere dicir que chama 60 veces nun segundo ó método update.
   Delta = 1/60
   posición.x = posición.x + (1 * delta) :multiplicamos a velocidade por delta. Estamos a poñer unha velocidade de 1 unidade por segundo. Lembrar que o noso mundo mide 300 unidades de ancho.
   Canto tempo tarde en percorrer o noso mundo ?
   Nun segundo percorre:
       60 (fps = veces por segundo) * 1/60 (é delta) * 1 (a velocidade) = 1.
       Polo tanto vai sumar unha unidade á posición x cada segundo.
       O noso mundo mide 300 unidades = 300 segundos.


   Máquina2: a 30 fps. Quere dicir que chama 30 veces nun segundo ó método update.
   Delta = 1/30
   posición.x = posición.x + (1 * delta) :multiplicamos a velocidade por delta. Estamos a poñer unha velocidade de 1 unidade por segundo. Lembrar que o noso mundo mide 300 unidades de ancho.
   Canto tempo tarde en percorrer o noso mundo ?
   Nun segundo percorre:
       30 (fps = veces por segundo) * 1/30 (é delta) * 1 (a velocidade) = 1.
       Polo tanto vai sumar unha unidade á posición x cada segundo.
       O noso mundo mide 300 unidades = 300 segundos.

Como vemos tarda o mesmo. O que está facendo é axustar, diminuíndo a velocidade do en función de delta. Se delta é máis grande (chama moitas veces por segundo) fai que se mova máis lentamente.





-- Ángel D. Fernández González -- (2018).