Unity Artificial Intelligence

19
By: Deodato Pechir. UNITY 3D REFERENCE SCRIPTING

Transcript of Unity Artificial Intelligence

Page 1: Unity Artificial Intelligence

By: Deodato Pechir.

UNITY 3D REFERENCE SCRIPTING

Page 2: Unity Artificial Intelligence

INDICE DINAMICO – REFERENCIA DE SCRIPTING

MENU:

1. AI. BASIC PATROL.

2. AI. VISIBLE RANGE & FOLLOW.

3. AI. OUT OF RANGE & HIDE.

4. AI. ENEMY ATTACK.

5. WAYPOINT & PATHFINDIGS.

6. MULTI WAYPOINTS & PATHFINDNGS.

Nota: Si quieres regresar al Índice haz click sobre el Cubo en la parte superior derecha de cada página

Page 3: Unity Artificial Intelligence

3

www.3dboxweb.com

1. ARTIFICIAL INTELLIGENCE BASIC PATROL

Page 4: Unity Artificial Intelligence

4

www.3dboxweb.com

ARTIFICIAL INTELLIGENCE – BASIC PATROL:

1. Cargamos el paquete Basic_AI, y haremos que el personaje camine por sí solo, y detecte que cuando se acerque a un muro este

gire a la derecha.

//Variables para controlar AI

var GirarVelocidad : float = 2;

var VelocidadCaminar : float = 5;

var Distancia : float = 3;

function Update () {

// Dibujar una línea que sea como el Raycast para saber con que colisiona

Debug.DrawRay (transform.position, transform.forward*Distancia, Color.white);

// Uso del Raycast para lanzar un rayo hacia enfrente y detecte cuando colisione.

if (Physics.Raycast (transform.position, transform.forward, Distancia)){

//ROTAR

//Si "RotarDerecha=true" hacer que gire continuamente a la derecha.

transform.Rotate (Vector3.up, 90 * GirarVelocidad * Time.deltaTime);

}else{

//MOVER

transform.Translate (Vector3.forward * VelocidadCaminar * Time.deltaTime);

}

}

Page 5: Unity Artificial Intelligence

5

www.3dboxweb.com

2. Ahora haremos que el personaje gire hacia la izquierda/Derecha a determinado tiempo, para darle variedad:

//Variables para controlar AI

var Distancia : float = 3;

var GirarVelocidad : float = 2;

var VelocidadCaminar : float = 5;

var RotarDerecha: boolean = true;

var Segundos : float = 10;

function Update () {

// Dibujar una línea que sea como el Raycast para saber con que colisiona

Debug.DrawRay (transform.position, transform.forward*Distancia, Color.white);

// Uso del Raycast para lanzar un rayo hacia enfrente y detecte cuando colisione.

if (Physics.Raycast (transform.position, transform.forward, Distancia)){

//ROTACION

if(RotarDerecha){

//Si "RotarDerecha=true" hacer que gire continuamente a la derecha.

transform.Rotate (Vector3.up, 90 * GirarVelocidad * Time.deltaTime);

}else{

//Si "RotarDerecha=false" hacer que gire continuamente a la Izquierda.

transform.Rotate (Vector3.up, -90 * GirarVelocidad * Time.deltaTime);

}

}else{

//CAMINAR

transform.Translate (Vector3.forward * VelocidadCaminar * Time.deltaTime);

}

}

Page 6: Unity Artificial Intelligence

6

www.3dboxweb.com

Opción 1: Cambiar la rotación Izquierda a Derecha en base a tiempo.

function CambiarGiro(){

// Cambiar la variable de boleano true/false.

RotarDerecha = !RotarDerecha;

}

//Activar la corrutina que hace que cambie de giro el player cada cantidad de segundos.

InvokeRepeating ("CambiarGiro", 0, Segundos);

Opción 2: Cambiar la rotación Izquierda a Derecha en base a funciones del teclado.

function Update () {

if (Input.GetKeyDown (KeyCode.Z)){

Desactivar();

}else if (Input.GetKeyDown (KeyCode.X)){

Activar();

}

}

//-------------------------------------------------------------------------

function Desactivar (){

//Cancelar corrutina de Cambio de Giro

CancelInvoke("CambiarGiro");

// Desativar la velocidad

VelocidadCaminar = 0;

//Imprimir AI

Debug.Log ("Desactivar AI");

}

function Activar (){

//Activar de nuevo el caminar

VelocidadCaminar = 5;

//Activar corrutina de Cambio de Giro

InvokeRepeating ("CambiarGiro", 0, Segundos);

//Imprimir AI

Debug.Log ("Activar AI");

}

Page 7: Unity Artificial Intelligence

