TÁ LÁ UM CORPO ESTENDIDO NO CHÃO

Espere descarregar essa demo e coloque o cursor dentro dela, centralizando a mira com o centro do plano (encontro dos riscos azul e vermelho). Ande com o FPC como visto nas aulas anteriores (WSAD). Repare que o robot se dirige sempre para o FPC. Quando chega a uma certa distância, pára e começa a animação de "shoot". Se você se afastar, ele volta a andar atrás. Na demo o Robot não atira. Se você atirar, o Robot levanta vôo. Isso e só um ´"teste de conceito" do qual vamos falar adiante.

Nessa aula você pode fazer o download de um novo pacote:

RIGHTCLICANDO AQUI

Nele você vai encontrar dois presentes:

Importe esse pacote para seu projeto.

O "Robot" tem 4 animações: "idle", "walk","run" e "shoot". O "Robot-Ragdoll" vai ser usado como uma versão do Robot, quando morto.

O robot que é defensor da Base e vai tentar matar nosso herói.

O "comportamento" dele é o seguinte: quando o herói se aproxima de uma certa distância ele vai andando na direção dele. E, chegando mais perto, atira.

No nosso Curso Básico, já aprendemos uma coisa semelhante nessa lição.

O que temos de novidade maior aqui é que agora o "inimigo" tem várias animações. Donde você deve dar uma olhada no Refence da Classe Animation nessa lição.

Uma coisa que também apredemos no Curso Básico foi criarmos uma "prova de conceito", que é um teste simplificado do que pretendemos usar no game. É o que vimos aí acima.

No teste , o script acoplado ao Robot é bem semelhante ao daquelas lições do "zumbi" e da bazuca, misturado com coisa básicas vistas sobre a Classe Animation. Vamos sobrepondo animações usando "layers" mais altos.:

var damp = 2;
var velocidadePerseguidor = 2;

function Start(){
 //É usual se colocar todas as animações do gameobject em loop
 animation.wrapMode = WrapMode.Loop;
 //e tirar de loop só aquelas exceções
 animation["shoot"].wrapMode = WrapMode.Once;
 //Inicializar todas as animações com:   
 animation.Stop();
}

function Update(){
 animation.CrossFade("idle"); //layer não especificado é = 0.

 if(Vector3.Distance(GameObject.Find("First Person Controller").transform.position,transform.position) < 30 && Vector3.Distance(GameObject.Find("First Person Controller").transform.position,transform.position) > 5){
   //muda animação  
   animation["walk"].layer = 10;
   animation.CrossFade("walk");
   animation.wrapMode = WrapMode.Loop;
   
   var rotate = Quaternion.LookRotation(GameObject.Find("First Person Controller").transform.position - transform.position);
   transform.rotation = Quaternion.Slerp(transform.rotation, rotate,damp * Time.deltaTime);
   transform.Translate(0,0, velocidadePerseguidor * Time.deltaTime);
  }

   
  if(Vector3.Distance(GameObject.Find("First Person Controller").transform.position,transform.position) <5){
   //muda animação 
   animation["walk"].layer = 5;
   animation["shoot"].layer = 20;
   animation.CrossFade("shoot");
   
   var rotateP = Quaternion.LookRotation(GameObject.Find("First Person Controller").transform.position - transform.position);
   transform.rotation = Quaternion.Slerp(transform.rotation, rotateP,damp * Time.deltaTime);
 }
}

No nosso exercício final, consideramos que se o Robot conseguir apontar para o herói , esse está "morto" ! Na realidade não tem tiro "fisico", nem gameobject como o míssil, nem "ray". Apenas o som. Colocando esse som de tiros (o Robot tem que estar próximo menos de 4 unidades) e fazendo o Robot retornar a sua posição inicial depois dessa morte, temos novas linhas de código (em azul):

var damp = 2;
var velocidadePerseguidor = 2;
var somClip: AudioClip;
var posInit:Vector3;
public var sa:saude;
var UmaVez=0;

