Fluidez de cámara 2

En este post aprenderemos a hacer que nuestra cámara se mantenga detrás de nuestro personaje y lo siga de manera que veamos lo que tiene delante en todo momento.

Empezaremos creando dos variables. La primera será una variable pública de tipo float a la que llamaremos distFromPlayer y le asignaremos un valor igual a 5 (public float distFromPlayer = 5;). Esta variable indicará la distancia nuestro personaje de la cámara. La segunda variable será también una variable pública de tipo float a la que llamaremos heightFromPlayer y le asignaremos un valor igual a 3 (public float heightFromPlayer = 3;). Esta variable indicará la altura a la que estará la cámara.

A continuación haremos que la posición de la cámara sea siempre la misma que la del personaje pero desplazada siguiendo el valor que le asignemos a las variables anteriormente creadas. Para ello igualaremos la posición de la cámara con la del personaje más un vector con los valores para la altura en el eje Y (heightFromPlayer) y la distancia en el eje Z (distFromPlayer) a la que queremos que esté. El código para esto será: transform.position = player.position + new Vector3 (0, heightFromPlayer, -distFromPlayer); .

El problema es que esto solamente mantendrá la cámara siguiendo al personaje a una distancia fija pero no rotará con él, de manera que no se mantendrá detrás del personaje. Para que rote con el personaje tendremos que multiplicar la rotación del mismo por el vector. De modo que quedará transform.position = player.position + (player.rotation * new Vector3 (0, heightFromPlayer, -distFromPlayer)); . Ahora la cámara se mantendrá siempre detrás del personaje aunque este rote. Para variar la velocidad a la que la cámara se adapta solo tendremos que aumentar el valor de la variable smoothLook. Un valor igual a 7 sería una buena opción.

followPlayer

Ahora mejoraremos el comportamiento y fluidez de la cámara en su desplazamiento de posición del mismo modo que hicimos con la rotación. Crearemos una variable Vector3 a la que llamaremos targetMove (Vector3 targetMove;) donde almacenaremos la posición objetivo de nuestra cámara. Para ello simplemente modificaremos la línea de código que teníamos previamente de modo que cambiaremos transform.position por nuestro vector targetMove. Quedará del siguiente modo: targetMove = player.position + (player.rotation * new Vector3 (0, heightFromPlayer, -distFromPlayer)); . Del mismo modo que hicimos con la rotación usaremos la función Lerp, pero esta vez mediante la clase Vector3. Para la variable from usaremos transform.position (nuestra posición de origen), para la variable to usaremos targetMove (nuestra posición objetivo) y para t emplearemos smoothMove, una variable pública que crearemos del tipo float con un valor inicial que le asignaremos igual a 0,5 (public float smoothMove = 0.5f;), a la que escalaremos en el tiempo empleando Time.deltaTime . La línea de código quedará de la siguiente manera: transform.position = Vector3.Lerp (transform.position, targetMove, smoothMove * Time.deltaTime); . Podéis probar a sustituir la función Lerp por Slerp, el resultado será idéntico.

followPlayer2

SmoothCam

Para lograr un efecto similar, pero probablemente con incluso más fluidez, podemos emplear la función SmoothDamp de la clase Vector3 que generará un Vector3. Comentaremos la anterior línea de código si no queremos eliminarla antes de empezar con la nueva. Como ya hemos visto necesitaremos un Vector3 para indicar la posición actual, otro para la posición objetivo, otro vector de referencia para la velocidad y una variable tipo float para el tiempo. Para la posición actual usaremos transform.position, mientras que para la posición objetivo targetMove. Crearemos una variable de tipo Vector a la que llamaremos smoothMoveV para usar como variable de referencia para la velocidad. Para la variable del tiempo que queremos que tarde en realizar la transición usaremos smoothMove. Como esta variable indicará el tiempo de por sí, no necesitamos escalarlo con Time.deltaTime. Además, en este caso cuanto mayor sea el número mayor será el tiempo que tarde la cámara en moverse, a diferencia de Lerp donde cuanto mayor fuese t menor sería el tiempo en realizar el movimiento. La línea de código resultante sería la siguiente: transform.position = Vector3.SmoothDamp (transform.position, targetMove, ref smoothMoveV, smoothMove); . Debemos reajustar el valor de la variable smoothMove a un valor menor (por ejemplo 0,2).

followPlayer3

El código final que obtenemos realizando los pasos del post será:

using UnityEngine;
using System.Collections;

public class CameraScript : MonoBehaviour {

Transform player;
Quaternion targetLook;
Vector3 targetMove;
public float smoothLook = 0.5f;
public float smoothMove = 0.5f;
Vector3 smoothMoveV;
public float distFromPlayer = 5;
public float heightFromPlayer = 3;

void Start () {

player = GameObject.FindWithTag ("Player").transform;
}

void Update () {

//transform.position = player.position + (player.rotation * new Vector3 (0, heightFromPlayer, -distFromPlayer));

targetMove = player.position + (player.rotation * new Vector3 (0, heightFromPlayer, -distFromPlayer));
//transform.position = Vector3.Lerp (transform.position, targetMove, smoothMove * Time.deltaTime);
transform.position = Vector3.SmoothDamp (transform.position, targetMove, ref smoothMoveV, smoothMove);

targetLook = Quaternion.LookRotation (player.position - transform.position);
transform.rotation = Quaternion.Lerp (transform.rotation, targetLook, smoothLook * Time.deltaTime);

//transform.LookAt (player);
}
}

Deja un comentario