7

www.3dboxweb.com

2. A.I. VISIBLE RANGE & FOLLOW

Page 8: Unity Artificial Intelligence

8

www.3dboxweb.com

ARTIFICIAL INTELLIGENCE –VISIBLE RANGE & FOLLOW:

1. Cargamos el paquete “AI_SceneFollow” y en la carpeta de Prefab, agregamos Enemigo y Jugador (Rigidbody y Collider).

2. Script “AI_RangeVisibleFollow” y lo asignamos al “Prefab_Enemigo” para que quede asignado a cada enemigo de la escena.

3. El “Jugador” ya tiene asignado los controles básicos de “1ra Persona” (Character Controller, Motor y FPSInput Controller).

Haremos que cuando el personaje se acerque al enemigo de acuerdo a una cierta distancia cuando lo visualiza, el enemigo gire

suavemente hacia el jugador y comience a seguirlo hasta, pero manteniendo una distancia cuando este totalmente cerda del jugador,

y el jugador hasta que salga de su rango de visión dejara de seguirlo.

[Los colores son en base a los pasos de scripting]

var Jugador : Transform;

var LineaBusqueda : int = 7;

var LineaAtaque : int = 2;

var GirarEnemigo : int = 6;

var CaminarEnemigo : int = 5;

function Update(){

// Línea de ataque del "Enemigo" seguir/atacar | La distancia del Enemigo y Jugador.

Debug.DrawRay (transform.position, transform.forward * LineaBusqueda, Color.white);

var DistanciaJugador= Vector3.Distance (transform.position, Jugador.position);

// Si entra en la "Linea Ataque" pero no pasa la "DistanciaAtaque" (cuan cerca jugador-enemigo).

if (DistanciaJugador <= LineaBusqueda && DistanciaJugador >= LineaAtaque){

//ROTAR

// Obtener "Angulo" donde esta el personaje para que Gire. | Suavisar al "Angulo" de rotacion con Lerp.

var Angulo = Quaternion.LookRotation(Jugador.position - transform.position);

transform.rotation = Quaternion.Slerp(transform.rotation, Angulo, Time.deltaTime * GirarEnemigo);

//MOVER

transform.Translate(Vector3.forward*CaminarEnemigo*Time.deltaTime);

}

}

Page 9: Unity Artificial Intelligence

9

www.3dboxweb.com

3. AI. OUT OF RANGE & HIDE

Page 10: Unity Artificial Intelligence

10

www.3dboxweb.com

ARTIFICIAL INTELLIGENCE –OUT OF RANGE & HIDE:

1. Cargamos el paquete “AI_SceneHide” y en la carpeta de Prefab, agregamos Enemigo y Jugador (Rigidbody y Collider).

2. Script “AI_RangeHide” y lo asignamos al “Prefab_Enemigo” para que quede asignado a cada enemigo de la escena.

3. El “Jugador” ya tiene asignado los controles básicos de “1ra Persona” (Character Controller, Motor y FPSInput Controller).

Haremos que cuando el personaje se esconda detrás de un muro o un objeto que no permita ver al enemigo al Jugador este

simplemente no esté en su rango de ataque.

[Los colores son en base a los pasos de scripting]

//Variable para cargar al Jugador

var Jugador : Transform;

function Update(){

//Variable para obtener info de las colisiones

var HitRay : RaycastHit;

// Saber si esta colisionando con Jugador o se cruza algo mas entre ellos y dejarlo en el HitRay.

if (Physics.Linecast (transform.position, Jugador.position, HitRay)){

//Saber que objeto de interpone o cruza entre Enemigo-Jugador

if (HitRay.collider.gameObject.name == "Prefab_Jugador"){

// Línea de Búsqueda -> "Personaje" Visible

Debug.DrawLine (transform.position, Jugador.position, Color.green);

}else{

// Linea de Busqueda -> "Personaje" NO Visible

Debug.DrawLine (transform.position, Jugador.position, Color.red);

}

}

}

Page 11: Unity Artificial Intelligence

11

www.3dboxweb.com

4. A.I. ENEMY ATTACK

Page 12: Unity Artificial Intelligence

12

www.3dboxweb.com

ARTIFICIAL INTELLIGENCE – ENEMY ATTACK (RANGE VISIBLE & ATTACK):

1. Cargamos “AI_Scene EnemyAttack” y en la carpeta de Prefab, agregamos Enemigo y Jugador (Rigidbody y Collider).

2. Script “AI_ EnemyAttack” y lo asignamos al “Prefab_Enemigo” para que quede asignado a cada enemigo de la escena.

3. El “Jugador” ya tiene asignado los controles básicos de “1ra Persona” (Character Controller, Motor y FPSInput Controller).

