Já vimos numa lição anterior como fazer o avatar "pegar" um revólver. Usamos a técnica do "invisível-aparece".
Nessa lição, vamos fazer o avatar pegar uma bazuca usando uma técnica mais sofisticada(?) em que usamos instancialização.
Como você pode ver na figura, para segurar a bazuca, o avatar precisa modificar a posição dos braços. Então, teremos que substituir todo o submesh que chamamos de "arms".
Começamos criando, no Blender, o conjunto braços+arma. Esse conjunto vai ser convertido em um "prefab", junto com um script - como vamos ver mais para frente.
IMPORTANTE: A posição desse conjunto, no Blender, tem que ser equivalente a daquele que vai ser substituído.
Para você fazer o exercício dessa aula, disponibilizamos, tanto esse conjunto, quanto a bazuca que vai ser colocada no chão (rightclique).
Teremos um script acoplado à "bazuca-no-chão" que, quando clicada, vai ser destruída. Vamos setar, nessa hora, uma variável "pegou", que é de um outro script, que vai acoplado ao avatar (e que se chama bazucaInst). Veja o primeiro script:
var bI : bazucaInst;
function OnMouseDown() {
bI.pegou = 1;
Destroy(gameObject);
}
OBSERVAÇÂO: Lembre-se de "arrastar" graficamente, do Hierarchy, o nome do GameObject ("demiurgo"), que contém o script bazucaInst, sobre a variável, no Inspector.
O outro script é:
var bracoBazuca:GameObject;
var bracoDemiurgo:GameObject;
var umaVez = 0;
var pegou=0;
function Update(){
if(pegou==1 && umaVez==0){
Instantiate(bracoBazuca, transform.position, transform.rotation);
Destroy(bracoDemiurgo);
umaVez=1;
}
if(GameObject.Find("bracoBazuca(Clone)")!=null){
GameObject.Find("bracoBazuca(Clone)").transform.position=transform.position;
GameObject.Find("bracoBazuca(Clone)").transform.rotation=transform.rotation;
}
}
Repare que o prefab, quando instancializado, passa a ter o nome "bracoBazuca(Clone)", que usamos para fazer com que sua posição e rotação sejam sempre as mesmas do avatar.
Criamos, nesse script, duas variáveis que são do tipo GameObject e devemos "arrastar" graficamente os nomes dos GameObjects para cima delas. Devemos mudar o nome do submesh "arms" do "demiurgo" (pois existe outro igual no zumbi) e o "arrasto" deve ser feito a partir do Hierarchy. O prefab é arrastado do Project.:
Quando criamos o prefab de uma arma que vai ser instancializada (no caso, o conjunto "braço + bazuca"), devemos colocar nele os scripts que vão fazer a arma funcionar.
No nosso caso, a bazuca vai funcionar diferente do revólver, onde atirávamos uma bala apertando a tecla "t". Para a bazuca, vamos usar um "raio" que vai sair da câmera e ir até uma posição num objeto do espaço 3D (seja ele o chão ou não)
Já falamos sobre "rays" na aula anterior. Antes de ver o script que "administra" o tiro, brinque com nossa demo. Pegue a bazuca perto do poste. O ponteiro vai mudar para a imagem de um projétil (muito mal desenhado, sorry...). Para, atirar um projétil "rightclique" no alvo. Você vai ver que o avatar vira para aquele ponto e atira. Se o zumbi pega o avatar, ele morre, claro...Como estamos usando "rightclique", inibimos a possibilidade de abrir o menu para full-screen (veja o código dessa página para aprender a fazer isso). O som (criado pela Unity Tec) é posicional, fica mais forte perto do avatar e quase não é ouvido se a explosão é longe:
Agora veja o script:
public var cursor : Texture2D;
public var mira : Texture2D;
public var explosao : Transform;
function Update (){
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
var hit:RaycastHit;
if(Input.GetKeyDown("mouse 1")){
if(Physics.Raycast(ray,hit)){
var rot:Quaternion= Quaternion.FromToRotation(Vector3.up,hit.normal);
if(Vector3.Distance(GameObject.Find("demiurgo").transform.position,hit.point) > 4 ) {
GameObject.Find("demiurgo").transform.LookAt(Vector3(hit.point.x,GameObject.Find("demiurgo").transform.position.y,hit.point.z));
ViraEAtira( hit,rot);
}
}
}
}
function ViraEAtira(hit:RaycastHit, rot:Quaternion){
yield WaitForSeconds (0.4);
Instantiate(explosao,hit.point,rot);
if(hit.collider.gameObject.name == "demiurgo 1" || hit.collider.gameObject.name == "poste")
Destroy(hit.collider.gameObject);
}
//Para mudar cursor
function OnGUI () {
GUI.Label(Rect(Input.mousePosition.x-12, Screen.height - Input.mousePosition.y-10, 100, 100), cursor);
Screen.showCursor = false;
cursor = mira;
}
Vamos analisar esse script.
Definimos duas variáveis para mudar o ponteiro, coisa que já ensinamos em outra lição.
Para a variavel "explosão", você vai ter que "arrastar" um dos prefabs de explosão que compõem o "unitypackage" da Unity Tec que você deve baixar, descompactar e carregar no projeto:
O raio é disparado com um "rightclique", o que definimos com:
Input.GetKeyDown("mouse 1")
Basta dar a direção ("ray"), que capturamos o "hit" (do primeiro atingido).
Para fazer o avatar se virar para o ponto em que o raio atinge algo - mas não para baixo ou cima - usamos:
GameObject.Find("demiurgo").transform.LookAt(Vector3(hit.point.x,GameObject.Find("demiurgo").transform.position.y,hit.point.z));
Como essa virada leva um tempinho, vamos dar um "wait" para a explosão. Para esse "wait" usamos:
yield WaitForSeconds (0.4);
IMPORTANTE: Quando usamos um "wait", ele não pode ficar dentro do Update. Temos que criar uma nova função.
Na nova função, instancializamos a explosão e, se o raio colidir com um dos alvos especificados, eles são destruidos. Poderíamos criar modelos de "zumbi arrebentado" ou "coluna arrebentada" para usar (como já vimos em outra aula).
É com truques semelhantes ao visto nessa aula, de "destroy+instantiate", que podemos fazer trocas de armas ou voltar a situação "avatar desarmado". No caso do exercício, o avatar, coitado, tem que ficar com a bazuca...
IMPORTANTE: Também usando os conceitos aprendidos nessa aula, é possivel criar um sistema de troca de avatares ou acréscimo de objetos ao avatar. Por exemplo: criar um chapéu que pode ser acrescentado ao avatar. Ou escolher entre um avatar homem e outro que seja uma mulher. É só pensar um pouco...
ANTERIOR PRÓXIMA ÍNDICE HOME PAGE