Páginas

domingo, 16 de febrero de 2014

Creando billboards en Unity

Crear un billboard en Unity es sencillo pero como todo, cuando te pones a hacerlo tiene su arte.



Para quien no lo sepa, un billboard es un plano 2D que se orienta automáticamente hacia la cámara, como estos árboles de Mario Kart.

Script

Este es mi script para billboards. He implementado tres métodos distintos.

using UnityEngine;
using System.Collections;

public class Billboard : MonoBehaviour {

public enum Metodo
{
metodo1,
metodo2,
metodo3

}

public Metodo metodo;

// Use this for initialization
void Start ()
{
if(metodo == Metodo.metodo1)
{
DoLookAt1();
}
else if(metodo == Metodo.metodo2)
{
DoLookAt2();
}
else if(metodo == Metodo.metodo3)
{
DoLookAt3();

}

}

// Update is called once per frame
void Update ()
{
if(metodo == Metodo.metodo1)
{
DoLookAt1();
}
else if(metodo == Metodo.metodo2)
{
DoLookAt2();
}
else if(metodo == Metodo.metodo3)
{
DoLookAt3();
}

}

void DoLookAt1()
{
// Tomo mi posicion y la de la camara
Vector3 cp = Camera.main.transform.position;
Vector3 op = transform.position;

// Proyecto las posiciones en el plano XZ
Vector3 cp2 = new Vector3(cp.x, 0, cp.z);
Vector3 op2 = new Vector3(op.x, 0, op.z);

// Muevo el objeto y la camara a las posiciones en XZ
transform.position = op2;
Camera.main.transform.position = cp2;

// Hago un lookAt
transform.LookAt(Camera.main.transform);

// Restauro las posiciones
transform.position = op;
Camera.main.transform.position = cp;

}

void DoLookAt2()
{
// Copio la rotacion de la camara
transform.rotation = Camera.main.transform.rotation;

// Pongo el objeto mirando al lado contrario
transform.Rotate(0, 180, 0);

}

void DoLookAt3()
{
// Tomo los angulos de euler de la camara y oriento el objeto
Vector3 ce = Camera.main.transform.eulerAngles;
transform.eulerAngles = new Vector3(0, ce.y, 0);

// Lo pongo a mirar en sentido contrario
transform.Rotate(0, 180, 0);

}
}


Método 1


// Tomo mi posicion y la de la camara
Vector3 cp = Camera.main.transform.position;
Vector3 op = transform.position;

// Proyecto las posiciones en el plano XZ
Vector3 cp2 = new Vector3(cp.x, 0, cp.z);
Vector3 op2 = new Vector3(op.x, 0, op.z);

// Muevo el objeto y la camara a las posiciones en XZ
transform.position = op2;
Camera.main.transform.position = cp2;

// Hago un lookAt
transform.LookAt(Camera.main.transform);

// Restauro las posiciones
transform.position = op;
Camera.main.transform.position = cp;


Lo que hace el método es transferir la cámara y el billboard al plano XZ, hacer un lookAt a la cámara y restaurar las posiciones de los objetos.




Con este método los billboards se orientan a la posición de la cámara.



En la vista, da sensación de perspectiva porque los billboards no tienen todos la misma orientación. Si eso es lo que se busca, pues ya está.


Método 2

// Copio la rotacion de la camara
transform.rotation = Camera.main.transform.rotation;

// Pongo el objeto mirando al lado contrario
transform.Rotate(0, 180, 0);


El método 2 lo que hace es poner a los billboards mirando en dirección contraria a la cámara.


Todos los billboards tienen la misma orientación.


Y la vista no da efecto de perspectiva. Probablemente esto sea lo que se busque en la mayor parte de los casos.


Ahora bien ¿Qué pasa si la cámara rota en X, o sea hace un picado? Que los árboles también miran hacia arriba. Nuevamente ésto puede ser bueno o puede ser malo, dependiendo de lo que se busque.


En la vista todos los árboles se ven de frente  pesar del picado.


Método 3

// Tomo los angulos de euler de la camara y oriento el objeto
Vector3 ce = Camera.main.transform.eulerAngles;
transform.eulerAngles = new Vector3(0, ce.y, 0);

// Lo pongo a mirar en sentido contrario
transform.Rotate(0, 180, 0);


Soluciona los problemas del método 2 porque tomamos solo el ángulo de euler Y de la cámara, lo transferimos al objeto y rotamos 180 grados en Y.


Con ésto los árboles no rotan en X y mantienen la perspectiva en el picado, lo que en este caso tendría sentido en mi opinión.

Descarga

Dejo aquí el proyecto, se abre con Unity 4.3






No hay comentarios:

Publicar un comentario