Nota: Ahora combinaremos las técnicas de: “Visible Range & Follow” y “Out of Range & Hide”, para hacer que el “enemigo” nos

ataque cuando estemos dentro de su área visible, este gire hacia nosotros y nos siga, pero cuando estemos detrás de un muro ya no

podrá vernos.

var LineaBusqueda : int = 7; var LineaAtaque : int = 2; var GirarEnemigo : int = 6; var CaminarEnemigo : int = 5; PASO 1: JUNTAR VARIABLES

//SCRIPT: RANGE TO FOLLOW function Update(){ // Linea de Busqueda del "Personaje", hacia donde se encuentra. Debug.DrawLine (transform.position, Jugador.position, Color.green); // Linea de ataque del "Enemigo" siguir/atacar. Debug.DrawRay (transform.position, transform.forward * LineaBusqueda, Color.white); var DistanciaJugador= Vector3.Distance (transform.position, Jugador.position); // Si entra en la "Linea Ataque" pero no pasa la "DistanciaAtaque" if (DistanciaJugador <= LineaBusqueda && DistanciaJugador >= LineaAtaque){ //ROTAR // Obtener "Angulo" donde esta el personaje para que Gire. | Suavisar al "Angulo" de rotacion con Lerp. var Angulo = Quaternion.LookRotation(Jugador.position - transform.position, Vector3.up); transform.rotation = Quaternion.Slerp(transform.rotation, Angulo, Time.deltaTime * GirarEnemigo); //MOVER transform.Translate(Vector3.forward*CaminarEnemigo*Time.deltaTime); } } //-------------------------------------------------------------------------------------------------------------- //SCIPT: RANGE VISIBLE ACTION var Jugador : Transform; var HitRay : RaycastHit; // Saber que cruz o colisiona entre el enemigo y el personaje. if (Physics.Linecast (transform.position, Jugador.position, HitRay)){

