Don't you speak portuguese? Translate this site with Google Translator

Pensamento do Dia

Esquecer - se da morte e dos mortos é prestar um péssimo serviço à vida e aos vivos. (Philippe Ariès)

Programando em C# para Unity 3D

Programando em C# para Unity

Help

Ao trabalhar ou estudar sobre programação no Unity mantenha sempre esta janela aberta: http://docs.unity3d.com/ScriptReference/

Use e abuse da busca para encontrar detalhes sobre a programação.

Também fique atento às dicas do Editor quando autocompleta o código.

GameObject

O comportamento dos GameObjects é controlado pelos componentes que são anexados a eles. O Unity considera os script como componentes e estes dão interatividade aos objetos do jogo.

Script

Criar uma pasta chamada Scripts em Assets:

Clicar em Assets

Do lado direito clicar com o botão direito – Create – Folder (com nome Scripts)

Abrir a pasta criada com um duplo clique

Clicar com botão direito do mouse na área livre

Create – C# Script com nome JogadorScript

O Unity suporta nativamente 3 linguagens de programação. Quando criamos um script precisamos especificar que linguagem ele usará. Podemos usar JavaScript, CSharp ou Boo.

Quando criamos um script em C# ou Boo e o abrimos no editor, ele já nos mostra uma pequena estrutura com uma classe e a definição de duas funções: Start() e Update(). Se for JavaScript ele não tem classe, apenas as funções.

Recomenda-se que cada script contenha somente uma classe e seja somente sobre um único assunto.

Cada script somente pode usar uma linguagem de programação, mas nós podemos usar scripts das 3 linguagens se quisermos em um único jogo, o que não é comum nem recomendado.

Neste tutorial iremos utilizar a linguagem C# (Csharp).

Inicialização de Variáveis Públicas do tipo GameObject

Estas variáveis devem ser completadas pelo Inspector, arrastando para elas um GameObject da Hierarquia ou um Prefab do Assets.

Anexar o Script à Main Camera

Como estes scripts iniciais usarão apenas comandos da Console, anexaremos à Main Camera. Arraste o nome do script e solte sobre a Main Camera na Hierarquia.

Boa Prática

Nomear as variáveis tipo GameObject com o sufixo Prefab:

public GameObject balaPrefab;

Tecla de Atalho para Help Online no Monodevelop

Selecione a palavra sobre a qual quer ajuda e tecle

Ctrl + '

Orientação a Objetos

Objetos são instanciados (clonados) de classes. Uma classe é justamente um arquivo que traz as definições de seu objeto.

Quando rodamos nosso jogo no Unity cada inimigo deve ser equipado com uma cópia do objeto.

Abrir o Script no Editor

Ao efetuar um duplo clique no nome do script ele é aberto no editor Monodevelop. O Unity, para facilitar nossa vida, já mostra um template de script com alguns comandos como abaixo:

using UnityEngine;

using System.Collections;

public class JogadorScript : MonoBehaviour {

// Use this for initialization

void Start () {

}

// Update is called once per frame

void Update () {

}

}

Renomear Script

Quando criamos um script o Unity dá o nome NewBehaviourScript a ele.

Devemos renomer o mesmo antes que perca o foco. Caso demoremos a fazer isso, após renomear e quando abrir o nome da classe estará como o nome original do script, ou seja, NewBehaviourScript. Precisará renomear a classe para que tenha o mesmo nome do script e funcione corretamente.

Includes

As duas primeiras linhas:

using UnityEngine;

using System.Collections;

Incluem as bibliotecas do Unity para que fiquem disponíveis no script.

Classe

A linha:

public class JogadorScript : MonoBehaviour {

Cria uma classe que herda da MonoBehaviour.

Toda script tem uma classe criada obrigatoriamente com o mesmo nome do script.

Base para a Linguagem C#

As bases de uma linguagem orientada a objetos são as variáveis e os métodos. Em CSharp qualquer código deve ficar dentro de uma classe.

Orientação a Objetos

Como C# é uma linguagem orientada a objetos é mais coerente usarmos o termo método no lugar de função.

Variáveis

É uma pequena seção da memória do computador onde guardamos valores. Podemos comparar as variáveis a gavetas. Cada gaveta guarda o nome da variável, o tipo, a visibilidade e o valor.


Definição/Criação de Variável

private int velocidade;

public int espaco;

Inicializando Variável

velocidade = 60;

espaco = 2;

Usando/Chamando Variável

tempo = espaco / velocidade;

Final de Linha

Toda linha de código em C# termina com ponto e vírgula (;).

Exemplo:

public int number1 = 2;

O C# exige que uma variável seja inicializada (receba valor) antes de ser usada.

Visibilidade/Modificadores de Acesso

public – são variáveis que podem ser acessadas também por outros scripts. Aparecem no Inspector para atribuição e alteração

private – são acessíveis somente no script onde são criadas. Não aparecem no Inspector

local – são acessíveis somente dentro da função onde foram criadas. Não aparecem no Inspector

Quando não especificamos a visibilidade é assumida private, que é a default.

No JavaScript, para ser public, basta que seja criada fora de função.

Exemplo:

public int nomeVariavel = 3;

ou

public void Start()

Comentários

// Comentários de linha única

/* Comentários

para várias

linhas

*/

Indentação

Importante para a organização e legibilidade do código

void Start(){

if(x == 0){

y = 3;

}

}

Editar Script

Edite o script e adicione as variáveis abaixo da linha da definição da Classe. Assim:

using UnityEngine;

using System.Collections;

public class VeriaveisScript : MonoBehaviour {

// Definição das variáveis

public int velocidade;

public int distancia;

public int tempo;

void Start () {

// Inicialização

distancia = 120;

tempo = 2;

// Usando

velocidade = distancia / tempo;

print (“A velocidade é de “ + velocidade);

}

}

O comando print é mostrado apenas na barra de status e na janela Console.

Selecionar a janela Console e clicar em Play.

public class MetodoScript : MonoBehaviour {

public int arma = 0;

// Use this for initialization

void Start () {

SacarArma ();

}

// Update is called once per frame

void SacarArma () {

// Armas com codigo: 1-espada, 2-flecha, 3-revolver, 4-rifle

arma = Random.Range (1, 5);

switch(arma){

case 1:

print ("Voce encontrou a espada");

break;

case 2:

print ("Voce encontrou a flecha");

break;

case 3:

print ("Voce encontrou o revolver");

break;

case 4:

print ("Voce encontrou o rifle");

break;

default:

print ("Voce nao encontrou nada");

break;

}

}

}

Execute algumas vezes.

Tipos de Dados

int – inteiros

float – ponto flutuante, são números decimais. Em C# devem ter seus valores escritos com um f ao final, para distinguir dos inteiros. Ex: float speed = 3.2f;

string – são dados do tipo texto

Visibilidade – Níveis de Acesso

Nomes de Variáveis e Métodos

Alguns nomes são proibidos, pois tem seu uso reservado pelo Unity, como é o caso de algumas letras:

x, y, z

Que são usadas internamente pelo transform.

Expressões e Precedência

Precisamos aprender a manipular as expressões em programação, assim como em Matemática. Aprender sobre a ordem de precedência, quem é executado primeiro, quem depois, etc.

Exemplo:

int variavelInt;

float variavelInt2;

variavelInt2 = 3;

variavelInt = 10 + 3 * variavelInt2;

Melhor é fazer assim, usando parêntesis, caso contrário dará um resultado errado:

variavelInt = (10 + 3) * variavelInt2;

Comando Condicional - if

Criar um script chamado IfScript. Remova o script Variaveis da Main Camera e anexe este.

A mais comum forma de tomar decisões é usando o comando if.

Operador NOT

if(!variavel)...

using UnityEngine;

using System.Collections;

public class IfScript : MonoBehaviour {

// Definição das variáveis

public int velocidade;

public int distancia;

public int tempo;

// Use this for initialization

void Start () {

// Inicialização

distancia = 180;

tempo = 10;

velocidade = distancia / tempo;

if(velocidade > 70){

print (“Desacelere, pois sua velocidade é de “ + velocidade);

}

}

}

Execute.

Atribuição

= é usado para atribuir, para gravar um valor em uma variável. Exemplo:

velocidade = 5; // Diz que a variável recebeu 5, agora tem 5 armazenado nela

== usado nas comparações com if, para comparar uma variável com um valor ou com outra variável. Exemplo:

if (x == 3)

ou

if ( x == z)

Operadores

Operadores de Comparação

==, >, <, >=, <=, !=

Operadores Lógicos

&& - AND

|| - OR

! - NOT

Operadores Matemáticos

+, -, *, /, %, ++, --

*=, +=, /=, -=, %=

Comando Switch - Instruções switch agem como condicionais if. Elas serão úteis para quando você quiser comparar uma única variável contra uma série de constantes.

Este comando substitui vários ifs em algumas vezes.

Crie um script SwitchScript contendo:

using UnityEngine;

using System.Collections;

public class SwitchScript : MonoBehaviour {

public int arma = 0;

void Start () {

// Armas com codigo: 1-espada, 2-flecha, 3-revolver, 4-rifle

arma = Random.Range (1, 5);

switch(arma){

case 1:

print ("Voce encontrou a espada");

break;

case 2:

print ("Voce encontrou a flecha");

break;

case 3:

print ("Voce encontrou o revolver");

break;

case 4:

print ("Voce encontrou o rifle");

break;

default:

print ("Voce nao encontrou nada");

break;

}

}

}

Execute várias vezes.

Métodos

É onde acontecem as ações. Um método contem um trecho de código, é um pequeno programa dentro do script.

Geralmente o código nos scripts é executado uma linha por vez.

Quando criamos nosso código geralmente queremos executá-lo mais de uma vez e queremos poder executar apenas um trecho de código.

O código dos métodos inicia na próxima linha após o início da chave e termina na linha imediatamente anterior ao final da chave.

Métodos são usados para oferecer comportamento aos GameObjects e também para reutilizar código.

Todo código executável em scripts está dentro de métodos.

Se nosso código executa algumas tarefas várias vezes ele está nos dizendo que devemos criar um método e apenas chamá-lo sempre que quisermos executar o código.

Exemplo: precisamos multiplicar dois números em várias partes do código. Então criamos um pequeno método chamado ProdutoDois() e apenas o chamamos quando precisarmos multiplicar os dois numeros.

Editar o script e adicionar duas variáveis:

public int numberOne = 2;

public int numberTwo = 9;

Insira no método Update():

if (Input.GetKeyUp(KeyCode.Return)) // Quando teclar Enter

ProductTwo(); // irá processar o método

Adicionar abaixo do método Update():

void ProductTwo(){

Debug.Log(numberOne * numberTwo);

}

Um método também quando chamado ele processa todo o código do seu conteúdo.

Métodos tem duas chaves, no início uma chave abrindo e ao final fechando a chave.

Os métodos que criamos somente serão executados quando forem chamados. Os métodos do Unity Start e Update são executados automaticamente pelo próprio Unity.

Chamando/executando um Método

ProductTwo();

Um método pode ter muitas linhas de código em seu interior. Um método é chamado um pequeno programa dentro de outro.

Tipos de Métodos:

Simples, apenas executando um trecho de código:

void ProductTwo(){

Debug.Log(numberOne * numberTwo);

}

Método que recebe parâmetros – recebe variáveis e processa em seu conteúdo

void ProductTwo(int x, int y){

Debug.Log(x * y);

}

Método que Retorna valores – pode receber variáveis e retorna o valor de uma variável de certo tipo

public int ProductTwo(int x, int y){

int produto = (x * y);

return produto;

}

Nomes de Métodos

-visibilidade

-tipo de dados que o método retornará

-nome do método, CamelCase e seguido de ()

-código delimitado por chaves { }

visibilidade tipoDeRetorno NomeMetodo(){

corpo do método;

}

void – usado quando o método não retorna nada.

Parâmetros – usados na definição da função: firstNumber e secondNumber.

Argumentos – usados na chamada da função: 3 e 4.

O comando return deve ser o último comando da função.

Estruturas de Laço

Laço for

Crie um script chamado ForScript contendo:

using UnityEngine;

using System.Collections;

public class ForScript : MonoBehaviour {

void Start () {

BuscaInimigo ();

}

// Update is called once per frame

void BuscaInimigo () {

for (int i=0; i < 5; i++) {

print ("Valor de i " + i);

}

}

}

foreach – laço que mostra os elementos de um array

using UnityEngine; using System.Collections; public class ForeachLoop : MonoBehaviour {
void Start () {
string[] strings = new string[3];
strings[0] = "First string";
strings[1] = "Second string";
strings[2] = "Third string";
foreach(string item in strings) {
print (item);
}
}
}

Execute e veja o resultado.

Arrays/Matrizes

Um array é tipo uma variável e é uma forma de uma variável conter mais de um tipo de dados.

Criar 3 empty GameObjects chamados:

gato, cachorro e porco

Criar a tag Inimigo

Selecionar os 3 e adicionar a tag a eles

Exemplo:

public GameObject[ ] players;

using UnityEngine;

using System.Collections;

public class ArrayScript : MonoBehaviour

{

public GameObject[] players;

void Start (){

players = GameObject.FindGameObjectsWithTag("Inimigo");

for(int i = 0; i < players.Length; i++){

Debug.Log("Inimigo numero "+i+" tem o nome "+players[i].name);

}

}

}

Classes

Classes contém variáveis e métodos e processam seus dados.

Em Unity praticamente não lidamos com a classe pois ele já cria para nós, mas todo script já vem com uma classe, cujo nome é o mesmo do script.

Como usar classes para armazenar e organizar suas informações e como criar construtores para trabalhar com partes de sua classe

Componente Script

Lembrar que um script é um componente no Unity que deve ser anexado a um GameObject para funcionar. Ao anexar o nome do script aparece ao final das propriedades do Objeto no Inspector. Também aparecem as variáveis public.

Os scripts é que dão interatividade e vida aos jogos.

Variáveis armazenam dados.

Métodos permitem a execução de tarefas.

Sintaxe dos pontos

transform.position.x;

Alterações das Propriedades

Podemos alterar as propriedades do Inspector tanto na cena quanto quando o jogo está executando. Alterações quando executando aparecem imediatamente mas se perdem logo que o jogo é parado.

O valor entrado nas variáveis no Inspector sobrescreve o valor original do script.

Resetando Mudanças

Para desfazer mudanças feitas nas variáveis de um objeto, melhor de um componente, basta clicar com o botão direito na pequena roldana à direita do nome do componente e clicar em Reset.

Nomes de Variáveis

Crie nomes simples e claros para suas variáveis.

Lembre da convenção:

-quando formado por uma única palavra, ele deve ser toda em minúscula:

private int speed;

-quando palavra composta, a primeira é com tudo minúsculo e a segunda iniciada com maiúscula, camelCase:

private int speedPlayer;

Nomes de Métodos

Seguem as mesmas regras, apenas com () ao final, mas assim CamelCase, diferente das variáveis devem iniciar com maiúscula como Start().

Nomes de Classes

Estes também devem ser CamelCase mas com inicial maiúscula.

Onde Declarar Variáveis

O local do código onde a variável é declarada é importante em termos de visibilidade.

Variáveis declaradas no início do script, logo abaixo da declaração da classe

Escopo das Variáveis

using UnityEngine;

using System.Collections;

public class LearningScript : MonoBehaviour {// --------Bloco 1

public string block1 = "Bloco 1";

// Use this for initialization

void Start () { // -------- Bloco 2

Debug.Log (block1);

string block2 = "Bloco 2";

Debug.Log (block2);

{// --------- Bloco 3

Debug.Log (block1);

Debug.Log (block2);

string block3 = "Bloco 3";

} // Final Bloco 3

} // Final Bloco 2

void Metodo(){// --- Bloco 4

string block4 = "Bloco 4";

Debug.Log (block4);

}// Final Bloco 4

} // Final Bloco 1

Bloco 3 – criado apenas com as chaves.

Tente mostrar a variével block3 no segundo bloco ou a block4 no bloco 3 e veja que o editor já reclama.

O escopo é determinado pela chaves dos blocos. As chaves limitam um bloco de código.

Variável é o primeiro bloco de código em C#.

Método é o segundo.

Editor

Quando tentamos trabalhar com uma variável ou método que ainda não foi declarado o editor já nos alerta mudando a cor do mesmo para vermelho. Logo que corrigimos fica preto.

Sintaxe do Ponto

GameObject.Component

GameObject.Component.variavel ou metodo

Funções de Inicialização

As funções que são executadas automaticamente pelo Unity, sem interferência do programador.

Método Start()

Chamado pelo Unity somente uma vez a cada execução do jogo. Primariamente usado para inicializar ou configurar as variáveis.

Método Update()

A maioria do código dos scripts vai dentro deste método. A cena é mostrada várias vezes por segundo, que é chamado de Frames por Segundo – FPS. Após a exibição de cada frame, o método Update() é chamado pelo Unity para executar seu código.

Permite ao jogo detectar entradas (inputs), cliques do mouse, teclas pressionadas, a cada frame.

O método Update() é adequado para uso de movimentação através de teclas.

awake() e start()

Update() e FixedUpdate()

Como efetuar mudanças a cada frame/quadro com a atualização usando as funções Update e FixedUpdate e suas diferenças.

Mostrando os métodos de Inicialização em Ação

Debug.Log("ExecutionOrder::global");

void Awake() {

Debug.Log("ExecutionOrder::Awake");

}

void Start () {

Debug.Log("ExecutionOrder::Start");

}

void Update () {

Debug.Log("ExecutionOrder::Update");

}

void FixedUpdate() {

Debug.Log("ExecutionOrder::FixedUpdate");

}

void LateUpdate() {

Debug.Log("ExecutionOrder::LateUpdate");

}

void OnRenderObject() {

Debug.Log("ExecutionOrder::OnRenderObject");

}

Objetos Internos do Unity

Um script unity é escrito em uma linguagem de programação, com seus recursos básicos e também conta com classes e funções/métodos da biblioeca do Unity. Um script em C# tem diferenças básicas de um script em JavaScript mas tem em comum os recursos da biblioteca do Unity que ambas utilizam.

transform

transform.Translate(1, 1, 1);
transform.Translate(Vector3.forward * Time.deltaTime);
transform.Translate(Vector3.up * Time.deltaTime, Space.World);

Vector2

Vector2(float x, float y);

Instantiate

var spawnPoint = new Vector2(Random.Range(x1, x2), transform.position.y);

Instantiate(asteroidePrefab, spawnPoint, Quaternion.identity);

Quaternion

Quaternion(float x, float y, float z, float w);

Ver a referência completa dos objetos do Unity aqui:

http://docs.unity3d.com/ScriptReference/

Quando acessamos esta página acima, à direita e acima aparecem as 3 linguagens para que selecionemos a que queremos perquisar.

Quaternions - É a posição e o ângulo de um objeto a ser rotacionado. Para realizar a rotação de objetos no espaço tridimensional são utilizados quaterniões.

Para representar a direção que um objeto aponta no espaço não basta apenas representar sua posição, é necessário atribuir um ângulo a ela. Em jogos quando um objeto é criado, é definida a sua posição e um ângulo inicial a ele. Quando desejamos fazer alguma rotação nesse objeto, realizamos com base em sua posição e seu ângulo atual, ou seja, em seu quaternião.

Destroy

Destroy(gameObject, 20); // Destroi objeto após 20 segundos

Exemplos de Scripts para Jogos

Movimento

Tiro

Limitando na Tela

Criando um Labirinto via Código

using UnityEngine;
using System.Collections;

public class Grade : MonoBehaviour {
// Referência - http://docs.unity3d.com/Manual/InstantiatingPrefabs.html
public GameObject cubo;
private int x,y;

void Start() {
LabirintoX(-9, 9, -5, -4);
LabirintoX(-9, 9, 0, 4);
LabirintoY(-4, 4, 0, 9);
LabirintoY(-4, 4, 0, -9);
LabirintoY(-4, 3, 0, -6);
LabirintoX(-5, 3, 0, 3);
LabirintoX(-5, 3, 0, 2);
LabirintoX(1, 5, 0, -3);
LabirintoX(1, 5, 0, -2);
LabirintoX(1, 5, 0, -1);
LabirintoX(1, 5, 0, 0);
LabirintoX(-4, 3, 0, -3);
LabirintoX(-4, -1, 0, -2);
LabirintoX(-4, -1, 0, -1);
LabirintoX(-4, -1, 0, 0);
//LabirintoX(-4, 0, 0, -1);
/*
y = -4;
for(x=-9;x <=9;x++){
if(x == -6) continue;
Instantiate(cubo, new Vector3(x, y, 0), Quaternion.identity);
}*/
}

void LabirintoX(int x1, int x2, int pulo, int y){
for(x=x1;x <=x2;x++){
if(pulo != 0 && x == pulo) continue;
Instantiate(cubo, new Vector3(x, y, 0), Quaternion.identity);
}
}

void LabirintoY(int y1, int y2, int pulo, int x){
for(y=y1;y <=y2;y++){
if(pulo != 0 && y == pulo) continue;
Instantiate(cubo, new Vector3(x, y, 0), Quaternion.identity);
}
}
}

Corrigindo Erros/Debugando

Editor Monodevelop

O editor Monodevelop ajuda muito na correção de erros. Alguns erros ele acusa logo no script. Tão logo digitemos o nome de uma variável para usá-la e antes de a definir, ele nós alerta deixando o nome em vermelho. Isso significa que ele exige que toda variável só pode ser usada quando definida/criada antes.

Ele também nos ajuda auto-completando a sintaxe de métodos e objetos internos do Unity.

Unity
Quando salvamos um script e voltamos para o Unity geralmente, havendo erro no script, o Unity avisa do erro com mais detalhes que o editor. Ele mostra o erro, o script e a linha, além de outras informações úteis e isso em vermelho na barra de status.

Algumas vezes ele não mostra detalhes sobre o erro, apenas a mensagem. Quando isso acontecer devemos acessar a Console e clicar na mensagem para receber mais detalhes.

Ferramentas
A console ajuda muito na correção de erros.
Podemos usar o comando Debug.Log para mostrar uma mensagem em uma região do script que desconfiamos de erro, ou mostrar o valor de uma variável.
Exemplos:
Debug.Log(“Teste”);

Debug.Log(“Velocidade vale: ” + speed);

Variáveis public

Quando declaramos uma variável public e do tipo GameObject no script, precisamos atribuir um prefab ou objeto a ela pelo Inspector do Unity. Quando esquecemos de fazer isso recebemos a mensagem: Null Reference Exception

Pacote com Scripts em C#

scripts.zip

Comments fornecido por CComment

Novo Testamento

Então entenderam os discípulos que lhes falara de João o Batista.
(Mt, 17:13)

Rotas no Mapa do Google

© 2015 Ribamar FS. All Rights Reserved. Designed By JoomShaper