
Esse pequeno curso é baseado em um "example project" da Unity Tec, chamado "3rd Person Shooter".
IMPORTANTE: Os modelos aqui apresentados foram desenvolvidos pela Unity Tec e não são licenciados Creative Commons (como o material "normal" de nosso site) donde só podem ser usados segundo as regras de licença da Unity Tec para assets que ela disponibiliza em tutoriais e exemplos. Procure se informar sobre esse assunto, se não for usá-los apenas particularmente para os exercícios desse curso.
Procuramos adaptar o projeto ao estilo dos cursos DMU, simplificando-o bastante, com dificuldade gradual de exercícios (que você deve fazer para realmente aprender na prática), downloads de "pacotes" , demos interativas etc.
A maioria dos conceitos apresentados aqui, você já deve ter aprendido em nosso Curso Básico (pré-requisito desse) mas, algumas coisas são novidades interessantes e importantes. Principalmente a possibilidade de criar jogos multiplayer sem limite de "entrantes".
Durante a criação desse curso usamos a versão 3.3 do Unity.
Aproveitem: aprendam e se divirtam.
Américo Damasceno Jr. - maio/junho 2011
Vamos começar fazendo o download de dois pacotes,
Abra um novo projeto no editor do Unity e importe esses pacotes.
Se você customizou a interface do editor como sugerido em nosso Curso Básico , vai encontrar as duas coisas assinaladas na figura, que vamos usar nesse curso:

Antes de começar esse curso, você deve reler:
Terminada essa revisão, vamos começar.
Historinha: No século XXXI, não temos mais futebol. Apesar de todas as baixarias e violências que existiam no futebol, desde o século XX, o pessoal ainda achava isso pouco, e, quando alguém resolveu lançar um novo esporte(?) chamado "Arena Mortal", o público de futebol foi definhando. Com a transformação da FIFA em FIAM (Federação Internacional de Arena Mortal), a coisa ficou consolidada.
Quais as regras desse novo jogo?
Muito simples: cada time é constituido de apenas um jogador, que entra armado numa Arena (donde o nome) e vai enfrentar outros jogadores de outros times. O "gol" é matar um adversário. Quem ficar vivo por último ganha o campeonato.
Devido a questão de segurança, a Arena (o "estádio") não tem arquibancadas e os jogos são transmitidos pela televisão.
Esse roteiro de jogo (completamente idiota) é só para justificar o exercício que vai sustentar nosso curso.
Vamos começar então colocando a "Arena Mortal" no espaço 3D. Arraste a "courtyard" para uma das views e faça um Reset (no Transform do Inspector) para colocá-la em (0,0,0).

Como fizemos no Curso Básico, crie um gameobject vazio com o nome "Administration" na divisória "Project" - vamos trabalhar com nomes em inglês nesse curso, pois ele vai ter uma versão internacional. Acople uma "NetworkView" à ele. E também o script - já explicado em detalhes no Curso Básico - que vamos chamar de "ServCli.js":
var IPServer = "127.0.0.1";
var IPServ = "";
function OnGUI (){
if (Network.peerType == NetworkPeerType.Disconnected){
IPServer = GUI.TextField(new Rect(120,10,100,20),IPServer);
if (GUI.Button (new Rect(10,10,100,30),"Conect")){
Network.Connect(IPServer, 25000);
}
if (GUI.Button (new Rect(10,50,100,30),"Start Server")){
Network.InitializeServer(50, 25000,false);
for (var go : GameObject in FindObjectsOfType(GameObject)){
go.SendMessage("OnLoaded", SendMessageOptions.DontRequireReceiver);
}
}
}
else{
if(Network.isServer){
IPServ = Network.player.ipAddress;
GUI.Label(new Rect(140,20,250,40),"IP to be used: "+IPServ );
}
if (GUI.Button (new Rect(10,10,100,30),"Exit")){
if(Network.isServer){
networkView.RPC("ExitCL", RPCMode.Others);
}
Network.Disconnect();
Application.Quit();
}
}
}
function OnConnectedToServer() {
for (var go : GameObject in FindObjectsOfType(GameObject))
go.SendMessage("OnLoaded", SendMessageOptions.DontRequireReceiver);
}
@RPC
function ExitCL(){
Application.Quit();
}
Você deve se lembrar que os avatares vão ser criados no local onde estiver o gameobject vazio "Administration", donde, focalize, na view "Perspective" (veja a figura abaixo), a escada e coloque-o logo acima:

Coloque também um NetworkView no prefab de nosso avatar básico, que tem o nome: "Human".
Assim como na Lição 23 do Curso Básico, linkada acima, vamos acoplar também no "Administration" o script que cria e é "Controlador de Avatar", que vamos chamar de "AvatarControl.js":
var velocity = 5.0;
var velJump = 8.0;
var gravity = 20.0;
private var deltaDirection : Vector3;
var Player : GameObject;
var contr : CharacterController;
var playerClone: String;
var avatar0: Transform;
function OnLoaded(){
Network.Instantiate(avatar0, transform.position, transform.rotation, 0);
playerClone = "Human(Clone)";
Player = GameObject.Find(playerClone);
contr = Player.GetComponent(CharacterController);
}
function Update(){
if(!Player) return;
if (contr.isGrounded){
Player.transform.eulerAngles.y += Input.GetAxis("Horizontal");
deltaDirection = Vector3(0, 0,Input.GetAxis("Vertical"));
deltaDirection = Player.transform.TransformDirection(deltaDirection);
deltaDirection *= velocity;
if (Input.GetButton ("Jump")) {
deltaDirection.y = velJump;
}
}
deltaDirection.y -= gravity * Time.deltaTime;
contr.Move(deltaDirection * Time.deltaTime);
}
function OnPlayerDisconnected (player : NetworkPlayer){
Network.RemoveRPCs(player, 0);
Network.DestroyPlayerObjects(player);
}
O que aparece de diferente em relação ao que vimos é que aqui, o avatar instancializado vai receber do Unity. o nome de "Human(Clone)", pois é sempre deduzido do nome do prefab.
Para a variável "avatar0", no "Inspector, vamos arrastar o "Human".
Para chegarmos ao nível das aulas citadas acima, falta apenas, acoplarmos, na Main Camera, o script:
var target : Transform;
var distance = 5.0;
var height = 1.0;
var heightDamping = 2.0;
var rotationDamping = 3.0;
var ac: AvatarControl;
function LateUpdate () {
if(!ac.Player) return;
target = ac.Player.transform;
if(!target) return;
wantedRotationAngle = target.eulerAngles.y;
wantedHeight = target.position.y + height;
currentRotationAngle = transform.eulerAngles.y;
currentHeight = transform.position.y;
currentRotationAngle = Mathf.LerpAngle (currentRotationAngle, wantedRotationAngle,rotationDamping * Time.deltaTime);
currentHeight = Mathf.Lerp (currentHeight, wantedHeight, heightDamping * Time.deltaTime);
currentRotation = Quaternion.Euler (0, currentRotationAngle, 0);
transform.position = target.position;
transform.position -= currentRotation * Vector3.forward * distance;
transform.position.y = currentHeight;
transform.LookAt (target);
}
O que aparece de diferente aqui é que criamos a variável-prefixo: var ac: AvatarControl, que vai capturar o avatar lá no outro script. Você tem que arrastar o "Administration", que contém s script "AvatarControl", para a variável-prefixo, no Inspector.
Agora, já podemos criar um executável do exercício dessa aula e, para isso, como já enfatizamos, não deixe de ticar "Run In Background" e colocar "Display Resolution Dialog" em "Disabled".

Baixe a demo zipada do exercício :
Você pode criar várias cópias do jogo(?) em sua máquina. Repare que os avatares não têm animação e são clones. Vamos mostrar como se faz para mudar isso, depois.

PRÓXIMA LIÇÃO ÍNDICE HOME PAGE