if (HitRay.collider.gameObject.name == "Prefab_Jugador"){ // Linea de Busqueda -> "Personaje" Visible Debug.DrawLine (transform.position, Jugador.position, Color.green); PASO 2: PASAR ROTAR/MOVER SI ESTA EN EL RANGO DE BUSQUEDA Y NO ESTA ESCONDIDO. }else{ // Linea de Busqueda -> "Personaje" NO Visible Debug.DrawLine (transform.position, Jugador.position, Color.red); } } PASO 3: PASAR LOS CORCHETES ABAJO

Page 13: Unity Artificial Intelligence

13

www.3dboxweb.com

var Jugador : Transform;

var LineaBusqueda : int = 7;

var LineaAtaque : int = 2;

var GirarEnemigo : int = 6;

var CaminarEnemigo : int = 5;

function Update(){

// Linea de Busqueda del "Personaje", hacia donde se encuentra.

Debug.DrawLine (transform.position, Jugador.position, Color.green);

// Línea de ataque del "Enemigo" seguir/atacar.

Debug.DrawRay (transform.position, transform.forward * LineaBusqueda, Color.white);

var DistanciaJugador= Vector3.Distance (transform.position, Jugador.position);

var HitRay : RaycastHit;

// Saber qué cruz o colisiona entre el enemigo y el personaje.

if (Physics.Linecast (transform.position, Jugador.position, HitRay)){

if (HitRay.collider.gameObject.name == "Prefab_Jugador"){

// Linea de Busqueda -> "Personaje" Visible

Debug.DrawLine (transform.position, Jugador.position, Color.green);

//------------------------------------------------------------------------------------------------------------------------

// Si entra en la "Linea Ataque" pero no pasa la "DistanciaAtaque"

if (DistanciaJugador <= LineaBusqueda && DistanciaJugador >= LineaAtaque){

//ROTAR

// Obtener "Angulo" donde esta el personaje para que Gire. | Suavisar al "Angulo" de rotacion con Lerp.

var Angulo = Quaternion.LookRotation(Jugador.position - transform.position, Vector3.up);

transform.rotation = Quaternion.Slerp(transform.rotation, Angulo, Time.deltaTime * GirarEnemigo);

//MOVER

transform.Translate(Vector3.forward*CaminarEnemigo*Time.deltaTime);

}

//------------------------------------------------------------------------------------------------------------------------

}else{

// Linea de Busqueda -> "Personaje" NO Visible

Debug.DrawLine (transform.position, Jugador.position, Color.red);

}

}

Page 14: Unity Artificial Intelligence

14

www.3dboxweb.com

5. WAYPOINTS & PATHFINDING

Page 15: Unity Artificial Intelligence

15

www.3dboxweb.com

ARTIFICIAL INTELLIGENCE – CREATE WAYPOINTS:

1. Importamos Waypoints.psd, creamos una carpeta con el nombre de “Gizmos” y aquí dentro pondremos el psd.

2. Creamos un Empty Object y lo metemos en un Prefab le asignamos un nuevo script: “AI_Gizmo”.

GIZMO BASICOS:

// Mandar llamar la textura para el Waypoint(debe de estar en Carpeta Gizmos)..

function OnDrawGizmos (){

Gizmos.DrawIcon (transform.position, "NombreImagen.psd");

}

GIZMO ESTILO DEO:

// Extensiones a leer.

enum Extenciones {psd, png, jpg, tga}

//Variables Formato y Extension

var Formatos : Extenciones;

var Textura : Texture;

// Mandar llamar la textura para el Waypoint(debe de estar en Carpeta Gizmos).

function OnDrawGizmos (){

Gizmos.DrawIcon (transform.position, Textura.name + "." + Formatos);

}

Page 16: Unity Artificial Intelligence

16

www.3dboxweb.com

ARTIFICIAL INTELLIGENCE – PATHFINDING:

//VARIABLES

var Waypoint : Transform;

var Speed : float = 5;

var DistanceToWP : float = 1;

//SI NO HAY WAYPOINT SE DESACTIVA EL SCRIPT

function Awake(){

if(Waypoint == null) {

enabled = false;

Debug.LogWarning("No hay WayPoint cargados en: "+name);

}

}

//CONECCION AL WAYPOINT

function OnDrawGizmos(){

if( Waypoint != null) {

Gizmos.color = Color (.6, .6, 1, .7);

Gizmos.DrawLine(transform.position, Waypoint.position);

}

}

//CAMINAR HACIA EL WAYPOINT

function FixedUpdate (){ // Waypoint – Position del persoaje

var vChaToWp = Vector3.Distance(Waypoint.position, transform.position);

if (vChaToWp >= DistanceToWP){

transform.LookAt ( Vector3 (Waypoint.position.x, transform.position.y, Waypoint.position.z) );

transform.position += transform.forward * Time.deltaTime * Speed;

}

}

Page 17: Unity Artificial Intelligence

17

www.3dboxweb.com

6. MULTI WAYPOINTS

Page 18: Unity Artificial Intelligence

18

www.3dboxweb.com

ARTIFICIAL INTLIGENCE - MULTI WAYPOINTS:

//VARIABLES

var Waypoint : Transform[];

var DistanceToWP : float = 1;

var Speed : float = 5;

//SI NO HAY WP DESACTIVAR EL SCRIPT.

function Awake(){

if( Waypoint.length <= 0 ) {

enabled = false;

Debug.LogWarning("No WayPoint Loaded in: "+name);

}

}

//CONECCION A LOS WAYPOINTS

function OnDrawGizmos(){

if( Waypoint.Length > 0 ) {

for(var i : int = 0; i < Waypoint.length; i++) { //Si hay mas de 1 WP se inician las conexiones.

if (i>0){ //inicia del ultimo WP hacia atras, para que no sobre ningun WP (resta).

Gizmos.color = Color (.6, .6, 1, .7);

Gizmos.DrawLine(Waypoint[i].position, Waypoint[i-1].position);

}

}

}

}

Page 19: Unity Artificial Intelligence

19

www.3dboxweb.com

//Variable no publica para iniciar indicar a que Waypoint caminara al llegar a un WP.

private var NextWP : int = 0;

//CAMINAR HACIA LOSWAYPOINTS

function FixedUpdate (){

// Waypoint - Posicion del personaje.

var vChaToWp= Vector3.Distance(Waypoint[NextWP].position, transform.position);

//Caminar hacia el WP en referencia de la distancia

if (vChaToWp >= DistanceToWP){

transform.LookAt ( Vector3 (Waypoint[NextWP].position.x, transform.position.y, Waypoint[NextWP].position.z) );

transform.position += transform.forward * Time.deltaTime * Speed;

}else{ // Obtenemos el total de WP y le restamos 1, para que no llegue al final y trate de ir a otro.

if (NextWP < Waypoint.length -1){ //Hacer que se pase al siguiente WP a caminar, sumando 1 al actual.

NextWP++;

}

}

}

SI SE QUIERE CREAR LOOP AL LLEGAR AL FINAL DEL WP:

var Loop : boolean = true;

//SCRIPT RECORTADO

if (NextWP < Waypoint.length -1){

NextWP++;

} else {

if (Loop){ // Si se llega al ultimo WP, hacemos que se repita

NextWP = 0;

}else{ //Si no hay Loop activado desactivar Script (rendimiento).

enabled =false;

}

}

} }