Unity 3d Manual
Unity 3d Manual
MENÚ:
El personaje contiene el componente de "Character Controller" y para que este completo componente interactue con fisicas de otros
objetos, entramos en la referencia de script en unity y buscamos: OnControllerColliderHit al ahcer click en la liga este componente del
charactercontroller nos permitira que al chocar con un objeto detecte la posicion y lo lanze con una fuerza (golpe entre objetos).
Nota: podrás mover al personaje usando las teclas “WASD” ó las “flechas”, así como la barra de espacio para saltar, y no puedes tener
más de 2 controles de personajes en la misma escena.
5
www.3deobox.com
Unity Scripts:
Mouse Look: Permite que la cámara pueda mirar en cualquiera dirección de X & Y o restringir en estos mismos ejes.
Mouse Orbit: Permite que la cámara siga un target, además de que pueda rotar alrededor del target.
Mouse Follow: A la cámara se le asigna un Target y lo desplazara a donde este el target, pero además permite que a donde se
mueva el mouse el target cuando camine se dirija a esa dirección.
Mouse Look At: A la cámara se le asigna un Target y este siempre estará mirándolo a donde se mueva.
Activate Trigger: Nos permite controlar cualquier objeto para activar si es una luz, una animación, etc.
Drag Rigidbody: Nos permite objetos con Rigidbodies puedan ser arrastrados con la interaccion del Puntero del mouse.
7
www.3deobox.com
SINTAXIS:
El Scripting es la forma en la que el usuario crea/define el comportamiento del juego (o las normas) en Unity. El lenguaje de
programación recomendado para Unity es JavaScript, aunque C Sharp o Boo Script pueden ser igualmente usados. Pueden pensar
en la API como un código que ya ha sido escrito para uno y que permite concentrarte en el diseño de tu juego y acelerar el tiempo de
desarrollo. Un buen entendimiento de estos principios básicos es esencial para aprovechar todo el poder de Unity.
Convenciones de nomenclatura:
Variables (variables) - empiezan con una letra minúscula. Las variables se usan para almacenar información sobre cualquier aspecto de
un estado de juego.
Functions (funciones) - empiezan con una letra mayúscula. Las funciones son bloques de códigos que han sido escritos una vez y que
se pueden rehusar tantas veces como sea necesario.
Classes (clases) - empiezan con una letra mayúscula. Éstos pueden tomarse como colecciones de funciones.
Update: Esta función manda llamar cada frame. Esta es la función más usual en juegos, exceptuándolo en el uso de código para Físicas.
FixedUpdate: Esta función es para mandar llamar en cada paso de las físicas. Estés es la función para normalmente scripting con físicas.
9
www.3deobox.com
Java Script:
#pragma strict
Funcion usada para optimizer procesos para publicar en Flash.
function Start () {
}
Declarar funcion de Start (al iniciar el juego se ejecutara).
function Update () {
}
Declarar funcion de Update (Constantemente se ejecuta).
C# Script:
using UnityEngine;
using System.Collections;
Estas líneas al inicio del script son necesaria para que C# mande llamar directamente al Engine de Unity.
Al iniciar un nuevo documento de C# siempre le pondrá como nombre a la clase “NewBehavoiurScript”, este es el default
que Unity le asigna como
nombre, en este caso el nombre de Script y el de la Clase, tienen que ser el mismo nombre, debemos de crear una
clase y dentro de esta deberá de ir todo el contenido que desarrollaremos para programar.
}
En C# TODA accion que se desee ejecutar debe de ir dentro de una function (void) forsozamente (Mejor performance).
// Update is called once per frame
void Update () { La forma en la que se declarar funcion de Update (Constantemente se ejecuta).
}
}
10
www.3deobox.com
EVENTOS ESCENAS:
EVENTOS TRIGGERS:
EVENTOS COLISIONADORES:
void OnCollisionEnter () – Es llamado cuando este Collider/rigidbody a comenzado a tocar otro rigidbody/Collider.
void OnCollisionExit() – Es llamado cuando este Collider/rigidbody ha dejado de tocar a otro Collider/rigidbody.
void OnCollisionStay() – Es llamado 1 vez por frame cada que este Collider/rigidbody está tocando otro Collider/rigidbody.
EVENTOS VISIBLES:
void OnBecameVisible () – Es llamado cuando el Render se ha cambiado a Visible por cualquier cámara.
void OnBecameInvisible() – Es llamado cuando el Render se ha cambiado a Invisible por cualquier cámara.
12
www.3deobox.com
EVENTOS ESCENAS:
EVENTOS TRIGGERS:
EVENTOS COLISIONADORES:
function OnCollisionEnter () – Es llamado cuando este Collider/rigidbody a comenzado a tocar otro rigidbody/Collider.
function OnCollisionExit() – Es llamado cuando este Collider/rigidbody ha dejado de tocar a otro Collider/rigidbody.
function OnCollisionStay() – Es llamado 1 vez por frame cada que este Collider/rigidbody está tocando otro Collider/rigidbody.
EVENTOS VISIBLES:
function OnBecameVisible () – Es llamado cuando el Render se ha cambiado a Visible por cualquier cámara.
function OnBecameInvisible() – Es llamado cuando el Render se ha cambiado a Invisible por cualquier cámara.
13
www.3deobox.com
Las variables tienen que ser declaradass de la siguiente manera: C# Script (C#) TipoVariable NombreVariable = valor; una vez declarada la variable no es
necesario usar “: TipoVariable” de nuevo, solo con poner “NombreVariable = valor”.
TipoVariable: El tipo de variable a crear.
Valor: El valor que tendrá la variable.
Ejemplos de Variables Publicas: int Deo_int = 200; | float Deo_float = 10.5f; | String Deo_String = "Hola Mundo";
Variables Públicas - Permite comunicarse entre los Scripts del mismo GameObject u otros GameObjects (Si se publica en Inspector):
public Strign DeoValor = "Hola a todos";
Variables Públicas Ocultas - Para crear variables publicas y estas no sean mostradas en el inspector. Esta línea va arriba de nuestra variable que deseamos no mostrar
y si después hay más variables definidas si se mostraran en el inspector: [System.NonSerialized]
Variables Privadas Permite comunicarse entre los Scripts del mismo GameObject u otros GameObjects (No se publica en Inspector):
private String DeoValor = "Hola a todos"; / String DeoValor = "Hola a todos";
Variables Globales - Permite crear variables globales para que se peudan comunicar entre todos los Scripts de la escena (No se publica en Inspector):
static Strign DeoValor = "Hola a todos";
Las variables tienen que ser declaradass de la siguiente manera: JavaScript (JS) var NombreVariable : TipoVariable = valor; una vez declarada la variable no es
necesario usar “var” + “ : TipoVariable” de nuevo, solo con poner “NombreVariable = valor”.
Var: Definir variable por priemra vez.
Variable: El nombre de la variable.
Valor: El valor que tendrá la variable.
Variables Locales desde en el Inspector: var Deo_int : int = 200; | var Deo_float : float = 10.5; | var Deo_String : String = "Hola Mundo";
Variables Públicas - Permite comunicarse entre los Scripts del mismo GameObject u otros GameObjects (Si se publica en Inspector):
public var DeoValor : String = "Hola a todos";
Variables Públicas Ocultas - Para crear variables publicas y estas no sean mostradas en el inspector. Esta línea va arriba de nuestra variable
que deseamos no mostrar y si después hay más variables definidas si se mostraran en el inspector: @System.NonSerialized
Variables Privadas Permite comunicarse entre los Scripts del mismo GameObject u otros GameObjects (No se publica en Inspector):
private var DeoValor : String = "Hola a todos";
Variables Globales - Permite crear variables globales para que se peudan comunicar entre todos los Scripts de la escena (No se publica en Inspector):
static Strign DeoValor = "Hola a todos";
IMPRIMIR EN CONSOLA:
Debug.Log ( ); ó print ();
VARIABLES:
Sumar y Restar:
JS & C# Variable1 + 1; Variable1 ++;
JS & C# Variable1 - 1; Variable1 --;
Dividir y Multiplicar:
JS & C# Variable1 = VariableValor2 / 10; -- Dividir
JS & C# Variable1 = VariableValor2 * 10; -- Multiplicar
1.7 CONDITIONS.
19
www.3deobox.com
Las condiciones nos permite hacer comparaciones, de acuerdo al resultado hacemos alguna otra acción.
if (variable_A > variable_B || variable_A != 0){ if (variable_A > variable_B || variable_A != 0){
Debug.Log ("La comparación es verdadera "); Debug.Log ("La comparación es verdadera ");
} }
} }
1.8 LOOPS
1.9 SWITCH.
(WHILE & FOR).
21
www.3deobox.com
Este tipo de estado debe de ir en una función de tipo Start(); While lopps nos permite repetir todo un bloque de código hasta que se cumpla
una condición. En si el While sirve para repetir “Mientras” se cumple la condición.
// Se hace aquí la acción que queremos repetir. // Se hace aquí la acción que queremos repetir.
print ("Cantidad: " + Valor); print ("Cantidad: " + Valor);
} }
} }
EJEMPLO: FOR IN EJEMPLO: FOR IN
Switch:
Este estado nos permite tomar de una sola variable su valor y realizar múltiples operaciones dependiendo del valor de la variable.
}
23
www.3deobox.com
Las funciones nos permiten contener múltiples acciones dentro, y se pueden ejecutar con el nombre de la función.
Se pueden crear funciones y sobrecargarlas con información, asi dependiendo del valor enviado se ejecutara una de las funciones
Almacenar cada uno de los valores del Arreglo por medio de “For in Array”
ArrayList InterfaceGUI = new ArrayList ();
void Start () {
ArrayList nombresGamePlay = new ArrayList {"Lupa", "Arma", "Vida", "PowerUp"};
Almacenar cada uno de los valores del Arreglo por medio de “For in Array”
function Start () {
for (var Listatemporal:String in nombres){ // Se transfiere los valores del arreglo por el numero de objetos del arreglo.
print (Lista);
}
}
Transform.position -- Es para: “obtener/mover” la posición que un objeto con en el método de world space.
Vector3 position
Time.deltaTime -- Se usa para hacer que la velocidad del juego sea independiente en frames/s, para que sea en relación al tiempo y no a frames.
float deltaTime
Ejemplos: Vector3.zero (0,0,0) | Vector3.one (1,1,1) | Vector3.up (0,1,0) | Vector3.forward (0,0,1) | Vector3.right (1,0,0,).
Ejemplos: transform.zero (0,0,0) | transform.one (1,1,1) | transform.up (0,1,0) | transform.forward (0,0,1) | transform.right (1,0,0,).
Transform.Translate -- Es para trasladar un objeto en cualquiera de los ejes X, Y, Z con selección del Space.
transform .Translate (Vector3 translation Axis, relativeTo : Space = Space.Self/Space.World) : void
Ejemplo:
Vector3.Lerp -- Desplaza al GameObject con una interpolación de un punto de inicio a un destino, con velocidad desacelerada.
Lerp (from: Vector3, to: Vector3, t: float) : Vector3
Vector3.MoveTowards -- Desplaza al GameObject con una interpolación de un punto de inicio a un destino, con velocidad constante.
MoveTowards (current : Vector3, target : Vector3, maxDistanceDelta : float) : Vector3
Ejemplo:
void Update () {
PosY = Mathf.PingPong ( Time.time * Velocidad, Distancia ) + Altura;
transform.position = new Vector3 (transform.position.x, PosY, transform.position.z);
}
32
www.3deobox.com
Transform.position -- Es para: “obtener/mover” la posición que un objeto con en el método de world space.
var position : Vector3
Time.deltaTime -- Se usa para hacer que la velocidad del juego sea independiente en frames/s, para que sea en relación al tiempo y no a frames.
var deltaTime : float
Ejemplos: Vector3.zero (0,0,0) | Vector3.one (1,1,1) | Vector3.up (0,1,0) | Vector3.forward (0,0,1) | Vector3.right (1,0,0,).
Ejemplos: transform.zero (0,0,0) | transform.one (1,1,1) | transform.up (0,1,0) | transform.forward (0,0,1) | transform.right (1,0,0,).
transform.position = Vector3 (0, 0, 0); | transform.position = Vector3.zero; // Cambiar la posición de un objeto en X,Y,Z.
transform.position = transform.zero; // Cambiar la posición de un objeto en X,Y,Z.
Transform.Translate -- Es para trasladar un objeto en cualquiera de los ejes X, Y, Z con selección del Space.
transform .Translate (translation : Vector3, relativeTo : Space = Space.Self/Space.World) : void
Ejemplo:
Vector3.Lerp -- Desplaza al GameObject con una interpolación de un punto de inicio a un destino, con velocidad desacelerada.
Lerp (from : Vector3, to : Vector3, t : float) : Vector3
Vector3.MoveTowards -- Desplaza al GameObject con una interpolación de un punto de inicio a un destino, con velocidad constante.
MoveTowards (current : Vector3, target : Vector3, maxDistanceDelta : float) : Vector3
Ejemplo:
function Update () {
transform.position.y = Mathf.PingPong (Time.time * Velocidad, Distancia) + Altura;
}
34
www.3deobox.com
Ejemplo:
Ejemplo:
void Update() {
// Pone al objeto a rotar en el eje de las X 20 grados/segundo.
transform.Rotate (new Vector3 (20 * Time.deltaTime, 0, 0), Space.Self);
}
36
www.3deobox.com
ANIMACION DE ROTACION SUAVE:
transform.rotation = Quaterion.Lerp (to : Vector3, from : Vector3, t: float); Quaterionn con rotacion con suavidad (Rotaciones Cortas).
transform.rotation = Quaterion.Slerp (to : Vector3, from : Vector3, t: float); Quaterionn con rotacion con suavidad (Rotacion Largas).
transform.rotation = Quaterion.RotateTowards (to : Vector3, from : Vector3, t: float); Quaterionn con rotacion constante de Inicio a Final.
Ejemplo:
void Update() {
// Rotar con suavidad (Fade).
transform.rotation = Quaternion.Lerp (transform.rotation, Quaternion.Euler (0, Rotador, 0), Time.deltaTime * 1);
}
Ejemplo:
void Update() {
// Rotar sin suavidad.
transform.rotation = Quaternion.RotateTowards (transform.rotation, Quaternion.Euler (0, Rotador, 0), Time.deltaTime * 100);
}
ANIMACION DE ESCALAMIENTO:
Transform.localScale Escala al objeto en el espacio local del GameObjetc Completa o por Eje.
Ejemplo:
void Update () {
Ejemplo:
Ejemplo:
function Update() {
// Pone al objeto a rotar en el eje de las X 20 grados/segundo.
transform.Rotate (Vector3(20 * Time.deltaTime, 0, 0), Space.Self);
}
38
www.3deobox.com
ANIMACION DE ROTACION SUAVE:
transform.rotation = Quaterion.Lerp (to : Vector3, from : Vector3, t: float); Quaterionn con rotacion con suavidad (Rotaciones Cortas).
transform.rotation = Quaterion.Lerp (to : Vector3, from : Vector3, t: float); Quaterionn con rotacion con suavidad (Rotacion Largas).
transform.rotation = Quaterion.Lerp (to : Vector3, from : Vector3, t: float); Quaterionn con rotacion constante de Inicio a Final.
Ejemplo:
function Update() {
// Rotar con suavidad.
transform.rotation = Quaternion.Lerp (transform.rotation, Quaternion.Euler (0, Rotador, 0), Time.deltaTime * 1);
Ejemplo:
function Update() {
// Rotar constantemente.
transform.rotation = Quaternion.RotateTowards (transform.rotation, Quaternion.Euler (0, Rotador, 0), Time.deltaTime * 100);
}
ANIMACION DE ESCALAMIENTO:
Transform.localScale Escala al objeto en el espacio local del GameObjetc Completa o por Eje.
Ejemplo:
function Update () {
// En los 3 ejes
transform.localScale += Vector3 (0.5f * Time.deltaTime, 0.0f, 0.0f);
ó
// En un solo eje
transform.localScale += Vector3.right * 2 * Time.deltaTime;
}
39
www.3deobox.com
Los inputs nos permiten mapear las teclas que se presionan (teclado/ratón) ó botones de algún control externo de USB.
Ejemplo:
void Update () {
// Mueve al objeto en horizontal/vertical del axis del inputs.
transform.Translate (Input.GetAxis ("Horizontal"), 0, Input.GetAxis ("Vertical"));
print (Input.GetAxis ("Horizontal")); // Mostrar el valor.
print (Input.GetAxis ("Vertical"));
}
Ejemplo:
void Update () {
if (Input. GetKeyDown/Up ("Atacar")){
print ("El GameObject la acción!");
}
}
Ejemplo:
Ejemplo:
void Update () {
if ( Input.GetKeyDown (KeyCode.Space) ){ void Update () {
//acción if ( Input.GetKeyUp (KeyCode.Space) ){
} //acción
} }
Ejemplos:
Ejemplos:
Ejemplo:
Mouse 0 = Izquierdo, Mouse 1 = Derecho, Mouse 2 = Central.
void Update () {
void Update () { if ( Input.GetMouseButtonUp (0) ) {
if ( Input.GetMouseButtonDown (0) ) { //acción
//acción }
} }
}
42
www.3deobox.com
Los inputs nos permiten mapear las teclas que se presionan (teclado/ratón) ó botones de algún control externo de USB.
Ejemplo:
function Update () {
// Mueve al objeto en horizontal/vertical del axis del inputs.
transform.Translate (Input.GetAxis ("Horizontal"), 0, Input.GetAxis ("Vertical"));
print (Input.GetAxis ("Horizontal")); // Mostrar el valor.
print (Input.GetAxis ("Vertical"));
}
Ejemplo:
function Update () {
if (Input. GetKeyDown/Up ("Atacar")){
print ("El GameObject la acción!");
}
}
Ejemplo:
Ejemplo:
function Update () {
if ( Input.GetKeyDown (KeyCode.Space) ){ function Update () {
//acción if ( Input.GetKeyUp (KeyCode.Space) ){
} //acción
} }
Ejemplos:
Ejemplos:
Ejemplo:
Mouse 0 = Izquierdo, Mouse 1 = Derecho, Mouse 2 = Central.
function Update () {
function Update () { if ( Input.GetMouseButtonUp (0) ) {
if ( Input.GetMouseButtonDown (0) ) { //acción
//acción }
} }
}
44
www.3deobox.com
Podemos crear variables dinámicas que se pueden tener acceso por medio del inspector, de esta manera se tiene control de que se
conecta con cada variable de manera visual, este es un buen principio cuando se crean variables sencillas y de accesos para artistas.
AI_Move
void Update () {
transform.position = new Vector3
(Box.position.x, transform.position.y, Box.position.z);
}
AI_LookAt
void Update () {
// Función para mirar hacia un objeto de la escena.
transform.LookAt (Box);
}
46
www.3deobox.com
Podemos crear variables dinámicas que se pueden tener acceso por medio del inspector, de esta manera se tiene control de que se
conecta con cada variable de manera visual, este es un buen principio cuando se crean variables sencillas y de accesos para artistas.
AI_Move
function Update () {
transform.position = Vector3 (Box.position.x, transform.position.y, Box.position.z);
}
AI_LookAt
function Update () {
// Función para mirar hacia un objeto de la escena.
transform.LookAt (Box);
}
47
www.3deobox.com
1.15 COMMUNICATION BETWEEN GAMEOBJECTS WITH FIND/TAG & BASIC ACCESS (On/Off).
48
www.3deobox.com
1. Importamos el paquete de Escena de la carpeta y lo insertamos en la escena colocando 2 luces, pointlight y un directional light.
2. Creamos un Script "AI_Find" y se aplicara a la "Cámara" para que este sea quien busque al pointlight al usar el input creado.
void Start () {
// Asignar a la variable el objeto PointLight de la escena.
ObjetoLuz = GameObject.Find ("Point Light");
}
void Update() {
if (Input.GetKeyDown(KeyCode.Space)) {
//Con el objeto cargado como es luz, entramos al componente de "Light ->light"
ObjetoLuz.light.enabled = false;
}
}
ObjetoLuz.light.enabled = ! ObjetoLuz.light.enabled; //hacer que la luz se apague o prenda al usar la misma tecla (input).
GameObject ObjetoLuz;
void Start () {
//Mejor Performance.
ObjetoLuz = GameObject.FindWithTag ("tag_Point Light");
}
void Update() {
if (Input.GetKeyDown(KeyCode.Space)) {
// Hacer que al presionar cambie el valor e imprima texto.
if (interruptor){
ObjetoLuz.light.enabled = ! ObjetoLuz.light.enabled;
}
}
}
49
www.3deobox.com
3. Importamos el paquete de Escena de la carpeta y lo insertamos en la escena colocando 2 luces, pointlight y un directional light.
4. Creamos un Script "AI_Find" y se aplicara a la "Cámara" para que este sea quien busque al pointlight al usar el input creado.
function Start () {
ObjetoLuz = GameObject.Find ("Point Light"); // Asignar a la variable el objeto PointLight de la escena.
}
function Update() {
if (Input.GetKeyDown(KeyCode.Space)) {
//Con el objeto cargado como es luz, entramos al componente de "Light ->light"
ObjetoLuz.light.enabled = false;
}
}
ObjetoLuz.light.enabled = ! ObjetoLuz.light.enabled; //hacer que la luz se apague o prenda al usar la misma tecla (input).
void Start () {
ObjetoLuz = GameObject.FindWithTag ("tag_Point Light"); //Mejor Performance.
}
function Update() {
if (Input.GetKeyDown(KeyCode.Space)) {
// Hacer que al presionar cambie el valor e imprima texto.
if (interruptor){
ObjetoLuz.light.enabled = ! ObjetoLuz.light.enabled;
}
}
}
50
www.3deobox.com
Podemos crear comunicación entre los GameObjects dentro de nuestra escena, esto con el propósito de enviar de un objeto a otro
información de variables y asi poder ejecutar funciones desde un objeto a otro. Esto apoyándonos del Inspector, para crear la conexión
entre los GameObjects y acceder a sus Scripts.
La práctica: será hacer que la cámara de vigilancia enfoque a cada una de los barriles, pero esto será hasta el momento que nosotros
presionemos cada una de las teclas 1 (Barrel_1), 2 (Barrel_2), 3 (Barrel_3) para hacer que gire en ese momento.
1. Importamos la escena“Communication_Inputs”, crearemos 2 scripts, 1 para la “Main Camera” el cual controlara las teclas (1, 2,
3) y otro script para el prefab “prop_cctvCam_body_001” que será el que tendrá las variables de los objetos a mirar (Barriles).
2. Creamos un script ”AI_LookAt” para “prop_cctvCam_body_001” y probamos “En GamePlay” agregar las cajas al transform:
AI_LookAt
//Para poder crear variables publicas y estas no sean mostradas en el inspector agregamos antes de la variable.
[System.NonSerialized]
// Variable para insertar al objeto que estaremos mirando, este debe de ir publico para poder conectarnos con la variable.
public Transform Mirar;
// Creamos una función para solo ejecutarlo cuando lo necesitemos el cambiar la mira sin usar UPDATE (baja rendimiento).
void Update () {
// Función para mirar hacia un objeto de la escena.
transform.LookAt (Mirar);
}
3. Crear Script “AI_Switcher” y asignar a la “Main camera”, este detectará las teclas 1, 2, 3
y conectaremos estos objetos al script “AI_LookAt” en la variable “Mira”, para que se
cambie automáticamente cuando le mande la información de este script al otro script.
AI_Switcher
void Update() {
if (Input.GetKeyDown (KeyCode.Alpha1) ) {
Debug.Log ("Iluminar Barril 1!");
//Conexión entre scripts para mandar variables y ejecutar funciones.
OtroScript.Mirar = vCaja_1;
}
if (Input.GetKeyDown (KeyCode.Alpha2) ){
Debug.Log ("Iluminar Barril 2!");
//Conexión entre scripts para mandar variables y ejecutar funciones.
OtroScript.Mirar = vCaja_2;
}
if (Input.GetKeyDown (KeyCode.Alpha3) ) {
Debug.Log ("Iluminar Barril 3!");
//Conexión entre scripts para mandar variables y ejecutar funciones.
OtroScript.Mirar = vCaja_3;
}
}
4. En el inspector en la “Main Camera” en el componente del script cargamos cada una de los barriles en cada una de las variables.
5. En el inspector en la “Main Camera seleccionada, en el componente del script cargamos la variable de OtroScrip (Prefab Camara).
AI_Switcher
void Update() {
if (Input.GetKeyDown (KeyCode.Alpha1) ) {
Debug.Log ("Iluminar Barril 1!");
//Conexión entre scripts para mandar variables y ejecutar funciones.
OtroScript.Mira = vCaja_1;
OtroScript.Enfocar(); Nota: Esto se repite en el if de caja 2 y 3.
}
}
6. PERFORMANCE: En “AI_LookAt” Cambiamos Update por “Enfocar ()” y dejamos publicola función “public void Enfocar(){}”
de esta manera ahora el buscar que caja iluminara no lo hara constantemente, si no solo hasta presionar las teclas "1, 2 o 3".
53
www.3deobox.com
Podemos crear comunicación entre los GameObjects dentro de nuestra escena, esto con el propósito de enviar de un objeto a otro
información de variables y asi poder ejecutar funciones desde un objeto a otro. Esto apoyándonos del Inspector, para crear la conexión
entre los GameObjects y acceder a sus Scripts.
La práctica: será hacer que la cámara de vigilancia enfoque a cada una de los barriles, pero esto será hasta el momento que nosotros
presionemos cada una de las teclas 1 (Barrel_1), 2 (Barrel_2), 3 (Barrel_3) para hacer que gire en ese momento.
1. Importamos la escena“Communication_Inputs”, crearemos 2 scripts, 1 para la “Main Camera” el cual controlara las teclas (1, 2,
3) y otro script para el prefab “prop_cctvCam_body_001” que será el que tendrá las variables de los objetos a mirar (Barriles).
2. Creamos un script ”AI_LookAt” para “prop_cctvCam_body_001” y probamos “En GamePlay” agregar las cajas al transform:
Script: AI_LookAt
// Creamos una función para solo ejecutarlo cuando lo necesitemos el cambiar la mira sin usar UPDATE (baja rendimiento).
function Update () {
// Función para mirar hacia un objeto de la escena.
transform.LookAt (Mirar);
}
3. Crear Script “AI_Switcher” y asignar a la “Main camera”, este detectará las teclas 1, 2, 3
y conectaremos estos objetos al script “AI_LookAt” en la variable “Mira”, para que se
cambie automáticamente cuando le mande la información de este script al otro script.
Script: AI_Switcher
function Update() {
if (Input.GetKeyDown (KeyCode.Alpha1) ) {
Debug.Log ("Iluminar Barril 1!");
//Conexión entre scripts para mandar variables y ejecutar funciones.
OtroScript.Mirar = vCaja_1;
}
if (Input.GetKeyDown (KeyCode.Alpha2) ){
Debug.Log ("Iluminar Barril 2!");
//Conexión entre scripts para mandar variables y ejecutar funciones.
OtroScript.Mirar = vCaja_2;
}
if (Input.GetKeyDown (KeyCode.Alpha3) ) {
Debug.Log ("Iluminar Barril 3!");
//Conexión entre scripts para mandar variables y ejecutar funciones.
OtroScript.Mirar = vCaja_3;
}
}
4. En el inspector en la “Main Camera” en el componente del script cargamos cada una de los barriles en cada una de las variables.
5. En el inspector en la “Main Camera seleccionada, en el componente del script cargamos la variable de OtroScrip (Prefab Camara).
Script: AI_Switcher
function Update() {
if (Input.GetKeyDown (KeyCode.Alpha1) ){
Debug.Log ("Iluminar Barril 1!");
//Conexión entre scripts para mandar variables y ejecutar funciones.
OtroScript.Mira = vCaja_1;
OtroScript.Enfocar(); Nota: Esto se repite en el if de caja 2 y 3.
}
}
6. PERFORMANCE: En “AI_LookAt” Cambiamos Update por “Enfocar ()” y dejamos publicola función “public function
Enfocar(){}” de esta manera ahora el buscar que caja iluminara no lo hara constantemente, si no solo hasta presionar alguna de las
teclas "1, 2 o 3".
55
www.3deobox.com
Una vez entendido la función del GetComponent, procederemos a usar un efecto de cámara en este caso el de Blur, y lo activaremos por medio de
Inputs, al hacer click izquierdo se active/desactive. El proceso es desde la caja del centro estará checando si se presiona el Botón Izquierdo del Mouse,
y si es así va a buscar a la cámara y entra en el componente de BlurEffect, y lo activara o desactivara.
AI_GetComponent:
if (Input.GetKeyDown (KeyCode.Mouse0) ){
// Activar o desactivar el valor de BlurEffect"
vBlurEffect.GetComponent<BlurEffect>().enabled = ! vBlurEffect.enabled;
}
}
Una vez entendido la función del GetComponent, procederemos a usar un efecto de cámara en este caso el de Blur, y lo activaremos por medio de
Inputs, al hacer click izquierdo se active/desactive. El proceso es desde la caja del centro estará checando si se presiona el Botón Izquierdo del Mouse,
y si es así va a buscar a la cámara y entra en el componente de BlurEffect, y lo activara o desactivara.
AI_GetComponent:
if (Input.GetKeyDown (KeyCode.Mouse0) ){
Instantiate (original: Object, position: Vector3, rotation: Quaternion): Object Crear Instancias en tiempo real del Project.
1. Creamos una escena con un plano y un “Empty Group”, del cual crearemos más objetos.
2. Creamos una Esfera, le asignamos “RidigBody” y la meteremos en un “Prefab”.
3. Creamos un Script “AI_Creator”, y se lo asignaremos al grupo vacio, eh iniciamos el scripting:
AI_Creator
//-------------------
Instantiate (original: Object, position: Vector3, rotation: Quaternion): Object Crear Instancias en tiempo real del Project.
1. Creamos una escena con un plano y un “Empty Group”, del cual crearemos más objetos.
2. Creamos una Esfera, le asignamos “RidigBody” y la meteremos en un “Prefab”.
3. Creamos un Script “AI_Creator”, y se lo asignaremos al grupo vacio, eh iniciamos el scripting:
AI_Creator
var Prefab : Rigidbody;
function Update (){
Instantiate (Prefab, transform.position, transform.rotation);
}
//-------------------
//-------------------
YIELD: Permite pausar líneas de código y cuando se termina el tiempo del yield pasa a la siguiente línea de código,
1. Ejemplo ----- Sin corrutina (No Funciona - No se puede ejecutar dentro de un LoopUpdate una funcion con Espera/Tiempo).
// Ejecucion de Yield dentro un Update, como se debe de poner en formato.
IEnumerator Update () Se debe de usar en lugar Void IEnumerator para poder crear corrutinas siempre.
2. Ejemplo ----- Con corrutina. - (La unica manera de ejecutar Yield dentro de funciones es que no sean de LoopUpdate).
// Ejecucion de Funcion Sencilla detenida por tiempo para ejecutar las lineas y posteriormente el resto de la funcion.
void Start () {
StartCoroutine ( Tiempo () );
Debug.Log (Time.time + " - Ejeucion 1");
}
IEnumerator Tiempo () {
Debug.Log (Time.time + " - Ejecucion 2");
yield return new WaitForSeconds (2.0f);
Debug.Log (Time.time + " - Ejecucion 3");
}
StartCoroutine ( NombreFuncion() ) Se debe de usar para poder ejecutar una función creada que contiene Yield.
3. Ejemplo ----- Con corrutina - (Ejecucion de Funciones y despues de lineas sencillas fuera de la funcion).
// Ejecutar Funcion con Corrutina esto ejecutara todo el contenido de la funcion y luego linea sencilla.
IEnumerator Start () {
yield return StartCoroutine ("Tiempo");
Debug.Log (Time.time + " - Ejeucion 1");
}
IEnumerator Tiempo () {
Debug.Log (Time.time + " - Ejeucion 2");
yield return new WaitForSeconds (2.0f);
Debug.Log (Time.time + " - Ejeucion 3");
}
}
63
www.3deobox.com
void MiFuncion () {
Debug.Log ("Se activo en el segundo: " + Time.time);
}
2. Ejemplo ----- Invoke con Tiempo de Ejecucion y segundos de Repetición.
void ElTiempo () {
Debug.Log ("Se activo en el segundo: " + Time);
}
AI_Shooter
YIELD: Permite pausar líneas de código y cuando se termina el tiempo del yield pasa a la siguiente línea de código,
1. Ejemplo ----- Sin corrutina (No Funciona - No se puede ejecutar dentro de un LoopUpdate una funcion con Espera/Tiempo).
// Ejecucion de Yield dentro un Update, como se debe de poner en formato.
2. Ejemplo ----- Con corrutina. - (La unica manera de ejecutar Yield dentro de funciones es que no sean de LoopUpdate).
// Ejecucion de Funcion Sencilla detenida por tiempo para ejecutar la linea sencilla y posteriormente el resto de la funcion.
function Start () {
Tiempo ();
Debug.Log (Time.time + " - Ejeucion 1");
}
function Tiempo () {
Debug.Log (Time.time + " - Ejecucion 2");
yield WaitForSeconds (2);
Debug.Log (Time.time + " - 3 Ejecucion 3");
}
3. Ejemplo ----- Con corrutina - (Ejecucion de Funciones y despues de lineas sencillas fuera de la funcion).
// Ejecutar Funcion con Corrutina esto ejecutara todo el contenido de la funcion y luego linea sencilla.
function Start () {
yield StartCoroutine ("Tiempo");
Debug.Log (Time.time + " - Ejeucion 1");
}
function Tiempo () {
Debug.Log (Time.time + " - Ejeucion 2");
yield WaitForSeconds (2);
Debug.Log (Time.time + " - Ejeucion 3");
}
65
www.3deobox.com
function FuncionDeo () {
Debug.Log ("Se activo en el segundo: " + Time.time);
}
function ElTiempo () {
Debug.Log ("Se activo en el segundo: " + Time.time);
}
AI_Shooter
function LanzarEsfera () {
Instantiate(vEsfera, transform.position, transform.rotation).velocity = Vector3 (0, 0, Random.Range(1, 20));
}
function Update () {
if (Input.GetKeyDown (KeyCode.Mouse0)){
InvokeRepeating("LanzarEsfera", 0, 1); //Activar de nuevo el Invoke.
} else if (Input.GetKeyDown (KeyCode.Mouse1)){
CancelInvoke (); //Cancelar Invoke.
}
}
66
www.3deobox.com
Podemos cargar películas dentro de Unity, solamente en la versión Profesional, esto nos permite poder poner cinemáticos
dentro del juego, funciona mucho para los inicios o algún tutorial en video que se requiera insertar.
Nota: Necesitamos por fuerzas tener instalado Quicktime, y los formatos que lee son: .mov, .mpg, .mpeg, .mp4, .avi, .asf
Lo ideal es que sea: Formato: Quicktime Compresor: MPG4
1. Creamos una escena con una cámara con proyección " Ortográfica" y creamos un
plano, hacia donde mirara la cámara.
2. Importamos el Video "Diablo_III.mp4", este lo importara tal cual como si fuera
una textura, y dentro tiene el audio del mismo video.
3. Creamos un material de tipo "VertexLight" y aplicamos la textura del video y se
aplicará plano al plano que tenemos en la escena.
4. Sobre el plano, creamos un "Audio Source" y cargamos el audio del video.
5. Ahora para hacer que la textura se reproduzca al iniciar la escena creamos un
Script "AI_PlayMaterial" y se lo asignamos al plano:
Play Movie
void Update () {
if (Input.GetKeyDown (KeyCode.Space)) {
if (Pelicula.isPlaying) {
Pelicula.Pause();
}
else {
Pelicula.Play();
}
}
}
At the End Jump to a scene
if (! Pelicula.isPlaying) {
// Cargar la escena al terminar
}
68
www.3deobox.com
Podemos cargar películas dentro de Unity, solamente en la versión Profesional, esto nos permite poder poner cinemáticos
dentro del juego, funciona mucho para los inicios o algún tutorial en video que se requiera insertar.
Nota: Necesitamos por fuerzas tener instalado Quicktime, y los formatos que lee son: .mov, .mpg, .mpeg, .mp4, .avi, .asf
Lo ideal es que sea: Formato: Quicktime Compresor: MPG4
6. Creamos una escena con una cámara con proyección " Ortográfica" y creamos un
plano, hacia donde mirara la cámara.
7. Importamos el Video "Diablo_III.mp4", este lo importara tal cual como si fuera
una textura, y dentro tiene el audio del mismo video.
8. Creamos un material de tipo "VertexLight" y aplicamos la textura del video y se
aplicará plano al plano que tenemos en la escena.
9. Sobre el plano, creamos un "Audio Source" y cargamos el audio del video.
10. Ahora para hacer que la textura se reproduzca al iniciar la escena creamos un
Script "AI_PlayMaterial" y se lo asignamos al plano:
Play Movie
function Update () {
if (Input.GetKeyDown (KeyCode.Space)) {
if (Pelicula.isPlaying) {
Pelicula.Pause();
}
else {
Pelicula.Play();
}
}
}
At the End Jump to a scene
if (! Pelicula.isPlaying) {
// Cargar la escena al terminar
}
69
www.3deobox.com
Dentro de Unity podemos crear Menús 3D, por medio de escenas las cuales en lugar de crear GUI Planos en 2D se sustituyen por
escenas InGame las cuales fungen como menús interactivos más reales, como puede ser opciones, iniciar juego, créditos, borrar,
crear, etc.
1. Cargamos el paquete 3D Menu y creamos un Script “AI_Botones” y se lo asignamos a cada uno de los botones.
AI_Botones
void OnMouseEnter () {
Boton = true;
}
void OnMouseExit () {
Boton = false;
}
void OnMouseUp () {
//Esta opcion varía de acuerdo al boton
Application.LoadLevel ("_Scene" / 0);
Application.OpenURL ("http://3deobox.com/");
Application.Quit ();
}
void Update () {
Pos = transform.position;
if (Boton) {
transform.position = Vector3.Lerp (transform.position, new Vector3 (Pos.x, Pos.y, 28), Time.deltaTime * 7f);
} else {
transform.position = Vector3.Lerp (transform.position, new Vector3 (Pos.x, Pos.y, 25), Time.deltaTime * 7);
}
}
Dentro de Unity podemos crear Menús 3D, por medio de escenas las cuales en lugar de crear GUI Planos en 2D se sustituyen por
escenas InGame las cuales fungen como menús interactivos más reales, como puede ser opciones, iniciar juego, créditos, borrar,
crear, etc.
1. Cargamos el paquete 3D Menu y creamos un Script “AI_Botones” y se lo asignamos a cada uno de los botones.
AI_Botones
function OnMouseEnter () {
Boton = true;
}
function OnMouseExit () {
Boton = false;
}
function OnMouseUp () {
//Esta opcion varía de acuerdo al boton
Application.LoadLevel ("_Scene" / 0);
Application.OpenURL ("http://3deobox.com/");
Application.Quit ();
}
function Update () {
Pos = transform.position;
if (Boton) {
transform.position = Vector3.Lerp (transform.position, Vector3 (Pos.x, Pos.y, 26), Time.deltaTime * 7);
} else {
transform.position = Vector3.Lerp (transform.position, Vector3 (Pos.x, Pos.y, 25), Time.deltaTime * 7);
}
Dentro de Unity podemos crear objetos con físicas y a estos los podemos controlar por medio de fuerzas físicas.
AI_Door
Dentro de Unity podemos crear objetos con físicas y a estos los podemos controlar por medio de fuerzas físicas.
AI_Door
Podemos saber cuando un objeto con Collider choca con otro objeto cuando tiene el mismo componente (Collider).
1. Creamos una escena sencilla donde tengamos un plano (piso), un muro (caja) y una caja que caiga de arriba para colisionar.
2. Seleccionamos la caja le asignamos “Rigidbody”, y le asignamos en “Box Collider>Material>Bouncy” (para q rebote mas).
3. Creamos y asignamos un script a la caja “AI_Collision” para saber cuándo colisiona la caja con otro objeto con “collision”.
void OnCollisionEnter (){
print ("Objeto en Colisión");
}
4. Ahora queremos saber cuándo colisione con el piso nos indique, esto es bueno para saber cuándo colisiona con un objeto a lo mejor para activar
una puerta o interruptor y cuando sea este haga alguna acción.
AI_Collision
//creamos una variable de tipo colisión para almacenar aquí con quien colisiona
void OnCollisionEnter (Collision vColisionando){
if (vColisionando.gameObject.name == "Cube"){
Destroy (vColisionando.gameObject);
}
}
5. Por último paso si quisiéramos saber con qué objeto colisiona sin importar cual sea:
AI_CollisionContacts
Destroy:
Destroy (gameObject, 3.0f); // Destruye al gameObject en 3 segundos Después.
Destroy (this); // Remueve la instancia de script del gameObject.
Destroy (rigidbody); // Remueve el Componente seleccionado del gameObject.
77
www.3deobox.com
Podemos saber cuando un objeto con Collider choca con otro objeto cuando tiene el mismo componente (Collider).
1. Creamos una escena sencilla donde tengamos un plano (piso), un muro (caja) y una caja que caiga de arriba para colisionar.
2. Seleccionamos la caja le asignamos “Rigidbody”, y le asignamos en “Box Collider>Material>Bouncy” (para q rebote mas).
3. Creamos y asignamos un script a la caja “AI_Collision” para saber cuándo colisiona la caja con otro objeto con “collision”.
function OnCollisionEnter (){
print ("Objeto en Colisión");
}
4. Ahora queremos saber cuándo colisione con el piso nos indique, esto es bueno para saber cuándo colisiona con un objeto a lo mejor para activar
una puerta o interruptor y cuando sea este haga alguna acción.
AI_Collision
//creamos una variable de tipo colisión para almacenar aquí con quien colisiona
function OnCollisionEnter (vColisionando : Collision){
if (vColisionando.gameObject.name == "Cube"){
Destroy (vColisionando.gameObject);
}
}
5. Por último paso si quisiéramos saber con qué objeto colisiona sin importar cual sea:
AI_CollisionContacts
Destroy:
Destroy (gameObject, 3.0f); // Destruye al gameObject en 3 segundos Después.
Destroy (this); // Remueve la instancia de script del gameObject.
Destroy (rigidbody); // Remueve el Componente seleccinado del gameObject.
78
www.3deobox.com
1. Creamos una escena con 1 plano, 2 cajas, 1 de ellas en medio (Plataforma) y la otra que caerá desde arriba con “Rigidbody”.
2. Corremos la escena para ver como caer la caja de arriba sobre la plataforma, pero esta plataforma no hace nada, para moverla…
3. Creamos un Script “AI_Rigidbody” y se lo agregamos a la caja que caerá desde arriba por medio de las físicas.
AI_Rigidbody
Podemos agregar componentes directamente InGame, por medio de Scripting. El ejemplo es que caerá una Caja (Rigidbody) y
colisionara con otra que no tiene al iniciar la escena, pero cuando colisiona con esta le agregamos el componente de Físicas.
1. Creamos una escena con 1 plano, 2 cajas, 1 de ellas en medio (Plataforma) y la otra que caerá desde arriba con “Rigidbody”.
2. Corremos la escena para ver como caer la caja de arriba sobre la plataforma, pero esta plataforma no hace nada, para moverla…
3. Creamos un Script “AI_Rigidbody” y se lo agregamos a la caja que caerá desde arriba por medio de las físicas.
AI_Rigidbody
Una manera de reproducir sonidos es por medio de Scripting, veremos las variaciones para reproducir sonidos en la escena:
1. Creamos una escena con un plano, una caja con “Rigidbody” y le cargamos un “Bounce Material”.
2. Importamos el sonido “bounce”, lo arrastramos a la caja y automáticamente saldrá el “Audio Source”>“Play on Awake: Off”
3. Creamos un script “AI_Audio” para la caja y se lo aplicamos, y haremos que cada rebote se reproduzca el audio “bounce”.
Nota: siempre hay que agregar un Audio Source, para usar sin problemas los audios cargados dentro de las variables.
AI_Audio
void OnCollisionEnter () {
// Reproducir el sonido que este en el Audio Source
audio.Play();
}
4. Para poder cambiar los sonidos del Audio Source, usaremos el componente “PlayOnShot”
AI_Clips
Una manera de reproducir sonidos es por medio de Scripting, veremos las variaciones para reproducir sonidos en la escena:
1. Creamos una escena con un plano, una caja con “Rigidbody” y le cargamos un “Bounce Material”.
2. Importamos el sonido “bounce”, lo arrastramos a la caja y automáticamente saldrá el “Audio Source”>“Play on Awake: Off”
3. Creamos un script “AI_Audio” para la caja y se lo aplicamos, y haremos que cada rebote se reproduzca el audio “bounce”.
Nota: siempre hay que agregar un Audio Source, para usar sin problemas los audios cargados dentro de las variables.
AI_Audio
function OnCollisionEnter () {
// Reproducir el sonido que este en el Audio Source
audio.Play();
}
4. Para poder cambiar los sonidos del Audio Source, usaremos el componente “PlayOnShot”
AI_Clips
Hay una cámara animada a los lados, que al presionar el mouse soltara una bola con físicas, que al tocar la caja blanca aumente 100 puntos por
cada vez que colisione y habrá un sonido al colisionar y al aumentar los puntos, estos puntos se verán en un 3D Text.
1. Cargamos el paquete “SmoothValues_Particles” y creamos un script “AI_Creator” y lo asignamos al creator de la cámara animado.
2. Asignamos Prefab_Ball en la variable Ball.
AI_Creator
void Update ()
{
if (Input.GetMouseButtonDown (0) ) {
Rigidbody RigidBall = Instantiate (PrefabtBall, transform.position, transform.rotation) as Rigidbody;
RigidBall.AddForce (Vector3.forward * 800);
}
}
AI_Ball
void OnCollisionEnter ()
{
Instantiate (PrefabParticle, transform.position, transform.rotation);
Destroy (gameObject);
}
86
www.3deobox.com
5. Ahora las partículas al terminar de emitir partículas se destruirán.
AI_Particle
void Update ( ) {
if (! particleSystem.IsAlive) {
Destroy (gameObject);
}
}
1. Ahora Seleccionamos la caja y le creamos un script “AI_Box” en donde chocaran las Esferas que salgan con fuerza, estas al colisionar
con la caja aumentara de 100 en 100 por cada colision y cambiara el valor sobre el 3D Text.
2. Cargamos el 3DMesh dentro de la variable de “Text3D”.
AI_Box
void Update ()
{
//Animacion de valores.
Ponits = Mathf.MoveTowards (Ponits, NextPoints, smoothTime * Time.deltaTime);
RoundPoints = Mathf.Round (Ponits);
Text3D.GetComponent <TextMesh> ().text = RoundPoints.ToString ();
//Sonido
if (Ponits == NextPoints) {
audio.Stop ();
}
}
void OnCollisionEnter ()
{
//Puntos Extras
NextPoints += 100;
audio.Play ();
}
87
www.3deobox.com
Hay una cámara animada a los lados, que al presionar el mouse soltara una bola con físicas, que al tocar la caja blanca aumente 100 puntos por
cada vez que colisione y habrá un sonido al colisionar y al aumentar los puntos, estos puntos se verán en un 3D Text.
1. Cargamos el paquete “SmoothValues_Particles” y creamos un script “AI_Creator” y lo asignamos al creator de la cámara animado.
2. Asignamos Prefab_Ball en la variable Ball.
AI_Creator
function Update ()
{
if (Input.GetMouseButtonDown (0) ) {
Rigidbody RigidBall = Instantiate (PrefabtBall, transform.position, transform.rotation);
RigidBall.AddForce (Vector3.forward * 800);
}
}
AI_Ball
function OnCollisionEnter ()
{
Instantiate (PrefabParticle, transform.position, transform.rotation);
Destroy (gameObject);
}
88
www.3deobox.com
5. Ahora las partículas al terminar de emitir partículas se destruirán.
AI_Particle
function Update ( ) {
if (! particleSystem.IsAlive) {
Destroy (gameObject);
}
}
3. Ahora Seleccionamos la caja y le creamos un script “AI_Box” en donde chocaran las Esferas que salgan con fuerza, estas al colisionar
con la caja aumentara de 100 en 100 por cada colision y cambiara el valor sobre el 3D Text.
4. Cargamos el 3DMesh dentro de la variable de “Text3D”.
AI_Box
function Update ()
{
//Animacion de valores.
Ponits = Mathf.MoveTowards (Ponits, NextPoints, smoothTime * Time.deltaTime);
RoundPoints = Mathf.Round (Ponits);
Text3D.GetComponent <TextMesh> ().text = RoundPoints.ToString ();
//Sonido
if (Ponits == NextPoints) {
audio.Stop ();
}
}
function OnCollisionEnter ()
{
//Puntos Extras
NextPoints += 100;
audio.Play ();
}
89
www.3deobox.com
Los triggers nos permiten informar cuando el jugador entra o ítem entran, sa mantienen ó salen de un área específica, dentro de unity
basta con poner un objeto con Collider y dentro de sus opciones en el Inspector activamos: Trigger.
1. Cargamos la escena Trigger_Animations, el cual contiene una escena con una luz roja que cambiara de color cuando nos
acerquemos y las puertas se abrirán por medio de una animación simple que tienen cargadas (Clamp Forever).
2. Creamos unos muros para separar cada área, y en medio ponemos “Empty Group” y le asignamos “Box Collider” (Puerta).
3. Creamos un Script “AI_Trigger”, y lo asignamos al trigger que funcionara como cruce de las puertas.
AI_Trigger
void OnTriggerEnter () {
//Velocidad Animaciones
Door_Right.animation ["Clip_Door_R"].speed = 1;
Door_Left.animation ["Clip_Door_L"].speed = 1;
//Animaciones
Door_Right.animation.Play ("Clip_Door_R");
Door_Left.animation.Play ("Clip_Door_L");
//Cambio de color en luz.
SpotLight.color = Color.green;
}
void OnTriggerExit () {
//Velocidad Animaciones
Door_Right.animation ["Clip_Door_R"].speed = -1;
Door_Left.animation ["Clip_Door_L"].speed = -1;
//Animaciones
Door_Right.animation.Play ("Clip_Door_R");
Door_Left.animation.Play ("Clip_Door_L");
//Cambio de color en luz.
SpotLight.color = Color.red;
}
91
www.3deobox.com
Los triggers nos permiten informar cuando el jugador entra o ítem entran, sa mantienen ó salen de un área específica, dentro de unity
basta con poner un objeto con Collider y dentro de sus opciones en el Inspector activamos: Trigger.
1. Cargamos la escena Trigger_Animations, el cual contiene una escena con una luz roja que cambiara de color cuando nos
acerquemos y las puertas se abrirán por medio de una animación simple que tienen cargadas (Clamp Forever).
2. Creamos unos muros para separar cada área, y en medio ponemos “Empty Group” y le asignamos “Box Collider” (Puerta).
3. Creamos un Script “AI_Trigger”, y lo asignamos al trigger que funcionara como cruce de las puertas.
AI_Trigger
function OnTriggerEnter () {
//Velocidad Animaciones
Door_Right.animation ["Clip_Door_R"].speed = 1;
Door_Left.animation ["Clip_Door_L"].speed = 1;
//Animaciones
Door_Right.animation.Play ("Clip_Door_R");
Door_Left.animation.Play ("Clip_Door_L");
//Cambio de color en luz.
SpotLight.color = Color.green;
}
function OnTriggerExit () {
//Velocidad Animaciones
Door_Right.animation ["Clip_Door_R"].speed = -1;
Door_Left.animation ["Clip_Door_L"].speed = -1;
//Animaciones
Door_Right.animation.Play ("Clip_Door_R");
Door_Left.animation.Play ("Clip_Door_L");
//Cambio de color en luz.
SpotLight.color = Color.red;
}
92
www.3deobox.com
1. Cargamos la escena Animation Events, que tiene ya un carácter controller (Player) y un pregab (Elevator).
2. En el Elevator cambiamos el Collider Trigger en la plataforma del Elevador para activar cuando entr solamente el Player.
3. Desactivamos “Play Automatically” y Creamos un Script “AI_Elevador” y se lo asignamos al Elevator.
AI_Elevator
Creamos funciones (EVENTOS) para cambiar de colores la plataforma e indique cuando este en movimiento.
//Reproducción de Animacion con transición (Blending) de acuerdo a tiempo (se puede tener varios tipos de animación)
animation.CrossFade("Elevator ", 0.5f)
95
www.3deobox.com
1. Cargamos la escena Animation Events, que tiene ya un carácter controller (Player) y un pregab (Elevator).
2. En el Elevator cambiamos el Collider Trigger en la plataforma del Elevador para activar cuando entr solamente el Player.
3. Desactivamos “Play Automatically” y Creamos un Script “AI_Elevador” y se lo asignamos al Elevator.
AI_Elevador
Creamos funciones (EVENTOS) para cambiar de colores la plataforma e indique cuando este en movimiento.
AI_Distance
void Update () {
Distance = Mathf.Round ( Vector3.Distance (Character.position, transform.position) );
GetComponent <TextMesh>().text = Round.ToString () + " mts";
void Update () {
Distance = Mathf.Round ( Vector3.Distance (Character.position, transform.position) );
GetComponent<TextMesh>().text = Round.ToString () + " mts";
AI_Distance
function Update () {
Distance = Mathf.Round ( Vector3.Distance (Character.position, transform.position) );
GetComponent <TextMesh>().text = Round.ToString () + " mts";
function Update () {
Distance = Mathf.Round ( Vector3.Distance (Character.position, transform.position) );
GetComponent<TextMesh>().text = Round.ToString () + " mts";
1.30 SLOWMOTION.
101
www.3deobox.com
Para controlar la velocidad general de la escena se usa Time.timeScale, pero para poder hacerlo individualmente por objeto es diferente:
AI_Camera
void Update () {
print (“DeltaTime: ” Time.deltaTime);
print (“DeltaTime: ” Time. fixedDeltaTime);
if (Input.GetKeyDown (KeyCode.Mouse0)) {
Time.timeScale = 0.1f;
print ("Slowmotion Speed");
}
if (Input.GetKeyDown (KeyCode.Mouse1)) {
Time.timeScale = 1.0f;
print ("Normal Speed");
}
AI_CarSpeed
void Update () {
if (Delta == fps.Normal) {
vDeltaTime = Time.fixedDeltaTime;
} else {
vDeltaTime = Time.deltaTime;
}
transform.Translate (Vector3.forward * Time. fixedDeltaTime * 0.6f, Space.Self);
}
102
www.3deobox.com
Para controlar la velocidad general de la escena se usa Time.timeScale, pero para poder hacerlo individualmente por objeto es diferente:
AI_Camera
void Update () {
print (“DeltaTime: ” Time.deltaTime);
print (“DeltaTime: ” Time. fixedDeltaTime);
if (Input.GetKeyDown (KeyCode.Mouse0)) {
Time.timeScale = 0.1f;
print ("Slowmotion Speed");
}
if (Input.GetKeyDown (KeyCode.Mouse1)) {
Time.timeScale = 1.0f;
print ("Normal Speed");
}
AI_CarSpeed
void Update () {
if (Delta == fps.Normal) {
vDeltaTime = Time.fixedDeltaTime;
} else {
vDeltaTime = Time.deltaTime;
}
transform.Translate (Vector3.forward * Time. fixedDeltaTime * 0.6f, Space.Self);
}
103
www.3deobox.com
Podemos Optimizar el performance de los scripts de una manera muy sencilla, si estos no estan dentro del area donde la camara los
tenga que ver, lo que se debe de hacer es desactivar el script del objeto, asi ahorramos esos procesos si no se ven y reactivarlos de
nuevo al momento que entren en la vision de la camara.
AI_Box
Podemos Optimizar el performance de los scripts de una manera muy sencilla, si estos no estan dentro del area donde la camara los
tenga que ver, lo que se debe de hacer es desactivar el script del objeto, asi ahorramos esos procesos si no se ven y reactivarlos de
nuevo al momento que entren en la vision de la camara.
AI_Box
Raycasting permite lanzar un rayo desde un origen hacia una dirección, con una distancia de lanzamiento y al colisionar puede
darnos muchos parámetros de información como distancia del rayo al colisionar, nombres, collider, etc.
AI_Creator
void Update () {
if (Input.GetKeyDown (KeyCode.Mouse0) ){
Instantiate (Nave, transform.position, transform.rotation);
}
}
AI_PrefabNave
void Update () {
if (RayActivator) {
//Dibujar una línea para verlo InGame.
Debug.DrawRay (transform.position, Vector3.down * RayDistance, Color.red);
IEnumerator Wings () {
RayActivator = false; // Se desactive el NO poder lanzar más el rayo.
animation.Play ("Animation");
yield return new WaitForSeconds (0.05f);
rigidbody.drag = 15f;
}
108
www.3deobox.com
Raycasting permite lanzar un rayo desde un origen hacia una dirección, con una distancia de lanzamiento y al colisionar puede
darnos muchos parámetros de información como distancia del rayo al colisionar, nombres, collider, etc.
AI_Creator
var Nave : GameObject;
function Update () {
if (Input.GetKeyDown (KeyCode.Mouse0) ){
Instantiate (Nave, transform.position, transform.rotation);
}
}
AI_PrefabNave
function Update () {
if (RayActivator) {
//Dibujar una línea para verlo InGame.
Debug.DrawRay (transform.position, Vector3.down * RayDistance, Color.red);
function Wings () {
RayActivator = false; // Se desactive el NO poder lanzar más el rayo.
animation.Play ("Animation");
yield WaitForSeconds (0.05);
rigidbody.drag = 15f;
}
109
www.3deobox.com
En esta practica lo que haremos es hacer que un objeto Fijo, rote hacia la direccion del raton, esto sirve para generar un juego donde
podriamos tener un personaje o una torre de ataque y esta dispare en direccion a donde este el mouse o al hacer click en una area.
RaycastHit:
-----------
point: --El punto de impacto en WorldSpace donde colisiono el rayo.
normal: --La cara de la normal donde imapacto el rayo.
distance: --La distancia desde el origen del rayo a donde impacto.
collider: --Con el Collider que colisiono.
rigidbody: --Rigidbody con collider al que pego (si no tiene rigid el valor es nulo).
AI_Box
void Update(){
//variable con la posicion de donde esta el mouse en la patanlla
Ray Rayo = Camera.main.ScreenPointToRay (Input.mousePosition);
En esta practica lo que haremos es hacer que un objeto Fijo, rote hacia la direccion del raton, esto sirve para generar un juego donde
podriamos tener un personaje o una torre de ataque y esta dispare en direccion a donde este el mouse o al hacer click en una area.
RaycastHit:
-----------
point: --El punto de impacto en WorldSpace donde colisiono el rayo.
normal: --La cara de la normal donde imapacto el rayo.
distance: --La distancia desde el origen del rayo a donde impacto.
collider: --Con el Collider que colisiono.
rigidbody: --Rigidbody con collider al que pego (si no tiene rigid el valor es nulo).
AI_Box
function Update(){
//variable con la posicion de donde esta el mouse en la patanlla
Rayo : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
Sensitivity: 1 = Unidades en la que se moverá la cámara cuando usemos el scroll.
Type: Mouse Movements (cuando se usa alguna acción del mouse, en este caso el scroll).
Axis: 3rd Axis (activar el uso de botón del Mouse de en medio - Scroll).
6. Cámara: creamos un script “AI_Zoom” el efecto de usar Scroll y la camara se deplaza suavemente.
AI_Zoom Básico:
void Update () {
//Obtener el valor del uso de Axis = Scroll con su valor de sensitivity =1
float mouseWheel = Input.GetAxis ("Mouse Wheel");
vPosicionZ -= 1.0f;
vPosicionY -= 1.0f;
}
// Si se usa el scroll hacia abajo recudir el valor (Zoom-Out).
else if (Input.GetAxis ("Mouse Wheel") < 0f){
vPosicionZ += 1.0f;
vPosicionY += 1.0f;
}
// Mover la camara hacia el nuevo valor sobre el eje de las "Z".
transform.position = Vector3.Lerp (transform.position, new Vector3 (transform.position.x, vPosicionY, vPosicionZ), vVelocidad * Time.deltaTime);
}
114
www.3deobox.com
7. Player: Rigidbody>Freeze Rotation X, Y, Z (para al desplazar no rote con la velocidad y se caiga).
MOVING:
Physics.Raycast
Raycast (origin : Vector3, direction : Vector3, distance : float=Mathf.Infinity,layerMask : int=kDefaultRaycastLayers) : boolean
Lanza un rayo contra todos los colliders en la escena.
Parametros:
origin --The starting point of the ray in world coordinates.
direction --La direccion del rayo.
distance --La longitus del rayo.
layerMask --MaskLayer se usada para ignorar colliders al lanzar el rayo.
RaycastHit:
-----------
point: --El punto de impacto en WorldSpace donde colisiono el rayo.
normal: --La cara de la normal donde imapacto el rayo.
distance: --La distancia desde el origen del rayo a donde impacto.
collider: --Con el Collider que colisiono.
rigidbody: --El Rigidbody del collider con el que pego (si no tiene rigid el valor es nulo).
ROTATING:
Plane.Raycast
void Raycast (ray : Ray, out enter : float) : boolean
Intersecta un rayo con el plano, la funcion permite saber la distancia a lo largo del rayo donde intersecta con el plano.
Ray:
--------
origin: --El punto de origen del rayo -> Rayo.origin : Vector3.
direction: --La direccion del Rayo -> Rayo.direction : Vector3.
GetPoint: --Devuelve un punto en unidades de distancia a lo largo del rayo --> Rayo.GetPoint(Hit) : Vector3.
115
www.3deobox.com
8. Player: se le dará la habilidad de desplazarse donde se dé un click sobre la escena, creamos un Script “AI_Moving”:
AI_Moving
if (Input.GetKeyDown(KeyCode.Mouse0) ){
// Genera un Rayo desde la posición de la cámara hacia el puntero del mouse.
Ray rayo = Camera.main.ScreenPointToRay (Input.mousePosition);
//Si el rayo colisiona con un collider regresara el "True", el rayo se lanza a 100 unidades de distnacia (Sin Distancia es "infinito").
// Rayo, HitInfo, Distancia.
if (Physics.Raycast (rayo, out Hit, 100)){
//Obtener la posición donde colision HIT (x, y, z).
PosDest = Hit.point;
}
}
//Mover al personaje cada que cambie la PosicionDestino (Vector3.Lerp "Smooth" / Vector3.MoveTowards "Constant").
transform.position = Vector3.MoveTowards (transform.position, PosDest, Velocidad * Time.deltaTime);
----------------------------------------------------------------------------------------------------------------------------------------
//PARA EVITAR QUE EL PERSONAJE BRINQUE HACIA ARRIBA, LO MOVEMOS SOLO EN LOS EJES: "X" y "Z"
transform.position = Vector3.MoveTowards(transform.position,new Vector3(PosDest[0],transform.position.y,PosDest[2]),Time.deltaTime * Velocidad);
X Y Z
116
www.3deobox.com
9. Player: Por último agregaremos la habilidad de que pueda rotar el personaje en dirección a donde este el mouse “AI_Rotating".
AI_Rotating
//Variable para girar con suavidad
public float GirarVelocidad = 4.0f;
//Variable para guardar la distancia del Hit.
private float HitDist;
//Variable para almacenar la posición donde se haga click.
private float PosDet;
void FixedUpdate () {
// Generar un Plano virtual al centro del personaje sobre el eje "Y"
Plane PlanoVirtual = new Plane (Vector3.up, transform.position);
// Lanzar un Rayo desde la posicion de la camara principal hacia la posicion del mouse.
Ray Rayo = Camera.main.ScreenPointToRay (Input.mousePosition);
// Angulos de Rotación: Obtener posicion de Mouse en Pantalla "X,Z" --> Conversion a Rotacion para el eje "Y".
Quaternion AnguloRot = Quaternion.LookRotation(PosicionPlano - transform.position);
// ROTACAION (Suave/Directa).
transform.rotation = AnguloRot; // Opcion 1
transform.rotation = Quaternion.Slerp(transform.rotation, RotarPlayer, Time.deltaTime * GirarVelocidad);
}
117
www.3deobox.com
modificara:
Sensitivity: 1 = Unidades en la que se moverá la cámara cuando usemos el scroll.
Type: Mouse Movements (cuando se usa alguna acción del mouse, en este caso el scroll).
Axis: 3rd Axis (activar el uso de botón del Mouse de en medio - Scroll).
6. Cámara: creamos un script “AI_Zoom” el efecto de usar Scroll y la camara se deplaza suavemente.
AI_Zoom Básico:
function Update () {
//Obtener el valor del uso de Axis = Scroll con su valor de sensitivity =1
var mouseWheel : float = Input.GetAxis ("Mouse Wheel");
AI_Zoom Avanzado:
//Variable con la distancia donde este la camara (Checar posicion inicial en Z).
private var vPosicionZ : float = 4.0;
private var vPosicionY : float = 5.0;
var vVelocidad : int;
}
118
www.3deobox.com
7. Player: Rigidbody>Freeze Rotation X, Y, Z (para al desplazar no rote con la velocidad y se caiga).
MOVING:
Physics.Raycast
Raycast (origin : Vector3, direction : Vector3, distance : float=Mathf.Infinity,layerMask : int=kDefaultRaycastLayers) : boolean
Lanza un rayo contra todos los colliders en la escena.
Parametros:
origin --The starting point of the ray in world coordinates.
direction --La direccion del rayo.
distance --La longitus del rayo.
layerMask --MaskLayer se usada para ignorar colliders al lanzar el rayo.
RaycastHit:
-----------
point: --El punto de impacto en WorldSpace donde colisiono el rayo.
normal: --La cara de la normal donde imapacto el rayo.
distance: --La distancia desde el origen del rayo a donde impacto.
collider: --Con el Collider que colisiono.
rigidbody: --El Rigidbody del collider con el que pego (si no tiene rigid el valor es nulo).
ROTATING:
Plane.Raycast
function Raycast (ray : Ray, out enter : float) : boolean
Intersecta un rayo con el plano, la funcion permite saber la distancia a lo largo del rayo donde intersecta con el plano.
Ray:
--------
origin: --El punto de origen del rayo -> Rayo.origin : Vector3.
direction: --La direccion del Rayo -> Rayo.direction : Vector3.
GetPoint: --Devuelve un punto en unidades de distancia a lo largo del rayo --> Rayo.GetPoint(Hit) : Vector3.
119
www.3deobox.com
8. Player: se le dará la habilidad de desplazarse donde se dé un click sobre la escena, creamos un Script “AI_Moving”:
AI_Moving
if (Input.GetKeyDown(KeyCode.Mouse0) ){
// Genera un Rayo desde la posición de la cámara hacia el puntero del mouse.
var rayo : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
//Si el rayo colisiona con un collider regresara el "True", el rayo se lanza a 100 unidades de distnacia (Sin Distancia es "infinito").
// Rayo, HitInfo, Distancia.
if (Physics.Raycast (rayo, Hit, 100)){
//Obtener la posición donde colision HIT (x, y, z).
PosDest = Hit.point;
}
}
//Mover al personaje cada que cambie la PosicionDestino (Vector3.Lerp "Smooth" / Vector3.MoveTowards "Constant").
transform.position = Vector3.MoveTowards (transform.position, PosDest, Velocidad * Time.deltaTime);
----------------------------------------------------------------------------------------------------------------------------------------
//PARA EVITAR QUE EL PERSONAJE BRINQUE HACIA ARRIBA, LO MOVEMOS SOLO EN LOS EJES: "X" y "Z"
transform.position = Vector3.MoveTowards(transform.position,Vector3(PosDest[0],transform.position.y,PosDest[2]),Velocidad * Time.deltaTime);
X Y Z
120
www.3deobox.com
9. Player: Por último agregaremos la habilidad de que pueda rotar el personaje en dirección a donde este el mouse “AI_Rotating".
AI_Rotating
//Variable para girar con suavidad
var GirarVelocidad = 4.0;
//Variable para guardar la distancia del Hit.
private var HitDist : float;
//Variable para almacenar la posición donde se haga click.
private var PosDet : Vector3;
function FixedUpdate () {
// Generar un Plano virtual al centro del personaje sobre el eje "Y"
var PlanoVirtual : Plane = new Plane(Vector3.up, transform.position);
// Lanzar un Rayo desde la posicion de la camara principal hacia la posicion del mouse.
var Rayo : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
// ROTACAION (Suave/Directa).
//transform.rotation = targetRotation;
transform.rotation = Quaternion.Slerp (transform.rotation, RotarPlayer, Time.deltaTime * GirarVelocidad);
}
}
121
www.3deobox.com
TEXTURE PROPERTIES:
SET OFFSET:
"_MainTex" Es la textura del main diffuse. Este solo se acceso vía propiedades de “mainTexture”.
"_BumpMap" Es el normal map.
"_Cube" Es el reflection del cubemap.
void Update () {
// Cambiar el Offset del Diffuse en "X" progresivamente haciendo que su máximo sea el 1 %.
renderer.material.SetTextureOffset ("_MainTex", new Vector2 (vOffset % 1, 0));
void Update () {
// Variable de tipo ping pong con un Min y Max por el tiempo transcurrido.
float vPinpong = Mathf.PingPong (Time.time * 0.3f, 1);
SET COLORS:
SET SHADINGS:
void Start () {
// Control de las características del material.
renderer.material.SetColor ("_Color", Color.red);
renderer.material.SetColor ("_SpecColor", Color.green);
renderer.material.SetColor ("_Emission", Color.blue);
renderer.material.SetColor ("_ReflectColor", Color.white);
}
SET MATERIALS:
// Controla el Blending entre materiales que tengan las mismas texturas (solo cambien características).
Material Material1;
Material Material2;
TEXTURE PROPERTIES:
SET OFFSET:
"_MainTex" Es la textura del main diffuse. Este solo se acceso vía propiedades de “mainTexture”.
"_BumpMap" Es el normal map.
"_Cube" Es el reflection del cubemap.
function Update () {
function Update () {
// Variable de tipo ping pong con un Min y Max por el tiempo transcurrido.
var vPinpong : float = Mathf.PingPong (Time.time * 0.3, 1);
SET COLORS:
SET SHADINGS:
function Start () {
// Control de las características del material.
renderer.material.SetColor ("_Color", Color.red);
renderer.material.SetColor ("_SpecColor", Color.green);
renderer.material.SetColor ("_Emission", Color.blue);
renderer.material.SetColor ("_ReflectColor", Color.white);
}
SET MATERIALS:
// Controla el Blending entre materiales que tengan las mismas texturas (solo cambien características).
var Material1 : Material;
var Material2 : Material;
AI_SIMPLE_LINE
// Variables
public int Columns = 7;
public float Framerate = 5f;
//
private float TextureSize;
private float OffsetX;
void Start ()
{
void Atlas_One_Line ()
{
//OFFSET MAT.
renderer.material.SetTextureOffset ("_MainTex", new Vector2 (OffsetX, 0));
OffsetX += TextureSize; // Avance de Columnas (X)
}
130
www.3deobox.com
AI_MULTI_LINES
//Variables
public int Columns = 7;
public int Rows = 4;
public float Framerate = 30f;
//
private Vector2 TextureSize;
private float OffsetX;
private float OffsetY;
void Start ()
{
//COLUMNAS: Ajustar el tamaño de la textura 1X1 (Unidades de UV).
TextureSize = new Vector2 (1f / Columns, 1f / Rows);
//TILLING MAT: Modificar el Tilling (X) para tener alto y ancho por altas.
renderer.material.SetTextureScale ("_MainTex", TextureSize);
//En el caso de este ejemplo de 5 Col y 7 fila -> X:0.2, Y:0.142857
OffsetX = TextureSize [0];
OffsetY = -TextureSize [1];
//OFFSET MAT: Modificar el Offset para dezplazarnos al 1er Atlas.
renderer.material.SetTextureOffset ("_MainTex", new Vector2 (0, OffsetY));
//PLAY: Invocar función con una repetición por segundos
InvokeRepeating ("Atlas_Multi_GUI", 1f / Framerate, 1f / Framerate);
}
void Atlas_Multi_GUI ()
{
//OFFSET MAT.
renderer.material.SetTextureOffset ("_MainTex", new Vector2 (OffsetX, OffsetY));
1 2 3
131
www.3deobox.com
AI_MULTI_GUI
void Start ()
{
//COLUMNA-FILAS Ajustar el tamaño de la textura 1X1 (Unidades de UV).
TextureSize = new Vector2 (1f / Columns, 1f / Rows);
//TILLING MAT: Modificar el Tilling (X,Y) para solo ver el 1er Atlas.
renderer.material.SetTextureScale ("_MainTex", TextureSize);
//En el caso de este ejemplo de 5 Col y 7 fila -> X:0.2, Y:0.142857
OffsetX = TextureSize [0];
OffsetY = -TextureSize [1];
//OFFSET MAT: Ver la primer Linea-Columna.
renderer.material.SetTextureOffset ("_MainTex", new Vector2 (0, OffsetY));
//Invocar función con inicio y repeticion igual en segundos.
InvokeRepeating ("Atlas_Multi_GUI", 1f / Framerate, 1f / Framerate);
}
void Atlas_Multi_GUI ()
{
//OFFSET MAT.
renderer.material.SetTextureOffset ("_MainTex", new Vector2 (OffsetX, OffsetY));
AI_SIMPLE_LINE
// Variables
var Columns : int = 7;
var Framerate : float = 5;
//
var TextureSize : float;
var OffsetX : float;
function Start ()
{
function Atlas_One_Line ()
{
//OFFSET MAT.
renderer.material.SetTextureOffset ("_MainTex", Vector2 (OffsetX, 0));
OffsetX += TextureSize; // Avance de Columnas (X)
}
133
www.3deobox.com
AI_MULTI_LINES
//Variables
var Columns : int = 7;
var Rows : int = 4;
var Framerate : float = 30f;
//
private var TextureSize : Vector2;
private var OffsetX : float;
private var OffsetY : float;
function Start ()
{
//COLUMNAS: Ajustar el tamaño de la textura 1X1 (Unidades de UV).
TextureSize = Vector2 (1 / Columns, 1 / Rows);
//TILLING MAT: Modificar el Tilling (X) para tener alto y ancho por altas.
renderer.material.SetTextureScale ("_MainTex", TextureSize);
//En el caso de este ejemplo de 5 Col y 7 fila -> X:0.2, Y:0.142857
OffsetX = TextureSize [0];
OffsetY = -TextureSize [1];
//OFFSET MAT: Modificar el Offset para dezplazarnos al 1er Atlas.
renderer.material.SetTextureOffset ("_MainTex", Vector2 (0, OffsetY));
//PLAY: Invocar función con una repetición por segundos
InvokeRepeating ("Atlas_Multi_GUI", 1 / Framerate, 1 / Framerate);
}
function Atlas_Multi_GUI ()
{
//OFFSET MAT.
renderer.material.SetTextureOffset ("_MainTex", Vector2 (OffsetX, OffsetY));
} 1 2 3
134
www.3deobox.com
AI_MULTI_GUI
void Start ()
{
//COLUMNA-FILAS Ajustar el tamaño de la textura 1X1 (Unidades de UV).
TextureSize = Vector2 (1 / Columns, 1 / Rows);
//TILLING MAT: Modificar el Tilling (X,Y) para solo ver el 1er Atlas.
renderer.material.SetTextureScale ("_MainTex", TextureSize);
//En el caso de este ejemplo de 5 Col y 7 fila -> X:0.2, Y:0.142857
OffsetX = TextureSize [0];
OffsetY = -TextureSize [1];
//OFFSET MAT: Ver la primer Linea-Columna.
renderer.material.SetTextureOffset ("_MainTex", Vector2 (0, OffsetY));
//Invocar función con inicio y repeticion igual en segundos.
InvokeRepeating ("Atlas_Multi_GUI", 1 / Framerate, 1 / Framerate);
}
void Atlas_Multi_GUI ()
{
//OFFSET MAT.
renderer.material.SetTextureOffset ("_MainTex", Vector2 (OffsetX, OffsetY));
Formato para Imágenes: PSD, PNG TGA, el factor de estos formatos es que pueden guardar información de transparencia.
1. Importamos la imagen Interface.jpg y Continue_A y _B, en Inspector>Format lo dejamos en Type: GUI, Type: True Color.
2. Creamos 2 (Interface, Continue_A): GameObject>Create Other> GUI Texture, cargamos cada uno en el valor de Texture.
3. Para tener como capaz de GUI, solo se deben de mover en el eje de profundidad de la cámara, en este caso sobre Z.
4. Importamos la tipografía “bloktilt” de Files y creamos GameO bject>Create Other> GUI Text (Le ponemos la tipografía), Para hacer que
la imagen de fondo quede siempre al centro en X & Y y/o se ajuste a la resolución Creamos un Script “AI_Interface” para la interfaz:
137
www.3deobox.com
5. Creamos un Script “AI_Counter” y se lo asignamos al Int_Counter:
Nota: no podemos imprimir variables numéricas en GUIs, hay que convertirlas de Numéricas a Strings.
AI_Counter
IEnumerator Start () {
//COUNTER
audio.Play ();
// GAME OVER
if (i < 0){
print ("Funciona");
1 2
138
www.3deobox.com
6. Creamos un Script “AI_Continue” y se lo asignamos a Int_Continue:
AI_Continue
void OnMouseEnter () {
GUI_Texture.texture = vTexture_B;
audio.Play ();
}
void OnGUI() {
// Boton Sencillo.
if (GUI.Button (Rect (10,70,50,30),"Boton") ){
Debug.Log ("Click con boton con texto");
}
Texture btnTexture;
void OnGUI() {
// Boton con Imagen.
if (GUI.Button (Rect (10,10,50,50), btnTexture)) {
Debug.Log ("Click con boton con imagen");
}
}
// Cambio de color en el material del texto // Cambio dinámico del estilo del texto
GUI_Text.material.color = Color.red/blue/green/white; GUI_TextfontStyle = FontStyle.Bold;
Formato para Imágenes: PSD, PNG TGA, el factor de estos formatos es que pueden guardar información de transparencia.
1. Importamos la imagen Interface.jpg y Continue_A y _B, en Inspector>Format lo dejamos en Type: GUI, Type: True Color.
2. Creamos 2 (Interface, Continue_A): GameObject>Create Other> GUI Texture, cargamos cada uno en el valor de Texture.
3. Para tener como capaz de GUI, solo se deben de mover en el eje de profundidad de la cámara, en este caso sobre Z.
4. Importamos la tipografía “bloktilt” de Files y creamos GameO bject>Create Other> GUI Text (Le ponemos la tipografía), Para hacer que
la imagen de fondo quede siempre al centro en X & Y y/o se ajuste a la resolución Creamos un Script “AI_Interface” para la interfaz:
141
www.3deobox.com
Nota: no podemos imprimir variables numéricas en GUIs, hay que convertirlas de Numéricas a Strings.
AI_Counter
function Start () {
//COUNTER
audio.PlayOneShot (Sonido);
// GAME OVER
if (i < 0){
//Application.LoadLevel (NivelCargar);
1 2
142
www.3deobox.com
AI_Continue
function OnMouseEnter () {
GUI_Texture.texture = vTexture_B;
audio.Play ();
}
function OnGUI() {
// Boton Sencillo.
if (GUI.Button (Rect (10,70,50,30),"Boton") ){
Debug.Log ("Click con boton con texto");
}
function OnGUI() {
// Boton con Imagen.
if (GUI.Button (Rect (10,10,50,50), btnTexture)) {
Debug.Log ("Click con boton con imagen");
}
}
GUI TEXT BASIC PROPERTIES. // Cambio dinámico del tamaño del texto
GUI_Text.fontSize = 12;
// Cambio de color en el material del texto
GUI_Text.material.color = Color.red/blue/green/white; // Cambio dinámico del estilo del texto
GUI_TextfontStyle = FontStyle.Bold;
Nota: Siempre debe de estar en 4:3 la proporción par aver que funcione correctamente esta función que creamos.
144
www.3deobox.com
Podemos crear barras de energías o ítems especiales por medio de GUIs, donde pueden tener transparencias, degradados,
y efectos que podemos crear desde Photoshop.
AI_Ball
// ANIMACION ESTILO PINGPONG
public float Velocidad;
public float Distancia;
public float Altura;
private float PosY;
void Update () {
PosY = Mathf.PingPong (Time.time * Velocidad, Distancia) + Altura;
transform.position = new Vector3 (transform.position.x, PosY, transform.position.z);
}
3. Ahora cada que toquemos una de las esferas se destruirá, reproducirá un sonido y asignaremos una variable de vida, para qu e
al tocar cada esfera esta suba un 10%.
// CAMBIO DE TEXTURAS
public Texture v20;
public Texture v30;
public Texture v40;
public Texture v50;
public Texture v60;
public Texture v70;
public Texture v80;
public Texture v90;
public Texture v100;
void OnTriggerEnter () {
audio.Play ();
Destroy (gameObject, 0.5f);
Vida += 10;
print (Vida);
4. Creamos un GUI Texture "GUI_Bar", para cargar la barra donde se mostraran las texturas con los porcentajes.
5. Creamos un GUI Texture "GUI_Life", para cargar los imagenes de los porcentajes que se mostraran encima de la barra de energía.
6. Creamos un GUI Text "GUI_Text", para mostrar el porcentaje de lo que se lleva cargado de manera contextual de la barra de
energía.
147
www.3deobox.com
7. Agregamos al OnTrigerEnter la variable de "Vida", cada que colisiones, para que aumente de 10 en 10 en su valor Numerico y de
Textura, asi de esta manera dara el efecto de que cambia el Porcentaje y la barra de vida va aumentando y cambia de colores.
AI_Ball
void Start () {
GUI_Life = GameObject.Find ("GUI_Life");
GUI_Text = GameObject.Find ("GUI_Text");
}
void Update () {
if (Vida == 20){
GUI_Life.GUI_Texture.texture = v20;
GUI_Text.GUI_Text.text = Vida.ToString() + "%";
}else if (Vida == 30){
GUI_Life.GUI_Texture.texture = v30;
GUI_Text.GUI_Text.text = Vida.ToString() + "%";
}
else if(Vida == 40){
GUI_Life.GUI_Texture.texture = v40;
GUI_Text.GUI_Text.text = Vida.ToString() + "%";
}
else if(Vida == 50){
GUI_Life.GUI_Texture.texture = v50;
GUI_Text.GUI_Text.text = Vida.ToString() + "%";
}
else if(Vida == 60){
GUI_Life.GUI_Texture.texture = v60;
GUI_Text.GUI_Text.text = Vida.ToString() + "%";
}
else if (Vida == 70){
GUI_Life.GUI_Texture.texture = v70;
GUI_Text.GUI_Text.text = Vida.ToString() + "%";
}
else if (Vida == 80){
GUI_Life.GUI_Texture.texture = v80;
GUI_Text.GUI_Text.text = Vida.ToString() + "%";
}
else if (Vida == 90){
GUI_Life.GUI_Texture.texture = v90;
GUI_Text.GUI_Text.text = Vida.ToString() + "%";
}
else if(Vida == 100){
GUI_Life.GUI_Texture.texture = v100;
GUI_Text.GUI_Text.text = Vida.ToString() + "%";
}
}
148
www.3deobox.com
Podemos crear barras de energías o ítems especiales por medio de GUIs, donde pueden tener transparencias, degradados,
y efectos que podemos crear desde Photoshop.
AI_Ball
// ANIMACION ESTILO PINGPONG
var Velocidad : float;
var Distancia : float;
var Altura : float;
var PosY : float;
function Update () {
PosY = Mathf.PingPong (Time.time * Velocidad, Distancia) + Altura;
transform.position = new Vector3 (transform.position.x, PosY, transform.position.z);
}
3. Ahora cada que toquemos una de las esferas se destruirá, reproducirá un sonido y asignaremos una variable de vida, para que
al tocar cada esfera esta suba un 10%.
// CAMBIO DE TEXTURAS
var v20 : Texture;
var v30 : Texture;
var v40 : Texture;
var v50 : Texture;
var v60 : Texture;
var v70 : Texture;
var v80 : Texture;
var v90 : Texture;
var v100 : Texture;
function OnTriggerEnter () {
audio.Play ();
Destroy (gameObject, 0.5);
Vida += 10;
print (Vida);
4. Creamos un GUI Texture "GUI_Bar", para cargar la barra donde se mostraran las texturas con los porcentajes.
5. Creamos un GUI Texture "GUI_Life", para cargar los imagenes de los porcentajes que se mostraran encima de la barra de energía.
6. Creamos un GUI Text "GUI_Text", para mostrar el porcentaje de lo que se lleva cargado de manera contextual de la barra de
energía.
150
www.3deobox.com
8. Agregamos al OnTrigerEnter la variable de "Vida", cada que colisiones, para que aumente de 10 en 10 en su valor Numerico y de
Textura, asi de esta manera dara el efecto de que cambia el Porcentaje y la barra de vida va aumentando y cambia de colores.
AI_Ball
void Start () {
GUI_Life = GameObject.Find ("GUI_Life");
GUI_Text = GameObject.Find ("GUI_Text");
}
void Update () {
if (Vida == 20){
GUI_Life.GUI_Texture.texture = v20;
GUI_Text.GUI_Text.text = Vida.ToString() + "%";
}else if (Vida == 30){
GUI_Life.GUI_Texture.texture = v30;
GUI_Text.GUI_Text.text = Vida.ToString() + "%";
}
else if(Vida == 40){
GUI_Life.GUI_Texture.texture = v40;
GUI_Text.GUI_Text.text = Vida.ToString() + "%";
}
else if(Vida == 50){
GUI_Life.GUI_Texture.texture = v50;
GUI_Text.GUI_Text.text = Vida.ToString() + "%";
}
else if(Vida == 60){
GUI_Life.GUI_Texture.texture = v60;
GUI_Text.GUI_Text.text = Vida.ToString() + "%";
}
else if (Vida == 70){
GUI_Life.GUI_Texture.texture = v70;
GUI_Text.GUI_Text.text = Vida.ToString() + "%";
}
else if (Vida == 80){
GUI_Life.GUI_Texture.texture = v80;
GUI_Text.GUI_Text.text = Vida.ToString() + "%";
}
else if (Vida == 90){
GUI_Life.GUI_Texture.texture = v90;
GUI_Text.GUI_Text.text = Vida.ToString() + "%";
}
else if(Vida == 100){
GUI_Life.GUI_Texture.texture = v100;
GUI_Text.GUI_Text.text = Vida.ToString() + "%";
}
}
151
www.3deobox.com
Blending de Animación : Es cuando se realiza transiciones entre clips de animaciones en un personaje de manera profesional.
Animacion Velocidad: Podemos modificar la velocidad de cualqueir animacino, y en negativo convierte la animacino atrás (reversa).
3. Insertamos el personaje en el escenario, y en la cámara Smooth Follow cargamos Soldier para que lo siga.
4. Con el Player seleccionado agregaremos los siguientes scripts Componen>Character> FPS InputController:
o Character Controller: permite agregar dinámicas al personaje para colisionar en la escena.
o Character Motor (Script): agrega componentes para poder controlar el mover, saltar, desplazar, etc.
o FPS InputController: El cual permite controlar por inputs los componentes
5. Player: Componen>Camera-Control> Mouse Look: Seleccionar eje X, el player rotara sobre el eje X del ratón.
6. Creamos un Script “AI_Character” lo asignamos al “player” para crear el control de animaciones Idle, Walk:
AI_Character
void Update () {
//CAMINAR ADELANTE.
if (Input.GetAxis ("Vertical") > 0.1f){
animation.Play("Walk");
}
}
//IDLE AL NO CAMINAR.
else if (Input.GetAxis ("Vertical") < 0.1f) {
animation.Play("Idle");
}
void FixUpdate () {
//CAMINAR ADELANTE.
if (Input.GetAxis ("Vertical") > 0.1f){
animation.CrossFade("Walk", 0.2f);
}
//IDLE AL NO CAMINAR.
else if (Input.GetAxis ("Vertical") < 0.1f){
animation.CrossFade ("Idle", 0.1f);
}
}
9. Ahora para regular la velocidad del personaje entrando al Character Motor en Movement de manera
dinámica (abrir el Class de CharacterMotorMovement y ver los maxForward, Sideway y Backwards
Speeds).
// Variables para controlar caminar y correr.
private CharacterMotor Motor;
public float vWalk = 1.5f;
void Start () {
//Crear variable para obtener los componentes de character controller
Motor = GetComponent <CharacterMotor>();
}
void FixedUpdate () {
// CAMINAR ADELANTE.
if (Input.GetAxis ("Vertical") > 0.1f){
animation.CrossFade("Walk", 0.2f);
}
155
www.3deobox.com
10. Ahora agregamos un Input para usar la animación de correr: Run - “shift left”.
AI_Character
void FixedUpdate () {
//CAMINAR ADELANTE
if (Input.GetAxis ("Vertical") > 0.1f){
animation.CrossFade("Walk", 0.2f);
// IDLE AL NO CAMINAR.
else if (Input.GetAxis ("Vertical") < 0.1f){
animation. CrossFade ("Idle", 0.1f);
}
//-------------------------------------------------------------
//CORRER ADELANTE
if (Input.GetAxis ("Vertical") > 0.1f && Input.GetKey (KeyCode.LeftShift) ){
animation.CrossFade("Run", 0.2f);
AI_Character
// Variables para controlar caminar y correr.
private CharacterMotor Motor;
public float vWalk = 1.0f;
public float vRun = 5.0f;
function FixedUpdate () {
//Crear variable para obtener los componentes de character controller
CharacterMotor Motor = GetComponent<CharacterMotor<();
AI_Character
// Variables para controlar caminar y correr.
private CharacterMotor Motor;
public float vWalk = 1.0f;
public float vRun = 5.0f;
function FixedUpdate () {
//Crear variable para obtener los componentes de character controller
CharacterController controllers = GetComponent<CharacterController>();
if (controllers.isGrounded){
//Crear variable para obtener los componentes de characterMotor
CharacterMotor Motor = GetComponent<CharacterMotor>();
}else {
animation.CrossFade ("Jump", 0.1f);
}
}
158
www.3deobox.com
Blending de Animación : Es cuando se realiza transiciones entre clips de animaciones en un personaje de manera profesional.
Animacion Velocidad: Podemos modificar la velocidad de cualqueir animacino, y en negativo convierte la animacino atrás (reversa).
3. Insertamos el personaje en el escenario, y en la cámara Smooth Follow cargamos Soldier para que lo siga.
4. Con el Player seleccionado agregaremos los siguientes scripts Componen>Character> FPS InputController:
a. Character Controller: permite agregar dinámicas al personaje para colisionar en la escena.
b. Character Motor (Script): agrega componentes para poder controlar el mover , saltar, desplazar, etc.
c. FPS InputController: El cual permite controlar por inputs los componentes
5. Player: Componen>Camera-Control> Mouse Look: Seleccionar eje X, el player rotara sobre el eje X del ratón.
6. Creamos un Script “AI_Character” lo asignamos al “player” para crear el control de animaciones Idle, Walk:
AI_Character
function Update () {
//CAMINAR ADELANTE.
if (Input.GetAxis ("Vertical") > 0.1){
animation.Play("Walk");
}
}
//IDLE AL NO CAMINAR.
else if (Input.GetAxis ("Vertical") < 0.1) {
animation.Play("Idle");
}
function FixUpdate () {
//CAMINAR ADELANTE.
if (Input.GetAxis ("Vertical") > 0.1f){
animation.CrossFade("Walk", 0.2f);
}
//IDLE AL NO CAMINAR.
else if (Input.GetAxis ("Vertical") < 0.1f){
animation.CrossFade ("Idle", 0.1f);
}
}
9. Ahora para regular la velocidad del personaje entrando al Character Motor en Movement de manera
dinámica (abrir el Class de CharacterMotorMovement y ver los maxForward, Sideway y Backwards
Speeds).
// Variables para controlar caminar y correr.
Private var Motor : CharacterMotor;
Public var vWalk : float = 1.5f;
function Start () {
//Crear variable para obtener los componentes de character controller
Motor = GetComponent (CharacterMotor);
}
function FixedUpdate () {
// CAMINAR ADELANTE.
if (Input.GetAxis ("Vertical") > 0.1f){
animation.CrossFade("Walk", 0.2f);
}
161
www.3deobox.com
10. Ahora agregamos un Input para usar la animación de correr: Run - “shift left”.
AI_Character
function FixedUpdate () {
//CAMINAR ADELANTE
if (Input.GetAxis ("Vertical") > 0.1){
animation.CrossFade("Walk", 0.2);
// IDLE AL NO CAMINAR.
else if (Input.GetAxis ("Vertical") < 0.1){
animation. CrossFade ("Idle", 0.1);
}
//-------------------------------------------------------------
//CORRER ADELANTE
if (Input.GetAxis ("Vertical") > 0.1 && Input.GetKey (KeyCode.LeftShift) ){
animation.CrossFade("Run", 0.2);
AI_Character
// Variables para controlar caminar y correr.
private var Motor : CharacterMotor;
public var vWalk : float = 1.0;
public var vRun : float = 5.0;
function FixedUpdate () {
//Crear variable para obtener los componentes de character controller
CharacterMotor Motor = GetComponent (CharacterMotor);
AI_Character
// Variables para controlar caminar y correr.
Private var Motor : CharacterMotor;
Public var vWalk : float = 1.0f;
Public var vRun : float = 5.0f;
function FixedUpdate () {
//Crear variable para obtener los componentes de character controller
CharacterController controllers = GetComponent<CharacterController>();
if (controllers.isGrounded){
//Crear variable para obtener los componentes de characterMotor
CharacterMotor Motor = GetComponent<CharacterMotor>();
}else {
animation.CrossFade ("Jump", 0.1);
}
}
164
www.3deobox.com
Unity puede ahorrar el trabajo de creación de clips de animación ya que permite mezclar clips de animaciones y esto nos ahorrar
animaciones, lo cual se ve impactado en performance. La forma de mezclar animaciones lo más común es dividir de la cadera hacia
arriba en una mezcla de clips, así de esta manera puede estar caminando, corriendo o en Idle, y podría estar disparando o haciendo
algún movimiento con las manos.
1. En el Personaje dentro del componente de Animation, cargamos los clips de animaciones individuales (Idle, shoot, Jump, Run).
2. Activamos "Play Automatically" para que no inicie ninguna animación sobre el personaje.
6. Ahora sobre el script creado iniciamos el proceso de insertar los clips, dentro de layers por importancia para poder mezclarlos.
AI_MixAnimations
void Update () {
//Correr - Idle
if ( Input.GetAxis("Vertical") > 0.1f) {
animation.CrossFade("run", 0.2f);
animation["run"].speed = Input.GetAxis("Vertical") + 1;
}else {
animation.CrossFade("idle", 0.2f);
}
//Brincar - Sin KeyDown para dejar presionado y activar animación
if (Input.GetKey (KeyCode.Space) ){
animation.CrossFade("jump", 0.2f);
}
// Disparar - Sin KeyDown para dejar presionado y activar animación
if (Input.GetKey (KeyCode.Mouse0) ){
animation.Play ("shoot");
}
}
167
www.3deobox.com
7. Ahora haremos control de clips por medio de inputs, para simular el personaje en movimiento y usando los clips de animación. La idea
es que haya Fade entre las animaciones y aparte la mezcla de los clips de la mitad de la cadera hacia arriba, para ahorrar el crear esas
animaciones por separado y tener que hacer también mas scripting.
AI_MixAnimations
void Start () {
// Hacer que todas los clips esten en modo Loop.
animation.wrapMode = WrapMode.Loop;
//Menos estos clips de animacion.
animation["shoot"].wrapMode = WrapMode.Once;
animation["jump"].wrapMode = WrapMode.Once;
void Update () {
// Clip de Correr con Fade.
if ( Input.GetAxis("Vertical") > 0.1f) {
animation.CrossFade("run", 0.2f);
// Inicio Lento (0) con fade a velocidad de (1+1=2), porque es lenta la animación de Run.
animation["run"].speed = Input.GetAxis("Vertical")+1;
}else {
//Al no presionar nada reproducir Idle Clip.
animation.CrossFade("idle", 0.2f);
}
// Clip de Brincar con Fade.
if (Input.GetKeyDown (KeyCode.Space) ){
animation.CrossFade("jump", 0.2f);
}
// Shoot Clip al hacer click
if (Input.GetKeyDown (KeyCode.Mouse0) ){
//Reproducir la animacion con Fade, y permite reproducir aun que no termine la animación (recomendado par anim. cortas.
animation.CrossFadeQueued("shoot", 0.15f, QueueMode.PlayNow);
}
}
168
www.3deobox.com
Unity puede ahorrar el trabajo de creación de clips de animación ya que permite mezclar clips de animaciones y esto nos ahorrar
animaciones, lo cual se ve impactado en performance. La forma de mezclar animaciones lo más común es dividir de la cadera hacia
arriba en una mezcla de clips, así de esta manera puede estar caminando, corriendo o en Idle, y podría estar disparando o haciendo
algún movimiento con las manos.
1. En el Personaje dentro del componente de Animation, cargamos los clips de animaciones individuales (Idle, shoot, Jump, Run).
2. Activamos "Play Automatically" para que no inicie ninguna animación sobre el personaje.
6. Ahora sobre el script creado iniciamos el proceso de insertar los clips, dentro de layers por importancia para poder mezclarlos.
AI_MixAnimations
void Update () {
//Correr - Idle
if ( Input.GetAxis("Vertical") > 0.1f) {
animation.CrossFade("run", 0.2f);
animation["run"].speed = Input.GetAxis("Vertical") + 1;
}else {
animation.CrossFade("idle", 0.2f);
}
//Brincar - Sin KeyDown para dejar presionado y activar animación
if (Input.GetKey (KeyCode.Space) ){
animation.CrossFade("jump", 0.2f);
}
// Disparar - Sin KeyDown para dejar presionado y activar animación
if (Input.GetKey (KeyCode.Mouse0) ){
animation.Play ("shoot");
}
}
170
www.3deobox.com
7. Ahora haremos control de clips por medio de inputs, para simular el personaje en movimiento y usando los clips de animación. La idea
es que haya Fade entre las animaciones y aparte la mezcla de los clips de la mitad de la cadera hacia arriba, para ahorrar el crear esas
animaciones por separado y tener que hacer también mas scripting.
AI_MixAnimations
function Start () {
// Hacer que todas los clips esten en modo Loop.
animation.wrapMode = WrapMode.Loop;
//Menos estos clips de animacion.
animation["shoot"].wrapMode = WrapMode.Once;
animation["jump"].wrapMode = WrapMode.Once;
}
function Update () {
}
171
www.3deobox.com
CHARA
1.41 CHARACTER ANIMATIONS – LEGACY RAGDOLLS
172
www.3deobox.com
Para hacer que un personaje cuando muera se sustituya por un ragdoll, y este tenga la misma posición de rotación de cada uno de los
joints se hace lo siguiente:
1. Cargamos el paquete “Ragdoll_Scene” y la carpeta de “Jane” que contiene el Mesh y las animaciones.
2. Insertamos el personaje “Jane” en la escena y creamos un Ragdoll de la mismo (GameObject>Create Other>Ragdoll).
3. Hacemos todo el Re Mapeado de los Joints de acuerdo a la siguiente tabla y le damos Create.
4. Hay que Eliminar el Componente de “Animation” para que solo quede el mesh como Ragdoll, sin componentes.
5. Al terminar el personaje Jane con Ragdoll lo meteremos en un Prefab y lo podemos eliminamos de la escena.
173
www.3deobox.com
6. Insertamos de nuevo del Project a Jane el cual usaremos como personaje para controlar con Animaciones.
7. Seleccionamos al personaje y animaciones y en Rig lo dejamos como: Legacy, y activamos en Loop todas las animaciones.
8. Creamos un script “AI_Ragdoll” y lo asignamos al personaje Jane y cargamos la animación “Run”:
AI_Ragdoll
if (Input.GetKeyDown (KeyCode.Mouse0)) {
// Instancia para cambiar por ragdoll
Transform Inst_Ragdoll =
Instantiate (vRagdoll, transform.position, transform.rotation) as Transform;
}
174
www.3deobox.com
Para hacer que un personaje cuando muera se sustituya por un ragdoll, y este tenga la misma posición de rotación de cada uno de los
joints se hace lo siguiente:
1. Cargamos el paquete “Ragdoll_Scene” y la carpeta de “Jane” que contiene el Mesh y las animaciones.
2. Insertamos el personaje “Jane” en la escena y creamos un Ragdoll de la mismo (GameObject>Create Other>Ragdoll).
3. Hacemos todo el Re Mapeado de los Joints de acuerdo a la siguiente tabla y le damos Create.
4. Hay que Eliminar el Componente de “Animation” para que solo quede el mesh como Ragdoll, sin componentes.
5. Al terminar el personaje Jane con Ragdoll lo meteremos en un Prefab y lo podemos eliminamos de la escena.
175
www.3deobox.com
6. Insertamos de nuevo del Project a Jane el cual usaremos como personaje para controlar con Animaciones.
7. Seleccionamos al personaje y animaciones y en Rig lo dejamos como: Legacy, y activamos en Loop todas las animaciones.
8. Creamos un script “AI_Ragdoll” y lo asignamos al personaje Jane y cargamos la animación “Run”:
AI_Ragdoll
if (Input.GetKeyDown (KeyCode.Mouse0)) {
// Instancia para cambiar por ragdoll
var Inst_Ragdoll : Transform =
Instantiate (vRagdoll, transform.position, transform.rotation) as Transform;
}
176
www.3deobox.com
Unity tiene el sistema automatizado para control de Estados de Animacion para personajes con un editor grafico llamado Mecanims.
Mecanim es un sistema totalmente visual, para crear Transiciones esntre animaciones, árbol de control de multiples animaciones,
herramientas especiales para animaciones por medio de Mocap, asi como Mezcla de animaciones por medio de layers.
AI_Cha_Animations
private Animator Anim; | private var Anim : Animator;
13. Ahora crearemos “Blend Tree” para agregar dentro WalkB, WalkBTurn Left y Right y lo conectamos directo en Idle.
14. Sobre el nuevo Blend tree cambiamos el nombre a “Walks Back”, samos 2click y entramos en el Clip.
15. Dentro agregamos “Add Motion Field” (+), para crear 3 Slots de Clips vacios y asignar ahí los siguientes clips de animación.
16. Ahora cambiamos la conexión de Idle con el nuevo Blend Tree (Walks Back – 3 Clips) y eliminamos el clip de solo WalkBack.
185
www.3deobox.com
17. Para poder controlar el cambio de animaciones hacia los lados tanto
para camianr como correr crearemos una variable dentro de
mecanims, “Parameters>Direction (Float)”, ahora lo asignamos
en dentro de “BlendTree - Walks Back” en
“Parameter>Direction”, además de cambiar el valor de Motions
de: -1 a 1, el cual será el valor que obtendremos del input de
GetAxis que va de -1 a 1.
18. Transiciones La variable Direction nos permitirá cambiar de: (-1) WalkBTurnLeft, (0) WalkB, (1) WalkBTurnRight.
19. Regresamos al Script del Personaje y agregamos una línea para controlar la nueva variable “Direction”.
AI_Cha_Animations
}
186
www.3deobox.com
20. Ahora Copiamos el Blend Tree, cambiando el nombre “Walks Fordward”, asignamos las animaciones de WalkF y WalkLeft/Right.
21. Ahora ajustamos los valores de las nuevas transiciones [Speed>-0.1 (), Speed<-0.1()].
//RUN
Una vez más creamos otro nuevo “Blend Tree” o copiamos uno de los anteriores y lo nombramos “Runs” y entramos en el.
22. Habra 3 Slots (Run, RunLeft y RunRight), Motion: Min -1 a Max 1 (GetAxis) y usamos en Parameter la variable “Direction”.
23. Creamos una Nuevo “Parameters>Run” (Bool).
AI_Cha_Animations
Runs Jump:
Jump Run:
WalkFordward Jump:
Jump WalkFordward:
AI_Cha_Animations
26. Creamos un nuevo “Avatar Body Mask” y desactivamos las partes que no queremos mezclar con las animaciones.
27. Vamos a Base Layer y creamos un nuevo layer “Hello Layer” y en Human cargamos “Dude Mask”.
28. Ahora sobre el “Hello Layer” creamos un “Empty Clip” para que no se reproduzca nada al iniciar en este layer.
29. Creamos una nuevo “Parameters>Hello (Bool)” para asignar en las condiciones de crear transiciones
(Conexiones).
30. Ahora insertamos el Clip de animación “Hello” y creamos las conexiones al “New State Hello” (Empty Clip):
AI_Cha_Animations
Nota: Ya se pueden ompartir las animacion con otros personajes (El Robot –
deberá tener su Propio Avatar ya que es otro personaje con diferente setup).
189
www.3deobox.com
static function IgnoreCollision (collider1 : Collider, collider2 : Collider, ignore : boolean = true) : void
1. Cargamos el paquete con la escena “FPS Scene”, se creará un personaje que cargue un arma, lance misiles explosivos.
2. Insertamos el “rocketLauncher” y lo acomodamos como arma al personaje para emparentarlo después a la cámara.
3. Insertamos el “Rocket” en la escena y le Asignamos Rigidbody y desactivamos la gravedad (Use Gravity: Of).
4. Rocket: Le emparentamos un “Point Light” y le ajustamos los parámetros que mas nos gusten.
5. Rocket: Le agregamos un Audio Soucer, cargamos el audio “RocketLauncherFire”.
6. Rocket: Le asignamos un Box Collider y se ajustara al tamaño del Rocket.
7. Gun: Creamos un Script “AI_Gun” y se lo asignamos al _Prefab_Gun>RocketLauncher.
AI_RocketLauncher
void Update () {
//Click Izquierdo.
if( Input.GetKeyDown ( KeyCode.Mouse0 ) ){
//Agregar velocidad constante al Misil creado en la escena dirigido hacia adelante (Z).
RocketInst.velocity = transform.forward * Speed;
// Normalmente se disparara desde un personaje y para evitar que colision con el personaje:
Physics.IgnoreCollision (RocketInst.collider, transform.root.collider, true);
Nota: Aqui probar con una caja antes de las partículas para mostrar la dirección del objeto.
}
}
191
www.3deobox.com
static function OverlapSphere (position : Vector3, radius : float, layerMask : int = kAllLayers) : Collider[]
function AddExplosionForce (explosionForce : float, explosionPosition : Vector3, explosionRadius : float, upwardsModifier : float = 0.0F, mode : ForceMode = ForceMode.Force) : void
Ahora se creara el efecto de que cuando la bala se impacte y genere el efecto de explosión, haremos que el sistema de partículas se
emita cuando colisione la bala, y se coloque en el polígono que colisiono (posición y cara normal).
AI_Rocket
//POSICIÓN: "contactPoint" permite obtener la posición "x,y,z" con lo que colisiona, (primer objeto = 0).
ContactPoint ObjImpactPos = vCollision.contacts[0];
//ROTACIÓN: Saber sobre qué cara de la normal colisiono (Vector3.Up = Cara de la Normal Frontal).
Quaternion ObjImpactRot = Quaternion.FromToRotation (Vector3.up, ObjImpactPos.normal);
// OBJETO (POS, ROT): crear instancia de la explosión, en la posición donde colisiono el rocket.
Instantiate (ParticleExplotion, ObjImpactPos.point, ObjImpactRot);
//Al impactar el misil creara una esfera, y los objetos que esten dentro de su radio con collider se almacenaran en un arreglo.
Collider[] ObjColl = Physics.OverlapSphere (transform.position, ExplosionRadius);
//Descargamos cada uno de los "Objeto con collider" dentro de la variable "hit".
foreach (Collider Hit in ObjColl){
//Y Si el objeto colisionado tiene asignado "collider" y "Rigidbod".
if (Hit.rigidbody){
//Agregamos impulso desde donde colisiono el Misicl hacia el objeto para hacerlo volar.
Hit.rigidbody.AddExplosionForce (ExplosionPower, transform.position, ExplosionRadius);
}
}
}
192
www.3deobox.com
static function IgnoreCollision (collider1 : Collider, collider2 : Collider, ignore : boolean = true) : void
1. Cargamos el paquete con la escena “FPS Scene”, se creará un personaje que cargue un arma, lance misiles explosivos.
2. Insertamos el “rocketLauncher” y lo acomodamos como arma al personaje para emparentarlo después a la cámara.
3. Insertamos el “Rocket” en la escena y le Asignamos Rigidbody y desactivamos la gravedad (Use Gravity: Of).
4. Rocket: Le emparentamos un “Point Light” y le ajustamos los parámetros que mas nos gusten.
5. Rocket: Le agregamos un Audio Soucer, cargamos el audio “RocketLauncherFire”.
6. Rocket: Le asignamos un Box Collider y se ajustara al tamaño del Rocket.
7. Gun: Creamos un Script “AI_Gun” y se lo asignamos al _Prefab_Gun>RocketLauncher.
AI_RocketLauncher
function Update () {
//Click Izquierdo.
if( Input.GetKeyDown ( KeyCode.Mouse0 ) ){
//Agregar velocidad constante al Misil creado en la escena dirigido hacia adelante (Z).
RocketInst.velocity = transform.forward * Speed;
// Normalmente se disparara desde un personaje y para evitar que colision con el personaje:
Physics.IgnoreCollision (RocketInst.collider, transform.root.collider, true);
Nota: Aqui probar con una caja antes de las partículas para mostrar la dirección del objeto.
}
}
193
www.3deobox.com
static function OverlapSphere (position : Vector3, radius : float, layerMask : int = kAllLayers) : Collider[]
function AddExplosionForce (explosionForce : float, explosionPosition : Vector3, explosionRadius : float, upwardsModifier : float = 0.0F, mode : ForceMode = ForceMode.Force) : void
Ahora se creara el efecto de que cuando la bala se impacte y genere el efecto de explosión, haremos que el sistema de partículas se
emita cuando colisione la bala, y se coloque en el polígono que colisiono (posición y cara normal).
AI_Rocket
//POSICIÓN: "contactPoint" permite obtener la posición "x,y,z" con lo que colisiona, (primer objeto = 0).
var ObjImpactPos : Collision = vCollision.contacts[0];
//ROTACIÓN: Saber sobre qué cara de la normal colisiono (Vector3.Up = Cara de la Normal Frontal).
var ObjImpactRot : Quaternion = Quaternion.FromToRotation (Vector3.up, ObjImpactPos.normal);
// OBJETO (POS, ROT): crear instancia de la explosión, en la posición donde colisiono el rocket.
Instantiate (ParticleExplotion, ObjImpactPos.point, ObjImpactRot);
//Al impactar el misil creara una esfera, y los objetos que esten dentro de su radio con collider se almacenaran en un arreglo.
var ObjColl : Collider[] = Physics.OverlapSphere (transform.position, ExplosionRadius);
//Descargamos cada uno de los "Objeto con collider" dentro de la variable "hit".
foreach (Collider Hit in ObjColl){
//Y Si el objeto colisionado tiene asignado "collider" y "Rigidbod".
if (Hit.rigidbody){
//Agregamos impulso desde donde colisiono el Misicl hacia el objeto para hacerlo volar.
Hit.rigidbody.AddExplosionForce (ExplosionPower, transform.position, ExplosionRadius);
}
}
}
194
www.3deobox.com
Para Pausar el juego necesitamos detener el audio y los movimiento del carácter controller por medio del “MouseLook” en X & Y creando
un Script “AI_Pause” y lo asignamos a la cámara.
AI_Pause
void Start ()
{
//Ocultar Mouse
Screen.showCursor = false;
}
void Update ()
{
if (Input.GetKeyDown (KeyCode.Escape) ) {
GamePause = !GamePause;
if (GamePause) {
//PAUSE
Time.timeScale = 0f; //Pause
AudioListener.pause = true; //Mute
Screen.showCursor = true; //show
//Nodejar que se mueva el Character controller con el Mouse.
CharacterMouseX.GetComponent <MouseLook> ().enabled = false;
CameraMouseY.GetComponent <MouseLook> ().enabled = false;
} else {
//NO PAUSE
Time.timeScale = 1f; // No Pause
AudioListener.pause = false; // sound
Screen.showCursor = false; // Hide
// Dejar que se mueva el Character controller con el Mouse.
CharacterMouseX.GetComponent <MouseLook> ().enabled = true; //Activar Mouse Look en X en el personaje.
CameraMouseY.GetComponent <MouseLook> ().enabled = true; //Activar Mouse Look en Y en la cámara.
}
print ("Pause: " + GamePause);
}
}
196
www.3deobox.com
Para Pausar el juego necesitamos detener el audio y los movimiento del carácter controller por medio del “MouseLook” en X & Y creando
un Script “AI_Pause” y lo asignamos a la cámara.
AI_Pause
function Start ()
{
Screen.showCursor = false; //Ocultar Mouse
}
function Update ()
{
if (Input.GetKeyDown KeyCode.Escape) ) {
GamePause = !GamePause;
if (GamePause) {
//PAUSE
Time.timeScale = 0; //Pause
AudioListener.pause = true; //Mute
Screen.showCursor = true; //show
//Nodejar que se mueva el Character controller con el Mouse.
CharacterMouseX.GetComponent (MouseLook).enabled = false;
CameraMouseY.GetComponent (MouseLook>).enabled = false;
} else {
//NO PAUSE
Time.timeScale = 1; // No Pause
AudioListener.pause = false; // sound
Screen.showCursor = false; // Hide
//Dejar que se mueva el Character controller con el Mouse.
CharacterMouseX.GetComponent (MouseLook).enabled = true; //Activar Mouse Look en X en el personaje.
CameraMouseY.GetComponent (MouseLook).enabled = true; //Activar Mouse Look en Y en la cámara.
}
print ("Pause: " + GamePause);
}
}
197
www.3deobox.com
Se puede usar Game Controller de Generico, Xbox y Playstation para poder controlar las acciones de nuestro juego re mapeando los
botones del control y sustituirlos por el uso del teclado y mouse, generando juegos con orientación a consolas o PC NextGen.
Edit>Project Settings>Inputs. Configuracion de Inputs: Gravity: 0.0 | Dead: 0.3 | Sensitivity: 1
BOTONES (Buttons del 0 – 11 en Y Axis) AXIS (3TH, 4TH, 5TH, 6TH 7TH, 8TH, X & Y en Axis)
UNITY INPUTS SCRIPT KEYCODE Gravity: Cuan rapido se centrara el Input (teclado/Mouse).
joystick 1 button 0 KeyCode.JoystickButon0
Dead: Los valores positivos o negativos que son menos que este
joystick 1 button 1 KeyCode.JoystickButon1
número se registrarán como cero (Joysticks).
joystick 1 button 2 KeyCode.JoystickButon2
joystick 1 button 3 KeyCode.JoystickButon3 Sensivity: Para Teclado/Joysticks, controla la suavidad, en valores
joystick 1 button 4 KeyCode.JoystickButon4 altos es rápido y en bajos son suaves (GetAxis -1 a 0 a 1).
joystick 1 button 5 KeyCode.JoystickButon5
joystick 1 button 6 KeyCode.JoystickButon6 Input.GetAxis ("AXIS") <= | >= | != | == float
joystick 1 button 7 KeyCode.JoystickButon7 Input.GetButtonDown ("AXIS") Boolean
joystick 1 button 8 KeyCode .JoystickButon8 Input.GetButtonUp ("AXIS") Boolean
joystick 1 button 9 KeyCode .JoystickButon9
joystick 1 button 10 KeyCode .JoystickButon10 Nota: Copiar el archivo “InputManager.asset” del Game Controller que deseas
usar (Xbox/Play/Generico).
joystick 1 button 11 KeyCode .JoystickButon11
199
www.3deobox.com
TRIGGERS
STICK IZQ
D-PAD
STICK DER
200
www.3deobox.com
TRIGGERS
D-PAD
STICK DER
STICK IZQ
201
www.3deobox.com
AI_Rocket_Launcher
if (Input.GetKeyDown (KeyCode.Mouse0) || Input.GetKeyDown (KeyCode.Joystick1Button7)) {}
Nota: Los inputs los estoy haciendo con base a mi Game Controller Generico.
AI_Pause
if (Input.GetKeyDown (KeyCode.Escape) || Input.GetKeyDown (KeyCode.JoystickButton9) ) {}
AI_JoystickRotate
void Update ()
{
//JOYSTICK SIDES – CONTINUO (Rotate).
if (Input.GetAxis ("X_JoyStick") >= 0.1f || Input.GetAxis ("X_JoyStick") <= -0.1f) {
transform.Rotate (Vector3.up * Input.GetAxis ("X_JoyStick") * SpeedJoystick * Time.deltaTime);
}
//JOYSTICK UPDOWN - NO CONTINUO (localEulerAngles).
if (Input.GetAxis ("Y_Joystick") >= 0.1f || Input.GetAxis ("Y_Joystick") <= -0.1f) {
RotationY += Input.GetAxis ("Y_Joystick") * SpeedJoystick * Time.deltaTime;
RotationY = Mathf.Clamp (RotationY, MinY, MaxY);
vCamera.transform.localEulerAngles = Vector3.right * RotationY;
}
}
203
www.3deobox.com
Se puede usar Game Controller de Generico, Xbox y Playstation para poder controlar las acciones de nuestro juego re mapeando los
botones del control y sustituirlos por el uso del teclado y mouse, generando juegos con orientación a consolas o PC NextGen.
Edit>Project Settings>Inputs. Configuracion de Inputs: Gravity: 0.0 | Dead: 0.3 | Sensitivity: 1
BOTONES (Buttons del 0 – 11 en Y Axis) AXIS (3TH, 4TH, 5TH, 6TH 7TH, 8TH, X & Y en Axis)
UNITY INPUTS SCRIPT KEYCODE Gravity: Cuan rapido se centrara el Input (teclado/Mouse).
joystick 1 button 0 KeyCode.JoystickButon0
Dead: Los valores positivos o negativos que son menos que este
joystick 1 button 1 KeyCode.JoystickButon1
número se registrarán como cero (Joysticks).
joystick 1 button 2 KeyCode.JoystickButon2
joystick 1 button 3 KeyCode.JoystickButon3 Sensivity: Para Teclado/Joysticks, controla la suavidad, en valores
joystick 1 button 4 KeyCode.JoystickButon4 altos es rápido y en bajos son suaves (GetAxis -1 a 0 a 1).
joystick 1 button 5 KeyCode.JoystickButon5
joystick 1 button 6 KeyCode.JoystickButon6 Input.GetAxis ("AXIS") <= | >= | != | == float
joystick 1 button 7 KeyCode.JoystickButon7 Input.GetButtonDown ("AXIS") Boolean
joystick 1 button 8 KeyCode .JoystickButon8 Input.GetButtonUp ("AXIS") Boolean
joystick 1 button 9 KeyCode .JoystickButon9
joystick 1 button 10 KeyCode .JoystickButon10 Nota: Copiar el archivo “InputManager.asset” del Game Controller que deseas
usar (Xbox/Play/Generico).
joystick 1 button 11 KeyCode .JoystickButon11
204
www.3deobox.com
TRIGGERS
STICK IZQ
D-PAD
STICK DER
205
www.3deobox.com
TRIGGERS
D-PAD
STICK DER
STICK IZQ
206
www.3deobox.com
DETECTOR DE MAPEADO DE CONTROLES GENERICOS PARA VIDEOJUEGOS:
207
www.3deobox.com
Lo que haremos es cambiar los controles de Disparar, Saltar, Mover y rotar cámara directamente con el Game Controller.
AI_Rocket_Launcher
if (Input.GetKeyDown (KeyCode.Mouse0) || Input.GetKeyDown (KeyCode.Joystick1Button7)) {}
Nota: Los inputs los estoy haciendo con base a mi Game Controller Generico.
AI_Pause
if (Input.GetKeyDown (KeyCode.Escape) || Input.GetKeyDown (KeyCode.JoystickButton9) ) {}
AI_JoystickRotate
function Update ()
{
//JOYSTICK SIDES – CONTINUO (Rotate).
if (Input.GetAxis ("X_JoyStick") >= 0.1 || Input.GetAxis ("X_JoyStick") <= -0.1) {
transform.Rotate (Vector3.up * Input.GetAxis ("X_JoyStick") * SpeedJoystick * Time.deltaTime);
}
//JOYSTICK UPDOWN - NO CONTINUO (localEulerAngles).
if (Input.GetAxis ("Y_Joystick") >= 0.1 || Input.GetAxis ("Y_Joystick") <= -0.1) {
RotationY += Input.GetAxis ("Y_Joystick") * SpeedJoystick * Time.deltaTime;
RotationY = Mathf.Clamp (RotationY, MinY, MaxY);
vCamera.transform.localEulerAngles = Vector3.right * RotationY;
}
}
208
www.3deobox.com
Para poder crear la opción de guardar una escena de un juego sobre la partida en la que estamos jugando, necesitamos usar una función
llamada PlayerPrefs, la cual nos permite guardar solamente variables del juego, en donde estas serán variables con información
de lo que queremos guardar como: posición del personaje, vida, sangre, ítems, checkpoint u opciones activadas del juego.
1. General: Se quiere que el personaje cuando pase por el ultimo Checkpoint activado y se use la opción de Salvar escena, este lo
haga a partir del último Checkpoint activado, así al reiniciar el juego el personaje inicie en la posición del Checkpoint Salvado.
2. Cargamos el paquete “Save_Scene_Start”, en data en Prefabs esta “Character_Prefab”, este lo insertamos en la escena.
3. En Data>Checkpoint_Prefab crearemos y asignaremos un script llamado “AI_CheckPoint”, así todos los prefab de este
tendrán el script dentro de la escena y no se tendrá que asignar de uno por uno el Script.
AI_CheckPoint
void OnTriggerEnter () {
print ("Checkpoint >"+vCheckPoint+"< Activado");
// Mandar al gameObject Esfera el CP activado a su variable para guardar
AI_Save_Load
void Update () {
//SAVE - Click Izquierdo, creamos Info para ahí almacenar la info
if (Input.GetKeyDown (KeyCode.Mouse0) ) {
PlayerPrefs.SetString("info", Salvar_CP);
print ("CheckPoint: "+Salvar_CP+" Salvado");
}
10. Ahora que esta creado el Script “AI_Save_Load”, haremos que cada
CheckPoint (A, B, C, D) en su variable de “Script_Salvar” carguen al script
de la Esfera: “AI_Save_Load”.
211
www.3deobox.com
void CharacterMove () {
//Obtener el valor desde el registro de windows
string Save_Load = PlayerPrefs.GetString("info");
if (Save_Load == "A"){
Character.transform.position = new Vector3 (0, 0, 45);
}else if (Save_Load == "B"){
Character.transform.position = new Vector3 (0, 0, 30);
}else if (Save_Load == "C"){
Character.transform.position = new Vector3 (0, 0, 17);
}else if (Save_Load == "D"){
Character.transform.position = new Vector3 (0, 0, 7);
}
}
void CharacterInstance () {
//Obtener el valor desde el registro de windows
string Save_Load = PlayerPrefs.GetString("info");
if (Save_Load == "A"){
Instantiate (Character, new Vector3 (0, 0, 45), transform.rotation);
}else if (Save_Load == "B"){
Instantiate (Character, new Vector3 (0, 0, 30), transform.rotation);
}else if (Save_Load == "C"){
Instantiate (Character, new Vector3 (0, 0, 17), transform.rotation);
}else if (Save_Load == "D"){
Instantiate (Character, new Vector3 (0, 0, 7), transform.rotation);
}
}
Nota: Permite NO destruir el objeto al iniciar (función de "Awake"), esto permite cargar
otra escena sin que se pierdan los valores del CP.
DontDestroyOnLoad (); | DontDestroyOnLoad (transform.gameObject);
212
www.3deobox.com
1. Creamos una Escena nueva junto con un Empty Group y asignamos “AI_Save_Load_File” :
AI_Save_Load_File
void Update ()
{
if (Input.GetKeyDown (KeyCode.Mouse0)) {
Save ();
}
if (Input.GetKeyDown (KeyCode.Mouse1)) {
Load ();
}
}
void Save ()
{
//Crear Carpeta si ya esta ignorarlo
if (!Directory.Exists (Application.dataPath + "/SaveLoad/Save/")) {
Directory.CreateDirectory (Application.dataPath + "/SaveLoad/Save/");
}
//Crear archivo txt con el valore de la variable
File.WriteAllText (Application.dataPath + "/SaveLoad/Save/Save.txt", vName +"\n"+ vPoitions +"\n"+ vEnergy +"\n" + vShell);
void Load ()
{
//Cargar el archivo que contiene multi lineas con valores en tipo string a convertir.
string[] FileTxt = File.ReadAllLines (Application.dataPath + "/SaveLoad/Save/Save.txt");
vPoitions = int.Parse (FileTxt [1]);
vEnergy = float.Parse (FileTxt [2]);
vShell = bool.Parse (FileTxt [3]);
print ("Nombre: " + (vName+" Deo") + ", Pociones: " + (vPoitions+1) + ", Energia: " + (vEnergy+0.1f) + ", Escudo: " + (!vShell));
}
213
www.3deobox.com
Para poder crear la opción de guardar una escena de un juego sobre la partida en la que estamos jugando, necesitamos usar una función
llamada PlayerPrefs, la cual nos permite guardar solamente variables del juego, en donde estas serán variables con información
de lo que queremos guardar como: posición del personaje, vida, sangre, ítems, checkpoint u opciones activadas del juego.
1. General: Se quiere que el personaje cuando pase por el ultimo Checkpoint activado y se use la opción de Salvar escena, este lo
haga a partir del último Checkpoint activado, así al reiniciar el juego el personaje inicie en la posición del Checkpoint Salvado.
2. Cargamos el paquete “Save_Scene_Start”, en data en Prefabs esta “Character_Prefab”, este lo insertamos en la escena.
3. En Data>Checkpoint_Prefab crearemos y asignaremos un script llamado “AI_CheckPoint”, así todos los prefab de este
tendrán el script dentro de la escena y no se tendrá que asignar de uno por uno el Script.
AI_CheckPoint
function OnTriggerEnter () {
print ("Checkpoint >"+vCheckPoint+"< Activado");
// Mandar al gameObject Esfera el CP activado a su variable para guardar
AI_Save_Load
function Update () {
//SAVE - Click Izquierdo, creamos Info para ahí almacenar la info
if (Input.GetKeyDown (KeyCode.Mouse0) ) {
PlayerPrefs.SetString("info", Salvar_CP);
print ("CheckPoint: "+Salvar_CP+" Salvado");
}
10. Ahora que esta creado el Script “AI_Save_Load”, haremos que cada
CheckPoint (A, B, C, D) en su variable de “Script_Salvar” carguen al script
de la Esfera: “AI_Save_Load”.
215
www.3deobox.com
function CharacterMove () {
//Obtener el valor desde el registro de windows
string Save_Load = PlayerPrefs.GetString("info");
if (Save_Load == "A"){
Character.transform.position = new Vector3 (0, 0, 45);
}else if (Save_Load == "B"){
Character.transform.position = new Vector3 (0, 0, 30);
}else if (Save_Load == "C"){
Character.transform.position = new Vector3 (0, 0, 17);
}else if (Save_Load == "D"){
Character.transform.position = new Vector3 (0, 0, 7);
}
}
function CharacterInstance () {
//Obtener el valor desde el registro de windows
string Save_Load = PlayerPrefs.GetString("info");
if (Save_Load == "A"){
Instantiate (Character, new Vector3 (0, 0, 45), transform.rotation);
}else if (Save_Load == "B"){
Instantiate (Character, new Vector3 (0, 0, 30), transform.rotation);
}else if (Save_Load == "C"){
Instantiate (Character, new Vector3 (0, 0, 17), transform.rotation);
}else if (Save_Load == "D"){
Instantiate (Character, new Vector3 (0, 0, 7), transform.rotation);
}
}
Nota: Permite NO destruir el objeto al iniciar (función de "Awake"), esto permite cargar
otra escena sin que se pierdan los valores del CP.
2. Creamos una Escena nueva junto con un Empty Group y asignamos “AI_Save_Load_File” :
AI_Save_Load_File
//Permite usar librerias del sistema (File).
import System.IO;
function Update () {
if (Input.GetKeyDown (KeyCode.Mouse0)) {
Save ();
}
if (Input.GetKeyDown (KeyCode.Mouse1)) {
Load ();
}
}
function Save () {
//Crear Carpeta si ya esta ignorarlo
if (!Directory.Exists (Application.dataPath + "/SaveLoad/Save/")) {
Directory.CreateDirectory (Application.dataPath + "/SaveLoad/Save/");
}
//Crear archivo txt con el valore de la variable
File.WriteAllText (Application.dataPath + "/SaveLoad/Save/Save.txt", vName +"\n"+ vPoitions +"\n"+ vEnergy +"\n" + vShell);
function Load () {
//Cargar el archivo que contiene multi lineas con valores en tipo string a convertir.
var FileTxt : String[] = File.ReadAllLines (Application.dataPath + "/SaveLoad/Save/Save.txt");
vPoitions = int.Parse (FileTxt [1]);
vEnergy = float.Parse (FileTxt [2]);
vShell = boolean.Parse (FileTxt [3]);
print ("Nombre: " + (vName + " Deo") + ", Pociones: " + (vPoitions + 1) + ", Energia: " + (vEnergy + 0.1f) + ", Escudo: " + (!vShell));
}
217
www.3deobox.com
Building Settings: