INDIVIDUALIZAÇÃO DE AVATARES

Vamos repetir agora para a você o conceito mais importante da criação de jogos multiplayer:

Todo objeto ou textura que vá ser acessado na lógica do jogo, por Remote Procedure Call, TEM QUE TER UM NOME INDIVIDUALIZADO !

Em jogos bem simples, podemos usar a técnica que mostramos no nosso Curso Básico, em que criamos vários prefabs com nomes diferentes (Player0, Player1, Player2 etc.) o os instancializamos conforme iam entrando no jogo. No nosso exercício, só podíamos ter 10 "entrantes" (pessoas que acessavam o jogo numa sessão do servidor)...

Mas, num jogo mais sofisticado, semi-profissional, que vai ficar sempre "no ar", essa técnica não vai ser adequada - podemos ter centenas de "entrantes" (não confundir com jogadores simultâneos).

Nessa aula vamos ver como individualizar, objetos e texturas importantes do jogo, "on-the-fly", o que significa: em tempo de execução.

Repare que, apesar de terem o mesmo nome, os avatares têm networkView-viewID diferentes.

Nós vamos usar esse valor para individualizar algumas partes do avatar.

A primeira coisa que precisamos fazer, é "marcar" todos os gameobjects que vão sofrer alguma ação no jogo. Vamos dar a eles a "tag": toChange (pode ser qualquer nome). Já vimos como criar uma "tag" nessa lição.

Vamos colocar essa tag, no nosso exercício, em: "Human" e "Hero".

Feitas essas marcações, vamos colocar no prefab "Human", o script que, quando o avatar for instancializado, vai individualizar os nomes dos gameobjects marcados e de todos os materiais , pois pretendemos mudar as texturas de nossos avatares, para diferenciá-los .

O script será:

var entrante: String;
 
function Start(){
 entrante = gameObject.networkView.viewID.ToString().Remove(0,13);
 if(networkView.isMine) networkView.RPC("Mudar",RPCMode.AllBuffered,  entrante);
}
 


@RPC
function Mudar(ent:String){ 
 if(gameObject.networkView.viewID.ToString().Remove(0,13) ==ent){
  //mudar nomes de alguns gameobjects
  var gos= GetComponentsInChildren(Transform);
  for (go in gos){
   if(go.tag=="toChange")
   go.name = go.name+ent ;
  }
  //muda o nome de todos os materiais
  var renderers = GetComponentsInChildren(Renderer);
  for (r in renderers){
   for(i=0;i<r.materials.length;i++){
     r.materials[i].name = r.materials[i].name+ent ;
   }
  }
 }
}

Essa função "Mudar", vai mudar o "Player" (acessado no script Controle de Avatar) para "Human(Clone)" + "ent", o que individualizará o movimento do avatar.

Agora que individualizamos o que era necessário, vamos criar uma maneira de mudarmos as texturas de nossos avatares através da internet, como mostramos no Curso Básico. Qualquer pessoa que saiba desenhar e tenha onde fazer upload de seu desenho, poderá criar um avatar personalizado para entrar no jogo.

NOTA: Com a versão free do Unity, só podemos mudar as texturas de modelos com animação, como esse nosso avatar. Na versão PRO, podemos mudar todo o modelo, para termos avatares completamente diferentes para cada jogador.

Primeiro vejamos as texturas "padrão" de nosso avatar. Elas estão no gameobject "Hero":

Tem outra textura que é um quadrado preto.

Uma textura de modelo é, quase sempre distorcida, com coisas invertidas etc. - é preciso saber interpretar o que é cada coisa (descubra o que é o olho do avatar, por exemplo). Para a redesenharmos, temos que considerar isso. Alguém (um mal desenhista como eu) poderia criar umas novas texturas com poucas modificações, como essas:

E mais uma textura que é um quadrado com a cor do cabelo.

É importante lembrar que o modelo tem regiões com saliências. Assim, uma textura do avatar de calção e chinelos de dedo, pode ficar extranha...

Como faremos para carregar essas texturas customizadas?

Vamos criar uma janela na interface do jogo para se poder entrar com os endereços delas. Já vimos como criar uma janela nessa lição.

Já vimos também como carregar algo da internet nessa lição. Donde, o script a ser acoplado ao prebab "Human" é:

var entrante="";
var UmaVez = 0;
var renderizar : boolean  = false;  
var windowRect : Rect = Rect (20, 20, 320, 270); // se mudar, verificar no Inspector
var janelaEscondida = true;
var endTexturaTroncoI="www.dmu.com/textuDMU2.jpg";
var endTexturaCabecaI="www.dmu.com/textuDMU1.jpg";
var endTexturaCabeloI="www.dmu.com/textuDMU0.jpg";
var endTexturaTronco =" ";
var endTexturaCabeca =" ";
var endTexturaCabelo =" ";
var titBot="Avatar-Abre/Muda";
  
function Start(){
 entrante = gameObject.networkView.viewID.ToString().Remove(0,13);
}
function mostraJanela(){
 renderizar = true;
}
function escondeJanela(){
 renderizar = false;
}

function OnGUI() {
 GUI.depth = 1; //layer mais baixo que 0
  if(UmaVez==0 && networkView.isMine){ 
 if (GUI.Button(new Rect(10, Screen.height-30, 115, 20), titBot)){
	
  if (janelaEscondida == true){
   mostraJanela();
   janelaEscondida = false;
  }
  else{
  escondeJanela();
   janelaEscondida  = true;
   
     Carregar();
     UmaVez=1;
	 
   }
  }
 }

 if (renderizar){
  windowRect = GUI.Window (1, windowRect, janela1, "Redefina e feche a janela");
 }
}

function janela1 (windowID : int){
 GUI.DragWindow (Rect (0,0, 120, 20)); //altura da area de dragar bloqueia click
 GUI.Label(new Rect(10,40,400,20),"Corpo: enderêço da  textura");
 endTexturaTroncoI = GUI.TextField(new Rect(10,80,300,20),endTexturaTroncoI);
 GUI.Label(new Rect(10,120,400,20),"Cabeça/Braços: enderêço da textura");
 endTexturaCabecaI = GUI.TextField(new Rect(10,160,300,20),endTexturaCabecaI);
 GUI.Label(new Rect(10,190,400,20),"Cabelo: enderêço da textura");
 endTexturaCabeloI = GUI.TextField(new Rect(10,220,300,20),endTexturaCabeloI);
}

function Carregar(){
 endTexturaTronco =endTexturaTroncoI;
 endTexturaCabeca =endTexturaCabecaI;
 endTexturaCabelo =endTexturaCabeloI;
 if(networkView.isMine)networkView.RPC("CarregaCL",RPCMode.AllBuffered,entrante,endTexturaTronco,endTexturaCabeca,endTexturaCabelo);
}

@RPC
function CarregaCL(ent : String, tT : String, tC : String , tCl : String ){
 if(gameObject.networkView.viewID.ToString().Remove(0,13) == ent){
 
 //textura tronco
 var GOH =GameObject.Find("Hero" +ent);
 var urlTT = tT; 
 var downloadTT = WWW(urlTT);
 yield downloadTT; 
 GOH.renderer.materials[2].mainTexture = downloadTT.texture;
  
 //textura cabeca
 var urlTC = tC; 
 var downloadTC = WWW(urlTC);
 yield downloadTC; 
 GOH.renderer.materials[1].mainTexture = downloadTC.texture;
 
 //textura cabelo
 var urlTCl = tCl; 
 var downloadTCl = WWW(urlTCl);
 yield downloadTCl; 
 GOH.renderer.materials[0].mainTexture = downloadTCl.texture;
  
 }
}

Repare que usamos:GOH.renderer.materials[n].mainTexture, na substituição das texturas. Esses valores "n", aparecem no Inspector, quando selecionamos o "Hero" , que é quem tem as texturas:

Veja uma imagem dos dois avatares (um é o da DMU) que aparecem no jogo - a demo abaixo.

Repare os olhos azuis de nosso avatar DMU (como mudado na textura acima):

Uma pessoa pode criar suas texturas personalizadas e colocá-las disponíveis na internet. O Victor, nosso colega de Orkut - a quem agradecemos - criou duas que podem ser instaladas "on-the-fly" por seus endereços:

http://www.dmu.com/VictorAzul.jpg

http://www.dmu.com/VictorVerde.jpg

Baixe a demo zipada do exercício. Os avatares não têm ainda animação, nem atiram... Tente mudar as texturas para uma das opções apresentadas aqui - ou crie a sua.

RIGHTCLICANDO AQUI



LIÇÃO ANTERIOR PRÓXIMA LIÇÃO
ÍNDICE HOME PAGE