9. ESTRUCTURA VECTOR3 (y IV)
FUNCIONES DE CLASE:
Lerp:
static function Lerp (from : Vector3, to : Vector3, t : float) : Vector3
Esta función interpola linealmente entre dos vectores, desde from hacia to en el valor t.
Vamos a intentar explicarlo de la manera más clara posible, ya que se trata de una función importante: Lerp realiza una línea imaginaria que va del punto que le pasamos como primer parámetro (from) al punto que le pasamos como segundo parámetro (to). Esa línea imaginaria es entonces una recta con un origen y un final, y entre ambos extremos tiene muchos puntos intermedios. Pensemos por ejemplo en una regla, para tener más o menos claro el concepto. Pongamos que al punto de origen (from) le asignamos el valor 0, y al punto final (to) le damos el valor 1. En ese caso, el punto que está en la mitad de nuestra recta imaginaria es evidente que valdrá 0,5.
Con esto claro planteemos ahora el mismo asunto pero al revés. Tenemos el punto origen y el punto final y queremos saber dónde está la mitad exacta entre esos dos puntos. Lo que haríamos es llamar a la función Lerp, asignar a los parámetros primero y segundo respectivamente las coordenadas de origen y final y darle al tercer parámetro (que en el prototipo recibe el nombre de "t", y es de tipo float) el valor 0.5. El valor retornado por la función se corresponderá con el punto situado en el centro de los dos extremos dados.
El parámetro t puede recibir valores entre 0.0 (que coincide con el origen) hasta 1.0 (que coincide con el final).
Vamos a practicar.
En Unity, le quitamos provisionalmente a nuestro gameobject PortaScripts el script, para que no nos dé errores en lo que a continuación haremos.
Acto seguido vamos al menú gameobject=> creater other => capsule. Colocamos la cápsula a un valor -3 en el eje x del transform en el inspector. Renombramos a esta cápsula y la llamamos Origen.
Creamos luego otra cápsula, y en la coordenada x de su transform la pondremos en 3. La rebautizamos como Fin (Final es una palabra reservada)
Es preferible que tengamos la escena enfocada desde la vista superior (lo que conseguimos haciendo click en el eje Y del gizmo)
Ahora hacemos doble click en el script (que aunque hemos borrado del Portascripts sigue estando en el Proyecto), y tecleamos:
var principio : Transform;
var fin : Transform;
function Update () {
transform.position = Vector3.Lerp(principio.position, fin.position, 0.3);
}
Salvamos el script y lo arrastramos a nuestro cubo. Acto seguido seleccionamos el cubo y en el inspector nos aparecerán nuestras dos variables. Arrastramos origen a principio y destino a fin.
Si todo va bien, nuestro cubo debiera situarse a tres décimas partes de la línea hipotética que separa las cápsulas, contando desde la que hemos dado en llamar origen. ¿Lo probamos?

