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