function Start(){
 animation.wrapMode = WrapMode.Loop;
 animation["shoot"].wrapMode = WrapMode.Once;
 animation.Stop();
 posInit = transform.position;
}

function Update(){
 animation.CrossFade("idle");
  var rotateP = Quaternion.LookRotation(GameObject.Find("First Person Controller").transform.position - transform.position);
  transform.rotation = Quaternion.Slerp(transform.rotation, rotateP,damp * Time.deltaTime);
 if(Vector3.Distance(GameObject.Find("First Person Controller").transform.position,transform.position) < 7 && Vector3.Distance(GameObject.Find("First Person Controller").transform.position,transform.position) > 4){
   animation["walk"].layer = 10;
   animation.CrossFade("walk");
   animation.wrapMode = WrapMode.Loop;
   
   transform.Translate(0,0, velocidadePerseguidor * Time.deltaTime);
   audio.Pause();
	 
 }
 if(Vector3.Distance(GameObject.Find("First Person Controller").transform.position,transform.position) <4){
   animation["idle"].layer = 0;
   animation["walk"].layer = 5;
   animation["shoot"].layer = 10;
   animation.CrossFade("shoot");
   if(UmaVez==0){
    Mata();
    UmaVez=1;
   } 
  }
}
  
function Mata(){
 //som dos tiros
 audio.Play(); 
 audio.loop=true;
 yield WaitForSeconds(1.0); 
 //Heroi morre - volta ao inicio
 GameObject.Find("First Person Controller").transform.position = GameObject.Find("PontoInicial").transform.position ;
 //Robot volta ao início
 transform.position = posInit;
 audio.Pause(); 
 animation["idle"].layer = 15;
 animation.CrossFade("idle");
 sa.saude = 100;
 UmaVez=0;
}

Claro que temos que dar a oportunidade do nosso herói matar o Robot. Como fizemos nessa lição do Curso Básico, vamos substituir o Robot por sua versão "morta".

Vejamos então como ficou o script colocado na bala (o míssil) disparada pelo nosso herói:

var explosao : Transform;  
public var radius  = 0.1;
public var  power  = 1;
var UmaVez=0;
var roboMorto : Transform;// Arrastar o Robot-Ragdoll 

function OnCollisionEnter( colisao : Collision ){
 var contact : ContactPoint = colisao.contacts[0];
 var rotation = Quaternion.FromToRotation( Vector3.up, contact.normal );
 Instantiate(explosao, contact.point, rotation );
 var colliders: Collider[] = Physics.OverlapSphere (gameObject.transform.position, radius );
  for (var hitx: Collider in colliders) {
      if(hitx.rigidbody) hitx.rigidbody.AddExplosionForce(power, gameObject.transform.position, radius, 3.0);
      //Se atingido for o Robot 
       if(hitx.gameObject.name == "Robot") {
       //esperar diminuir fumaça
      yield WaitForSeconds(1.0); 
        if(UmaVez==0){
         Instantiate(roboMorto, GameObject.Find("Robot").transform.position,GameObject.Find("Robot").transform.rotation); 
          Destroy(GameObject.Find("Robot"));
         UmaVez=1;
        }
      }
   }
 //Destruir o missil
 Destroy( gameObject );
}

Você pode brincar com nossa demo, matando ou deixando-se matar (pelo menos a primeira vez):

PARA DEMO:CLIQUE AQUI!


CONCLUSÃO

Assim termina nosso pequeno curso. É possível que você descubra alguns "bugs" na nossa demo. É que ela não é um jogo pronto. Nossa intenção foi apenas mostrar conceitos básicos de programação - ampliando o que foi ensinado em nosso Curso Básico com a ajuda das idéias, modelos e animações de um dos tutoriais oficiais da Unity Tec.

Espero que lhe tenha sido útil.

Américo Damasceno Jr. - maio 2011


LIÇÃO ANTERIOR
ÍNDICE HOME PAGE