Bien. Parece que funciona, pero podemos ir un poco más allá. Para ello vamos a recurrir a una clase que aún no hemos estudiado, que es la clase Time, y concretamente a la variable time de la clase Time. Time.time es una variable que representa los segundos transcurridos desde que el juego se inicia. Por lo tanto, la variable vale cero al iniciarse el juego, 1 un segundo después, etc.
Con esto en mente, vamos a nuestro último script y dentro de la función Lerp sustituimos el 0.3 por Time.time, salvamos y le damos al play.
Efectivamente, nuestro cubo empieza pegado al origen (el parámetro t, representado por Time.time vale cero) y va desplazándose hacia el fin hasta que t vale 1, o sea, hasta que transcurre un segundo.
Sabiendo esto, podemos hacer que el trayecto de nuestro cubo dure por ejemplo diez segundos en lugar de uno. Conseguimos esto meramente multiplicando Time.time * 0.1.
Podemos, dándole una vuelta más de tuerca al asunto, crear una variable expuesta (susceptible de ser accesada desde el inspector) de tipo float, que el usuario pueda modificar, y que al ser multiplicada por Time.time haga que nuestro cubo viaje más rápido o más lento.
Slerp:
static function Slerp (from : Vector3, to : Vector3, t : float) : Vector3
Esta función es similar a la anterior, con la particularidad de que en lugar de interpolar en línea recta lo hace en forma esférica. Para probarla no tienes más que sustituir el término "Lerp" del script anterior por "Slerp", y poner el cubo en órbita. Si tienes tiempo y ganas, ubica los gameobjects Origen y Destino en otras posiciones a través de sus respectivos transforms en el inspector (desplázalos también en sus ejes Y y Z).
Mientras vas trasteando, me despido hasta la próxima clase.
8. ESTRUCTURA VECTOR3(III)
Scale:
function Scale (scale : Vector3) : void
Multiplica el Vector3 que llama la función por el Vector3 que le pasamos a dicha función como parámetro.
Lo veremos mejor con un ejemplo. Vamos a darle un meneo de nuevo a nuestro script. Tecleamos:
var unObjeto : GameObject;
var miVector : Vector3;
miVector = unObjeto.transform.position = Vector3(2.0, 1.0, 3.0);
Debug.Log("Magnitud inicial del cubo " +miVector.magnitude);
miVector.Scale(Vector3(3.0, 1.5, 2.0));
unObjeto.transform.position = miVector;
Debug.Log("Magnitud final del cubo " +miVector.magnitude);
Antes que nada vamos a explicar lo que pretendemos hacer: dejamos expuesta la variable unObjeto para arrastrar con posterioridad nuestro cubo desde el inspector. Asimismo declaramos una variable para sostener el valor original y modificado para un vector3.
Aunque aún no lo hemos estudiado, a nadie sorprenderá que los diferentes gameobjects que ocupan la escena han de ir ineludiblemente vinculados a un objeto transform, el cual a su vez es el que sirve para fijar en qué punto del espacio 3D se halla el gameobject. Así, para obtener o indicar la posición de un gameobject en el espacio usaríamos la sintaxis gameobject.transform.position. Se da la circunstancia que la variable position de la clase transform es de tipo Vector3, por lo que nos sirve para nuestro ejemplo.
Hacemos una iniciación doble, de tal manera que damos unos valores a nuestro Vector3 miVector, que a su vez tendrá el mismo valor que le damos a la posición actual del cubo. Obtenemos la magnitud de dicho vector y la imprimimos.
Luego usamos la función Scale, y la magnitud del vector modificado es impreso de nuevo, y a la par el cubo se desplaza por segunda vez.
Obtendremos al darle al play un resultado como este

Si nos fijamos en la parte inferior de la ventana Game, sólo aparece impresa la magnitud final del vector de nuestro cubo. Para ver también el valor inicial, hemos de hacer un click sobre dicho texto impreso, de tal suerte que nos aparecerá una ventana emergente con ambos valores, tal como mostramos:

La función Scale tiene un segundo prototipo, que es el que sigue
static function Scale (a : Vector3, b : Vector3) : Vector3
El fin último es, al igual que en la función homónima, multiplicar dos vectores. La diferencia es que aquí pasamos expresamente los dos vectores que queremos multiplicar entre sí. También difieren ambas funciones en que la primera no devuelve ningún valor (el cambio resultante de la multiplicación es directamente asignado al objeto que la llama) y esta en cambio sí devuelve un Vector3 con el resultado, que podemos por lo tanto asignar a una variable.
Normalize:
function Normalize () : void
Esta función hace que el Vector3 que la llama pase a tener una magnitude de 1, conservando, eso sí, la misma dirección. Como decimos, esta función cambia el vector que la llama; si lo que pretendemos es conservar sin cambios el vector corriente y crear un nuevo vector normalizado, hemos de usar -como ya aprendimos en el capítulo anterior- la variable normalized.
ToString:
function ToString () : String
Devuelve nuestro vector convertido en un string y formateado.
Para ver como funciona, añadamos al final del script que usamos en el ejemplo anterior la siguiente línea:
ebug.Log("Mi vector como string formateado: " + miVector.ToString());
Veremos que nos aparece el vector resultado de la multiplicación del anterior ejemplo convertido en un string que podemos imprimir.
Dejamos para el próximo capítulo las dos funciones de clase que nos restan para acabar la explicación de la estructura Vector3.
7. ESTRUCTURA VECTOR3 (II)
CONSTRUCTOR:
1)static function Vector3 (x : float, y : float, z : float) : Vector3
Como sabemos de nuestros conocimientos de programación orientada a objetos, el constructor es una función especial cuyo cometido es crear de manera adecuada las instancias/objetos de una determinada clase o estructura. La función constructora se caracteriza por tener el mismo nombre que la clase.
Tal como vemos en el prototipo de nuestro constructor, le hemos de pasar al mismo los tres componentes de nuestro punto 3D, referidos al eje horizontal, vertical y de profundidad respectivamente, en formato de punto flotante. Así:
var miPunto = Vector3(2.0, 5.0, 4.8);
referenciamos un punto que con respecto al origen se desplazará dos unidades a la derecha, cinco hacia arriba y 4,8 hacia el fondo.
Vale, pero ¿cuál es el origen?, se preguntará alguien.
Pues depende, tendremos que responder. Si un objeto no depende de otro, entendemos por origen el punto 0,0,0 de las coordenadas globales (que es donde deberíamos tener nuestro cubo) y desde ese punto origen se calcula el desplazamiento, pero si un objeto depende de otro (recordemos el ejemplo de la rueda y el coche) caben para ese objeto dos orígenes o coordenadas diferentes: las globales (distancia de la rueda respecto del eje 0,0,0 del caso anterior) y las locales (referidas al objeto del que depende)
2)static function Vector3 (x : float, y : float) : Vector3
Como vemos, hay una segunda función constructora que no toma en cuenta el eje Z (la profundidad) asumiendo que ésta es cero. Por tanto, si a la función constructora Vector3 sólo le pasamos dos parámetros, automáticamente será llamada esta segunda versión del constructor.
VARIABLES:
x, y, z:
Estas variables se refieren a los componentes X, Y y Z del vector, respectivamente.
this:
var this[index : int] : float
Esta es otra forma para acceder a los componentes X, Y y Z del vector, siendo los respectivos índices de cada componente 0, 1 y 2.
Así, estas dos declaraciones son equivalentes:
var miVector : Vector3;
miVector.x = 3.0;
miVector[0] = 3.0; //Equivale a la anterior
magnitude:
var magnitude : float
Esta variable devuelve la longitud o tamaño de un vector. Habíamos hablado previamente de que un vector3 contiene el número de unidades que lo separan del origen dado en los ejes X, Y y Z. Obviamente, cuanta mayor es la distancia entre nuestro Vector3 y el punto de origen, mayor la longitud del vector.
La longitud del vector equivale a la raiz cuadrada de (x*x+y*y+z*z).
Soy consciente de que a estas alturas la utilidad de funciones como estas es difícil de apreciar. Con un poco de paciencia, y cuando las combinemos con otras clases, veremos el partido que se le puede sacar a todo esto.
sqrMagnitude:
var sqrMagnitude : float
Si de lo que se trata es de comparar dos vectores, es preferible usar esta función que la precedente, ya que aunque parezca antiintuitivo, Unity calcula con más rapidez los cuadrados de las magnitudes que las magnitudes en sí.
normalized:
var normalized : Vector3
Esta variable devuelve un vector con la misma dirección que el original, pero con magnitud 1. Es importante constatar que el vector original permanece inalterado y lo que se devuelve es meramente una copia que conserva la dirección de dicho original, aunque con la longitud alterada. Si en lugar de normalizar una copia quisiéramos hacer lo propio con el original, entonces tendríamos que usar la función Normalize, que veremos en breve.
Decir también que si el vector es demasiado pequeño para ser normalizado, lo que se devuelve es un vector a cero.
VARIABLES DE CLASE:
zero:
static var zero : Vector3
Es meramente un atajo para poner un vector a cero.
transform.position = Vector3.zero;
// Es lo mismo que escribir
transform.position = Vector3(0,0,0);
one, forward, up y right:
Son respectivamente atajos para escribir Vector3(1,1,1), Vector3(0,0,1), Vector3(0,1,0) y Vector3(1,0,0).
Vamos a ver algunos de los conceptos de esta lección en un ejemplo. Abrimos nuestro script favorito y escribimos:
var unObjeto : GameObject;
var desplazamiento : Vector3;
var magnitud : int = 0;
desplazamiento = Vector3.right;
for(var contador = 0; contador < 3; contador++)
{
unObjeto.transform.position += desplazamiento;
magnitud += desplazamiento.magnitude;
Debug.Log("Longitud del Vector del cubo: " + magnitud);
}
Salvamos, arrastramos nuestro cubo para que se convierta en la variable unObjeto y le damos al play. Nuestro cubo se mueve tres unidades a la derecha y bajo la ventana Game aparece la magnitud de desplazamiento del vector.
El script funciona de la siguiente forma: Además de la variable que sostendrá a nuestro cubo, creamos una variable de tipo Vecto3 para poder almacenar a modo de impulsos maniobras de desplazamiento de una unidad a la derecha. Ese input a la derecha se lo daremos tres veces mediante un bucle for, y cada magnitud individual (que obviamente vale 1 cada vez) se acumula en una variable de tipo int que hemos creado a tal efecto.
Mañana seguimos con las funciones.
Bye.
Con la tecnología de Blogger.
BUSCADOR
PÁSATE POR EL FORO
API DE UNITY
TEMAS
- 00_INTRODUCCION (3)
- 01_CLASE OBJECT (3)
- 02_ESTRUCTURA VECTOR3 (4)
- 03_CLASE TRANSFORM (7)
- 04_CLASE RIGIDBODY (8)
- 05_CLASE COLLIDER (2)
- 06_CLASE MESHCOLLIDER (1)
- 07_CLASE CHARACTERCONTROLLER (3)
- 08_CLASE RENDERER (2)
- 09_CLASE MESHFILTER (1)
- 10_CLASE JOINT (2)
- 11_CLASE HINGEJOINT (2)
- 12_CLASE SPRINGJOINT (1)
- 13_CLASE CHARACTERJOINT (1)
- 14_CLASE BEHAVIOUR (1)
- 15_CLASE MONOBEHAVIOUR (9)
- 16_CLASE CAMERA (6)
- 17_CLASE LIGHT (3)
- 18_CLASE MATERIAL (3)
- 19_CLASE CUBEMAP (1)
- 20_CLASE RENDERTEXTURE (3)
- 21_CLASE PARTICLEEMITTER (3)
- 22_CLASE MESH (2)
- 23_CLASE GAMEOBJECT (6)
- 24_CLASE SHADER (1)
- 25_CLASE PHYSICMATERIAL (1)
- 26_CLASE COMPONENT (1)
- 27_CLASE GUIELEMENT (1)
- 28_CLASE GUITEXT (2)
- 29_CLASE GUITEXTURE (1)
- 30_CLASE GUI (8)
- 31_CLASE GUILAYOUT (4)
- 32_CLASE TEXTURE (1)
- 33_CLASE TEXTURE2D (2)
- 34_CLASE INPUT (4)
- 35_ESTRUCTURA BOUNDS (1)
- 36_CLASE COLLISION (1)
- 37_CLASE CONTROLLERCOLLIDERHIT (1)
- 38_CLASE DEBUG (1)
- 39_CLASE EVENT (3)
- 40_CLASE GIZMOS (1)
- 41_CLASE LIGHTMAPSETTINGS (1)
- 42_ESTRUCTURA MATHF (3)
- 43_CLASE PHYSICS (2)
- 44_ESTRUCTURA QUATERNION (1)
- 45_CLASE RANDOM (1)
- 46_ESTRUCTURA RAY (1)
- 47_ESTRUCTURA RAYCASTHIT (1)
- 48_ESTRUCTURA RECT (1)
- 49_CLASE RENDERSETTINGS (1)
- 50_CLASE SCREEN (1)
- 51_CLASE TIME (1)
- 52. CLASE YIELDINSTRUCTION (1)
- MONOGRAFICOS (2)
