80257280 unity artificial intelligence

Upload: giltikdemetrio

Post on 08-Oct-2015

41 views

Category:

Documents


0 download

DESCRIPTION

INTELIGENCIA ARTIFICAIAL CON UNITY

TRANSCRIPT

  • By: Deodato Pechir.

    UNITY 3D REFERENCE SCRIPTING

  • 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 pgina

  • 3

    www.3dboxweb.com

    1. ARTIFICIAL INTELLIGENCE BASIC PATROL

  • 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 lnea 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);

    }

    }

  • 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 lnea 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);

    }

    }

  • 6

    www.3dboxweb.com

    Opcin 1: Cambiar la rotacin 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);

    Opcin 2: Cambiar la rotacin 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");

    }

  • 7

    www.3dboxweb.com

    2. A.I. VISIBLE RANGE & FOLLOW

  • 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 bsicos 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 visin 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(){

    // Lnea 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 = 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);

    }

    }

  • 9

    www.3dboxweb.com

    3. AI. OUT OF RANGE & HIDE

  • 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 bsicos de 1ra Persona (Character Controller, Motor y FPSInput Controller).

    Haremos que cuando el personaje se esconda detrs 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"){

    // Lnea de Bsqueda -> "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);

    }

    }

    }

  • 11

    www.3dboxweb.com

    4. A.I. ENEMY ATTACK

  • 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 bsicos de 1ra Persona (Character Controller, Motor y FPSInput Controller).

    Nota: Ahora combinaremos las tcnicas 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 detrs 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 = 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

  • 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);

    // Lnea 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 = 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);

    }

    }

  • 14

    www.3dboxweb.com

    5. WAYPOINTS & PATHFINDING

  • 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);

    }

  • 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;

    }

    }

  • 17

    www.3dboxweb.com

    6. MULTI WAYPOINTS

  • 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 ) {

    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);

    }

    }

    }

    }

  • 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;

    }

    }

    } }