Sei sulla pagina 1di 183

Introdução ao Jogo de programação:

Usando C # e Unity 3D
Conteúdo

Agradecimentos ………………………………………… ix
Sobre o autor ………………………………………… xi
Prefácio ………………………………………… xiii
Introdução ………………………………………… 1
Capítulo 1 – Conceitos de Programação ………………………………………… 3
O que é um Programa? ………………………………………… 3
Fundamentos da Programação ………………………………………… 3
Conceitos de programação orientada a objetos ………………………………………… 16
Classes e Objetos ………………………………………… 17
Encapsulamento ………………………………………… 20
Passagem de mensagens ………………………………………… 22
Abstração ………………………………………… 22
Composição ………………………………………… 23
Herança ………………………………………… 24
Polimorfismo ………………………………………… 25
Modularidade ………………………………………… 25
Genéricos ………………………………………… 26
Interfaces ………………………………………… 28
Delegados ………………………………………… 29
Eventos ………………………………………… 30
Capítulo 2 - Breve Introdução à IDE Unity ………………………………………… 35
Resumo da interface ………………………………………… 35
Painel Cena ………………………………………… 36
Painel Game ………………………………………… 36
O Inspetor ………………………………………… 36
Janela Hierarquia ………………………………………… 37
Janela Projeto ………………………………………… 37
Criando Nosso Primeiro Objeto do Jogo ………………………………………… 38
Entrar na Programação C # e Unity 3D ………………………………………… 46
Editar Construtor e Configurações do Jogador ………………………………………… 49
Capítulo 3 - Objetos do Jogo e Componentes ………………………………………… 51
O que é um GameObject? ………………………………………… 51
Adicionando e Editando Componentes ………………………………………… 52
Scripts como Componentes ………………………………………… 53
GameObjets Estáticos ………………………………………… 54
Prefabs – Conceitos e Uso ………………………………………… 59
Relacionamento Pai-filho ………………………………………… 60
Capítulo 4 – Regras e Mecânica de Jogo ………………………………………… 61
Conceitos Básicos de Mecânica de Jogo ………………………………………… 61
Exemplos Simples da Mecânica ………………………………………… 66
Física para os Jogos ………………………………………… 71
Entrar no Componente Collider ………………………………………… 72
Interações do Collider ………………………………………… 73
Corpo rígido ………………………………………… 74
Juntas ………………………………………… 74
Mecânica de Caracteres ………………………………………… 78
Capítulo 5 – Criando a Interface do Usuário ………………………………………… 131
Os Princípios de Design de Interface em Unity 5 ………………………………………… 132
Criando Nossa Primeira Interface do Usuário ………………………………………… 141
Melhorar a Interface do Usuário ………………………………………… 175
Capítulo 6 - Criando Battleship ………………………………………… 185
Contexto Histórico ………………………………………… 185
Play de Jogo ………………………………………… 186
Plano de Jogo para a Implementação ………………………………………… 187
Reunindo tudo – Objetos do Jogo ………………………………………… 196
Fluxo de Jogo + Lógica ………………………………………… 199
Interface de Usuário do Jogo ………………………………………… 203
Capítulo 7 – Aprofundando-se nos Códigos ………………………………………… 207
Script – BoardUIVer1.cs ………………………………………… 207
Script – BoardVer1.cs ………………………………………… 212
Funções Definidas na Classe BoardVer1 ………………………………………… 216
Interface de Usuário do Jogo ………………………………………… 248
Anexo 1 – Índice de figuras ………………………………………… 255
Índice de figuras ………………………………………… 255
Apêndice 2 – Tabela dos Blocos de Códigos ………………………………………… 257
Tabela dos Blocos de Códigos ………………………………………… 257

Agradecimentos
Quero aproveitar a oportunidade e reconhecer e agradecer a minha par-
entos lugar. Sinto-me humilde e grato pelas grandes obras que têm
realizado para mim. Eles têm sofrido muito por seus filhos e
deram-se muito para o bem de seus filhos. Espero que um dia
Eu posso pagar por seus esforços, e ser capaz de ser um bom pai para o meu próprio
crianças.
Em segundo lugar, gostaria de reconhecer cada indivíduo que tem
entrou e me influenciou por toda a minha vida. Estes são os mentores
desde a minha infância, seguido por meus professores na universidade e
todos os outros no meio. O bom, o mau eo feio, tenho verdadeiramente
moldado e formado o meu caráter, personalidade e sabedoria. Pode o
jornada continuar para sempre!
Por último, gostaria de agradecer a minha mulher para pacientemente lendo
o projecto do livro e dando-lhe um feedback ao longo do
desenvolvimento. O livro é nem perto de uma obra de arte, e com certeza
não é romance romântico. Pelo contrário, é muito seco e técnica, assim
obrigado por sua paciência e feedback, enquanto gestora da casa-
manter e cuidar das crianças, que, no momento da redação deste texto são de
2 ½ anos e 4 meses de idade.

Sobre o autor
Quando criança, eu era sempre curioso sobre como as coisas funcionam e quais
a força motriz por trás deles era. Esta curiosidade, eventualmente, dirigido
me no estudo da Ciência da Computação. Um dos únicos campos com
potencial ilimitado para criar tudo o que você pode sempre possivelmente
conceber.
Na realidade, a capacidade de criar seu próprio mundo e ser capaz de com-
mand e controlar o virtual eo ambiente físico é o que eu
queria fazer. Como construir e robôs de controle, como fazer computadores
pensar, como criar uma simulação e assim por diante. Para encurtar a história, isso é
como a minha jornada começou.
Vahé Karamian detém um mestrado em ciência da computação, a sua
interesse incluem a forma de melhorar a aprendizagem virtual através do Virtual
Mundos e ambientes 3D. Ele desenvolveu e ensinou computador
cursos de ciências desde 2011. Os tópicos incluem Introdução à Computação
Ciência, Java, C #, Python, Estruturas de Dados e Algoritmos, Operating
Sistemas e Game Design e Programação.

Prefácio
O livro chegou a ser baseada em vários fatores. Em primeiro lugar,
o principal objetivo deste livro é fornecer um ponto de partida no campo
da ciência da computação e programação especificamente jogo. Em segundo lugar, é
destina-se como uma forma de aumentar o interesse em indivíduos no domínio da com-
ciência informática.
O livro é destinado a público específico. Supõe-se que o
leitor tem uma paixão para o estudo da ciência da computação, e que eles
tem uma paixão em game design e desenvolvimento. Assume-se também que
o leitor é pró-ativa e que eles teriam a capacidade de se envolver
num nível mais profundo por conta própria.
O livro destina-se principalmente para o programador em vez do
artista. Há uma abundância de livros lá fora, visando especificamente o ar-
parte tistic de desenvolvimento de jogos. Este livro é escrito para aqueles que
quer dar vida às partes artístico bonito! É para a mágica
parte de todo o processo. É para o guerreiro código.
Uma vez que os temas discutidos no livro são extremamente grandes em
amplitude e profundidade, é impossível cobrir todos os aspectos de uma
livro. Tendo em mente que este é concebido como um livro introdutório para
o assunto, o conteúdo discutido nos primeiros capítulos são genéricos
para o campo da ciência da computação, o resto do livro concentra-se em
mecânica do jogo e como escrever jogos de computador.
O outro assunto teria uma atração em comparação com jogo
design e desenvolvimento? O futuro da Human Computer Interaction
vai ser através de Realidade Virtual e Realidade Aumentada na
nos próximos anos. Este livros lhe dará os blocos de construção para o caminho-
caminho para o futuro.

Introdução
Este livro é escrito com dois objetivos em mente, em primeiro lugar, para introduzir
o leitor aos conceitos de programação usando C #, em segundo, para colocar em
praticar os conceitos de uma forma divertida e descontraída através do desenvolvimento de com-
jogos de informática e conceitos de design do jogo.
Mesmo que este é um livro introdutório, presumo que o leitor
teria alguma familiaridade com programação de computadores e object-
programação orientada com a linguagem C #. Assume-se também que o
leitor sabe o básico do ambiente Unity 3D.
No Capítulo 1, o leitor é dada uma breve visão geral sobre os conceitos
da programação e da terminologia projeto orientado a objetos. O capítulo
destina-se como uma referência rápida. Para aqueles leitores que já estão fa-
miliar com o básico, que será uma boa revisão rápida. Para aqueles leitores
que estão apenas começando para fora, ele vai te dar uma boa base e espero fazer
os temas mais acessíveis à medida que crescem no campo.
Capítulo 2, é uma introdução ao ambiente Unity 3D IDE.
As seções básicas do IDE são explicados. O usuário é mostrado como
navegar dentro do IDE e criar GameObjects. Como usar o trans-
ferramentas de formulário para a tradução, escala e girar uma GameObject. o Inspector
Janela é discutida em que todos os componentes e GameObject
propriedades podem ser modificadas através do designer e muitos outros útil
dicas e truques.
Capítulo 3, aprofunda o conceito de GameObjects. Como
criá-los, como adicionar componentes, existente ou personalizado. Scripts são
discutido e mostrado como eles podem ser anexados a GameObjects e agir
como componentes. O conceito de uma casa pré-fabricada é introduzido eo pai-
Relacionamento da criança dentro de um GameObject também é introduzido e dis-
amaldiçoado.
Capítulo 4, o leitor é apresentado a Regras e Mecânica de jogo.
Este é o capítulo que define as bases e as regras de design de jogo
e o desenvolvimento. Ele discute os conceitos básicos de mecânica de jogo que são
usado em todos os jogos para uma extensão. Em seguida, vários exemplos são construídos a partir
arranhar para ilustrar os conceitos. Física, aceleradores e corpo rígido são
também discutiu.
Capítulo 5, o leitor é apresentado ao design de interface do usuário, e
a nova arquitetura de built-in para o design da interface do usuário na Unidade 5. Uma visão geral
a arquitetura de interface do usuário é dada no capítulo e os exemplos construir em
Capítulo 4 são usados para introduzir conceitos de interface do usuário e demonstrar como
construir UIs interessantes para o seu jogo.
Capítulo 6, discute um jogo clássico chamado Battleship. Uma breve his-
tórica fundo é dado e as regras do jogo e jogo são discutidas.
Em seguida, o leitor é orientado as etapas para projetar e implementar
cução do jogo. Objetos do jogo, o fluxo de jogo, lógica do jogo eo usuário
interface são discutidas.
Capítulo 7, investiga o código C # que tem sido discutido e
gerado durante todo o Capítulo 6 e reforçada no Capítulo 7. A pri-
scripts de mary são dissecados, as funções são definidos e explicados ea
Interface de usuário para o jogo finalizado.

Capítulo 1 - Programação Conceitos


O que é um Programas?
Um programa é uma instrução de passo-a-passo, que foi concebido para
resolver um determinado problema. Aqui está outra definição:
"Uma lista organizada de instruções que, quando executado, faz com que o
computador a comportar-se de uma maneira predeterminada. Sem programas,
computadores são inúteis. "
Mas a melhor definição que foi dada foi pelo meu Professor Dr. Lee em
a classe estrutura de dados na Cal Poly:
Programa = Dados + Algorithm
Um programa é como uma receita. Ele contém uma lista de variáveis que representam
enviou os dados a serem processados, e uma lista de instruções, o algoritmo (s)
que executam operações especiais sobre os dados.
Fundamentos da Programação
Cada programa precisa para armazenar dados. A fim de armazenar dados em um com-
informática, nós usamos o que são chamados de variáveis. Uma variável precisa saber o que
tipo de dados que está armazenando, portanto, uma variável precisa ter um tipo de dados.
Tipos de dados
Linguagens e frameworks de programação de hoje oferecem vários
tipos de dados básicos que podem ser usados para armazenar e recuperar informações sobre
o computador. Esses tipos de dados são, em geral:
1. numérico
2. Alpha-Numeric
3. booleana
4. Complex

Os tipos de dados numéricos são representados por byte, short, int, long,
float e double. Tipos de dados alfanuméricos são CHAR e cordas. Então
você tem o seu tipo de dados booleano, que apanhar um verdadeiro de um falso valor,
e tipos de dados, finalmente complexas que são definidos pelo usuário. Complexo ou usuário
tipos de dados definidos são as classes que serão discutidos mais tarde.
Existem 15 diferentes built-in tipos de dados na linguagem C #. o
seguinte tabela vai listá-los para fora para você e também fornecer-lhe com o
gama possível de cada tipo.
Nome curto uint 9223372036854775 64 Tipo de base de
.NET Classe UInt32 807 - todos os outros
Digitar inteiro sem sinal ulong 1.79769313486232 tipos
Largura 32 UInt64 e308 para corda
Range (bits) De 0 a 4294967295 inteiro sem sinal 1.79769313486232 Corda
byte baixo 64 E308 A sequência de
Byte Int16 0- carbonizar caracteres
inteiro sem sinal inteiro assinado 1844674407370955 carbonizar decimal
8 16 1615 Um personagem Decimal
0 a 255 32.768 a 32.767 flutuador Unicode única Precise fraccionada
sbyte ushort solteiro 16 ou inte-
SByte UInt16 Flutuante de Unicode símbolos Tipo de gral que
inteiro assinado inteiro sem sinal precisão simples usados no texto pode
8 16 tipo de ponto bool representar
-128 A 127 0 a 65535 32 boolean números decimais
int longo -3.402823e38 Para Tipo booleano com 29 dígitos
Int32 Int64 3.402823e38 lógica significativos
inteiro assinado inteiro assinado duplo 8 128
32 64 Duplo Verdadeiro ou falso ± 1,0 × 10e-28 a ±
-2.147.483.648 - Flutuante de objeto 7,9 × 10e28
para 9223372036854775 precisão dupla Objeto
2,147,483,647 808 para tipo de ponto
O bloco de código a seguir ilustra como usar alguns dos mais
tipos de dados comuns:

// Verdadeiro ou falso - um pouco


bool b = true;

// 0 ... 255
byte B = 9;

// -32.768 .. 32.767
curtas s = 25;

// 2,147,483,648 ... 2.147.483, 647


int i = 10;
// -3.402823e38 ... 3.402823e38
float f = 10.0f;

// -9.223.372.036.854.775.808 .. 9.223.372.036.854.775.807
longo l = 34;
// -1.79769313486232e308 ... 1.79769313486232E308
dupla z = 13,33;

Código de bloco tipos 1-variáveis de atribuição e de dados


É importante compreender os tipos de dados. Cada variável que você definir
no seu programa tem que ser de algum tipo de dados. É importante ser capaz
atribuí-los adequadamente, ser capaz de atualizar e ou modificá-las e,
vezes, você vai querer converter de um tipo de dados para outro.
Condicionais e decisão de estruturas que permitam
Então precisamos de alguma maneira de fazer a decisão dentro do nosso programa
com base em algumas condições. Estas são feitas pela declaração if..else e
switch. Podemos ter várias instruções if..else. Nós também podemos
combinar declarações if..else condicionais com a instrução switch e
vise-versa.
int x = 4;
se (x> 2)
{
. System Console .WriteLine ( "X é> 2");
if (x <5)
{
. System Console .WriteLine ( "X é <5, mas> 2");
}
}
outro
{
. System Console .WriteLine ( "X é <= 2");
}
Bloquear Código 2-se ... exemplo de estrutura de outra pessoa
O computador tem de executar cada instrução de se encontrar.

page 20
Unity 3D - Jogo de Programação Intro
6
A porção do outro if..else é opcional, e apenas será executada
primeiro se ele é definido e, segundo, se a se a condição é falsa. o if..else
declaração também pode ser aninhados. Isso permite que o programador para verificar se há
muitas condições diferentes. Um exemplo seria:
se (x> 100)
{
// faça alguma coisa;
}
else if (x> = 25 && x <= 50)
{
// Fazer outra coisa
}
else if (x> = 10 && x <25)
{
// Fazer outra coisa
}
outro
{
// Fazer outra coisa
}
Código Bloco 3 - declaração if..else Nested
Em um comunicado if..else aninhada, cada um se condição será executado em
a ordem theyare listados. Uma vez que um dos, se as condições de satisfazer os critérios,
seu corpo vai ser executada, e o resto das condições serão ignorados.

page 21
Vahé Karamian
7
Os dois diagramas acima ilustram a condição if..else graph-
camente.
A instrução switch é uma outra maneira de fornecer a tomada de decisão
dentro de seus programas. Leva em uma variável como um parâmetro, e de-
multas casos especiais. Se o parâmetro satisfaz o caso, então o corpo de
o caso será executado. O caso default é opcional assim como o resto
declaração na estrutura de decisão if..else. Se o caso padrão é definido,
e nenhum dos casos primários são combinados, então ele será executado.
// X se de um valor atribuído antes desta etapa
switch (x)
{
case 1:
{
// Código aqui para lidar com caso quando x = 1
break;
}
case 2:
{
// Código aqui para lidar com caso quando x = 2
break;
}
case 3:
{
// Código aqui para lidar com caso quando x = 3
break;
}
default:
{
// Código aqui para lidar com lógica quando x
// Não corresponde a nenhum dos casos definidos
break;
}
}
Código Bloco 4-switch exemplo estrutura de declaração
Uma grande diferença que você vai notar entre o if..else eo
Estruturas de switch, é a capacidade de executar vários blocos de código em um
switch. Observe que cada caso é encerrado por uma quebra com-
mand. O comando ruptura é opcional. Se ele estiver presente, após o
execução do bloco caso, a estrutura switch irá terminar. Se for
não estiver presente, a lógica irá fluir para o próximo bloco caso.

page 22
Unity 3D - Jogo de Programação Intro
8
Para compreendê-lo, considere o seguinte: assumir o valor para o
variável x é definido como 1. Também assumem que a instrução break não é de-
multado no bloco caso. Quando a instrução switch é avaliado, ele vai
executar caso 1. Uma vez que não existe nenhum comando quebra de presente, ele irá exe-
bonito o próximo bloco caso, que passa a ser o caso 2. Isso vai continuar
até que uma instrução break é identificado.
Código Bloco 2 e Código Bloco 4 fornecer um exemplo simples de como
para usar a decisão de fazer declarações na linguagem C #. Tenha em mente
que a listagem exibir a estrutura básica, você pode estendê-los para atender
cenários complexos.

page 23
Vahé Karamian
9
Estruturas de loop
Às vezes a gente também precisa ser capaz de repetir o mesmo bloco de código
um certo número de vezes. Isto é conseguido em uma estrutura em ansa. Existem Sev-
estruturas de loop eral na linguagem C #:
loop
Byusing um loop for, você pode executar uma instrução ou um bloco de declaração
repetidamente até que uma expressão especificada for avaliada como falsa. Este tipo de
circuito é útil para a iteração sobre matrizes e para outras aplicações em
que você sabe de antemão quantas vezes você quiser que o loop para it-
perar. A estrutura de um loop for:
for (initializer; condição; iterator)
{
// Corpo do laço
}
A secção de inicializador define o inicial
condição. As declarações neste sec-
ção executado apenas uma vez, antes de entrar
o laço.
A secção contém uma condição Bool-
expressão ean que é avaliada para
determinar se o ciclo deve
sair ou continuar a executar.
A seção iterador define o que acon-
canetas após cada iteração do corpo de
o laço.
O corpo do circuito consiste numa
declaração, uma declaração vazia, ou uma
bloco de instruções que você cria
colocando a zero ou mais declaração em
suspensórios.
Figura 1 - para o diagrama de circuito
page 24
Unity 3D - Jogo de Programação Intro
10
loop foreach
A declaração foreach repete um grupo de comandos incorporados para
cada elemento em uma matriz ou um objeto de coleção que implementa o
IEnumerable ou IEnumerable <T> interface. A declaração foreach é
usado para percorrer uma coleção para obter a informação que você precisa, mas
ele não pode ser usado para adicionar ou remover itens do conjunto fonte.
Isto é para evitar efeitos colaterais imprevisíveis.
Figura 2 - Diagrama de loop foreach
As demonstrações incorporados continuar a executar para cada elemento
a matriz ou coleção. Após a iteração foi concluída para todos
os elementos de recolha, o controlo é transferido para a próxima declaração
mento seguinte do bloco foreach.
int [] = new fibarray int [] {0, 1, 1, 2, 3, 5, 8, 13};
foreach (int elemento em fibarray)
{
. System Console .WriteLine (elemento);
}

page 25
Vahé Karamian
11
while
A declaração enquanto executa uma instrução ou um bloco de instruções
até que uma expressão especificada for avaliada como falsa. Uma vez que o teste do
enquanto que a expressão ocorre antes de cada execução do ciclo, um tempo
ciclo executa zero ou mais vezes.
do-while
A declaração do-while executa uma instrução ou um bloco de declaração
mentos repetidamente até que uma expressão especificada for avaliada como falsa. Ao contrário
o loop while, um loop do-while é executado uma vez antes da condição
expressão nal é avaliado.
Figura 3 - enquanto diagrama de circuito
Figura 4 - do-while diagrama de circuito
Cada linguagem de programação e ambiente irá fornecer alguma
uma espécie de mecanismo de loop. Em C #, temos quatro tipos que têm
foi discutida acima. Cada estrutura de laço é usado para a finalidade específica
tal como descrito. Os laços mais utilizados são o loop for, o fo-
chegar loop e a estrutura de loop while. O loop do-while é usado em
ocasiões especiais, onde você gostaria de executar o corpo do loop

page 26
Unity 3D - Jogo de Programação Intro
12
pelo menos uma vez antes de verificar a condição para determinar se
quero continuar a iteração ou seguir em frente com o ramo principal do código.
Por exemplo, a estrutura for loop deve ser usado quando você sabe
o tamanho dos elementos ou o número de vezes que você gostaria de ex-
ecute o bloco de código dentro do corpo do ciclo. O loop foreach
estrutura deve ser usado quando você quer iterar sobre um conjunto de coleta.
O tempo e as estruturas de loop do..while são normalmente utilizados quando
não sabemos quantas vezes precisamos para executar a estrutura do corpo
do circuito, mas, sabemos que a condição para a qual para sair do
loop.
for (int LoopCount = 0; LoopCount <10; LoopCount ++)
{
// Fazer alguma coisa aqui ...
}
enquanto (x <10)
{
// Fazer alguma coisa aqui ...
X ++;
}
Faz
{
// Fazer alguma coisa aqui ...
X ++;
} While (x <10);
Amostras de estrutura 5 de circuito código de bloco
Métodos
Um método de programação orientada a objeto é um as- procedimento
ciado a uma classe de objeto. Um objecto é composta de comportamento e de dados.
Os dados são representados como propriedades do objeto e comportamentos como metanfetamina
ods. Os métodos são também um objecto da interface para o exterior apresenta
mundo. Métodos também fornecem a interface que outras classes usar para ac-
cesso e modificar as propriedades de dados de um objeto. Isto é conhecido como
encapsulamento.
Um método é um bloco de código que contém uma série de instruções. UMA
programa faz com que as instruções a serem executadas chamando o método

page 27
Vahé Karamian
13
e especificar quaisquer argumentos de método necessários. Em C #, cada executada
instrução é realizada no contexto de um método.
Métodos são declarados em uma classe ou estrutura, especificando o acesso
nível, como, modificadores públicos ou privados opcionais, tais como abstrato ou
selada, o valor de retorno, o nome do método, e qualquer método pa-
tros. Todas estas partes são em conjunto o assinatura do método.
Parâmetros do método estão entre parênteses e são separados por
vírgula, parênteses vazios indicam que o método não requer PA-
tros. O que se segue é um exemplo de assinatura de um método:
[modificador de acesso]-tipo de retorno método-name ([tipo de parâmetro parâmetro de nome []])
{/ * Método de corpo * /}
Os elementos de sintaxe são como se segue:
 acesso modificador: determina o grau em que o seu
método é acessível por outras classes.
 retorno-type: o tipo de variável retornado pelo método (a
método também pode retornar um objeto de uma classe especificada). Seu
método deve retornar um valor usando a palavra-chave de retorno e
ele deve retornar um valor que corresponda ao tipo de retorno.
 método-name: o nome que você atribui ao seu método.
 parâmetro-type: o tipo de parâmetro passado para o seu
método (um método também pode aceitar objetos de um determinado
classe).
 parâmetro-name: o nome do parâmetro passado para o seu
Método.
 método de corpo: a afirmação de que executar o seu método de
tarefa.
// A função a seguir leva de dois dados de ponto flutuante
// Parâmetros, e retorna a soma das duas variáveis
// Como outro tipo de dados de vírgula flutuante
flutuador Add privada (float x, flutuador y)
{
voltar x + y;
}
Código Bloco 6-exemplo de um método

page 28
Unity 3D - Jogo de Programação Intro
14
Por padrão, quando um tipo de valor é passado para um método, uma cópia é
passou, em vez do próprio objeto. Portanto, as alterações ao argumento
não têm efeito sobre a cópia original no método de chamada. Você pode passar
um tipo de valor por referência usando a palavra-chave ref.
Ao passar por valores de referência, o método não recebe o ob-
Ject em si, mas um argumento que indica a localização do objecto em
memória. Se você alterar um membro do objeto usando essa referência,
a alteração é refletida no argumento do método de chamada, mesmo se
você passar o objeto por valor.
Aqui está um exemplo que demonstra passagem de parâmetros por referência:
// O parâmetro x é passado por referência.
// Alterações à x afetará o valor original de x.
SquareIt static void (ref int x)
{
X * = x;
System Console .WriteLine ( "O valor dentro do método: {0}", x).;
}
static void Main (string [] args)
{
int n = 5;
System Console .WriteLine ( "O valor antes de chamar o método.:
{0} ", N);
SquareIt (ref n); // Passando a variável por referência.
System Console .WriteLine ( "O valor depois de chamar o método: {0}".,
n);
. System Console .WriteLine ( "Prima qualquer tecla para sair.");
System Console .ReadKey (.);
}
Código Bloco 7 - parâmetro Método passar por referência
Os métodos podem retornar um valor para o chamador. Se o tipo de retorno não é
vazio, o método pode retornar o valor usando a palavra-chave de retorno. UMA
indicação com a palavra-chave de retorno, seguido por um valor que corresponda ao
tipo de retorno retornará esse valor para o chamador método. O teclado de retorno
palavra também pára a execução do método. Sem o retorno
palavra-chave, o método irá parar a execução, quando se atinge o final do
bloco de código.

page 29
Vahé Karamian
15
Para escrever um programa, usamos estes princípios simples e combiná
-los para resolver problemas complexos. Agora é claro que há mais do que isso
que reúne os olhos, mas os princípios são os mesmos. Há um monte de outras
conceitos e informações técnicas que não tenha sido apresentadas neste
seção. Isto porque, o autor espera que o leitor esteja familiarizado
com as noções básicas de programação e que ele ou ela tomou programação
cursos Ming e agora está pronto para aplicar essas habilidades ao jogo
programação.
Vamos dar uma olhada em um exemplo simples que irá demonstrar alguns
dos conceitos que acabamos de discutir. O programa a seguir é uma simples
calculadora que vai ser usado para executar algumas operações básicas tais como
adição, subtração, multiplicação e divisão:
flutuador Add private static (float x, flutuador y)
{
voltar x + y;
}
Subtrair flutuador private static (float x, flutuador y)
{
voltar x - y;
}
flutuador private static Multiply (float x, flutuador y)
{
voltar x * y;
}
flutuador estática privada? Divida (float x, flutuador y)
{
se (y> 0.0f)
voltar x / y;
outro
return null;
}
static void Main (string [] args)
{
flutuar R1 = Adicionar (2.0F, 2.0F);
flutuar r2 = Subtrair (R1, 2.0F);
flutuar R3 = Multiply (R2, R1);
flutuar R4 = Divide (8.0f, 0.0f);
if (R4 == null)
{
R4 = Divide (8.0f, 2.0F);
}

page 30
Unity 3D - Jogo de Programação Intro
16
String R = cadeia .format ( "R1 = {0}; R2 = {1}; R3 = {2}; R4 = {3}", R1, R2, R3,
R4);
. System Console .WriteLine (r);
}
Código Bloco 8-programa simples calculadora de demonstração
Neste ponto, você deve ter uma boa compreensão dos princípios básicos. Há sim
um monte de conteúdo aqui se você não tiver feito qualquer programação antes. Para
aqueles que tiveram exposição a alguma programação, este se destinava
como uma lembrança rápida, bem como proporcionar uma versão mais condensada
dos conceitos.
Agora que temos uma visão preliminar dos fundamentos, podemos
começar a discutir modernos conceitos de programação usando Object-Oriented
Programação.
Conceitos de programação orientada a objeto
Jogos sem programação não será muito divertido! Programação
é o que traz tudo para a vida em um jogo, portanto, é veryimportant
para aprender e compreender os conceitos de programação e como aplicar
-los para os jogos que você pretende projetar e desenvolver.
-Programação Orientada a Objetos (OOP) é, uma filosofia de design, um
modelo de programação onde os programas são organizados em torno de objetos e
de dados, ao invés de ação e lógica, tudo em OOP é agrupado como auto
sustentável. Programação Orientada a Objetos permite a decomposição de um
problema em um número de entidades chamadas objetos e, em seguida, constrói dados
e métodos em torno destes objectos.
O conceito de objectos de software surgiu da necessidade de modelar
objetos do mundo real em simulações de computador. Um objeto pode ser conside-
rado como uma representação de um item de física ou de uma ideia que pode executar
um conjunto de atividades relacionadas. O conjunto de atividades que o objeto executa
define o comportamento do objeto.
Por exemplo, em seu jogo você terá vários objetos que fazem
o seu jogo. Por exemplo, pense em como você pode representar um tanque

page 31
Vahé Karamian
17
em seu jogo. O tanque, o qual é uma espécie de um veículo, pode apresentar uma variável
ety de comportamentos, como mover do ponto A para o ponto B, carregamento e
un-carregar os reservatórios, o acompanhamento de um alvo, e tiro ao alvo. Deve
também manter informações sobre suas características (saúde, combustível, velocidade,
velocidade máxima, a capacidade de shell, e etc ...) para não mencionar a sua actual
estado (localização, velocidade de orientação, estoque e etc ...).
Para representar o tanque como um objeto, você iria programar a sua tamento
IORs como métodos e declarar variáveis para conter informações sobre a sua
características e estados. Durante o jogo, o objeto vai levar
os seus vários métodos, alterando as variáveis como necessário para reflectir a
efeito de suas ações. O conceito de um objeto é simples, mas poderosa.
Objetos fazem módulos de software ideais porque eles também podem ser definidos e
mantidas independentemente uma da outra, com cada objecto a formação de um
puro, universo auto-suficiente. Tudo o que um objeto sabe é capturado
em suas variáveis, e tudo o que ele pode fazer é expressa em seus métodos.
Classes e Objetos
Os blocos de construção básicos de programação orientada a objetos são o
classe eo objeto. Uma classe é o projeto de um objeto. Um objeto é
uma instância da definição de classe. Isso será muito mais clara à medida que dis-
xingar-lo e colocá-lo em prática ao longo do livro.
Nosso mundo está cheio de objetos. Meu carro é um objeto, minha bicicleta é um
objeto, minha casa é um objeto e meu avião é um objeto. Na verdade, qualquer
item tangível é um objeto. De igual modo, os objectos podem ser agrupados em conjunto
em uma classe. Meu carro podem ser agrupados em uma classe genérica de veículos, todos
que têm características e comportamentos semelhantes. Um objeto também pode
representam coisas mais abstratas - como formas geométricas, e ou trans-
ações.
A maneira mais fácil de demonstrar este conceito é com um ex- simples
amplo. Vamos considerar que gostaríamos para modelar um carro. Para que nós
Para conseguir isso, gostaríamos de criar uma classe chamada carro. Nossa classe carro
precisa armazenar algumas informações sobre o objeto do carro e alguns logia
ODS para representar o comportamento do objecto carro. O que se segue é um Visual
representação do nosso modelo de carro:

page 32
Unity 3D - Jogo de Programação Intro
18
Figura Objeto 5-Car
Agora, na realidade, as propriedades e funções de um carro moderno são
muito mais complexo. Mas por causa da manifestação que eu tenho guardado
as coisas simples. Continuando a nossa discussão, cada objeto carro terá
os pontos de dados definidos, e os métodos que serão designadas usadas para
o acesso e ou alterar o comportamento do objeto carro instanciado.
Você declarar uma classe usando a palavra-chave classe, que usam o acompanhamento
ing sintaxe simplificada:
[modificador de acesso] class class-name { / * corpo * / }
 acesso modificador : o grau em que sua classe é acessibili-
ble para o mundo exterior.
 class-name : o nome que você atribui a sua classe.
 classe de corpo : o corpo de vocês classe.
As aulas são normalmente declaradas usando o modificador de acesso público,
o que significa que a classe está disponível sem restrições. Você vai aprender
mais sobre o acesso modificadores posteriores. A sintaxe anterior foi sim-
plified de modo que você não está sobrecarregado com demasiada informação.
Aqui é um simples carro de classe:

page 33
Vahé Karamian
19
public class Car
{
private string make;
// Store fazer como tipo de cadeia
private string modelo;
// Modelo de loja como tipo de cadeia
private int ano;
// Ano loja como tipo int
private string de cor;
// Cor loja como tipo de cadeia
pública Car () { / * construtor * / }
public void start () { / * código para ligar o carro * / }
public void Stop () { / * código para parar o carro * / }
public void Acelerar () { / * código para a aceleração * / }
Cadeia pública GetMake () { return este .make; }
Cadeia pública getModel () { return este .model; }
public int GetYear () { return este .ano; }
Cadeia pública GetColor () { return este .Color; }
public void SetMake ( cadeia make) { este .make = fazer; }
public void setModel ( cadeia modelo) { este .model = modelo; }
public void setYear ( int ano) { este .ano = ano; }
public void SetColor ( string de cor) { este .Color = cor; }
}
Código Bloco 9 - Exemplo de classe carro
No carro de classe, temos declarado quatro campos: faça , modelo , ano
e cor . O ano de campo é do tipo int , eo resto são do tipo cadeia .
O modificador de acesso dos campos é definida como privada . Isto indica que
os campos são restritas, e que ninguém tem acesso direto a eles. Para
acessar esses campos, o usuário precisaria passar pelo getter e
Setter métodos, tais como o GetMake () método para recuperar o valor
do campo, ou para definir ou modificar o valor através do SetMake () método.
Como você já sabe, uma classe define um modelo para a criação de objetos.
Uma vez que você declarou uma classe, você pode criar objetos dessa classe.
A declaração a seguir cria um carro objeto:
Carro myCar = new Car ();
A primeira seção, declara uma referência a um carro de objeto, chamado meu-
Carro , e é usado para manter o local da memória real de um carro objecto.
A segunda seção, na verdade, cria um carro objeto no computador de

page 34
Unity 3D - Jogo de Programação Intro
20
memória. o novo
1
operador aloca a memória para o carro de objeto,
eo carro () método cria o objeto. A Car () método é conhecido como
um construtor . A localização de memória do recém-criado Car objeto é
atribuído a myCar e myCar é uma referência através do qual você pode
acessar o real Car objeto.
encapsulamento
dados e procedimentos relacionados com a embalagem em conjunto é chamado de encapsu-
lação. A chave para o objecto de encapsulação é o interface de mensagens. o
interface de mensagem serve para proporcionar uma barreira essencial entre o in-
estrutura terna do objeto e tudo o que está fora do objeto.
A interface de mensagem garante que todas as interações com o objeto tomar
colocar através de um sistema pré-definido de mensagens que o objeto é ga-
anteed para compreender e tratar corretamente.
O encapsulamento é essencial para a criação sustentável Object-ori-
Programas mas orientados. Quando a interação com um objeto usa apenas o
interface disponível publicamente de métodos e propriedades, a classe do
objeto se torna uma unidade corretamente isolado. Esta unidade pode então ser substituído
de forma independente para corrigir erros, mudar comportamentos internos ou para melhorar
funcionalidade ou desempenho.
Em nossa analogia do carro, o motorista de um carro realmente não precisa saber
a mecânica complexa que vão para ligar o carro e tornando-
acelerar ou desacelerar, tudo que eles precisam é saber o que botões apertar
para ligar o carro, parar o carro, e fazer o movimento do carro. Os detalhes são
escondido! A complexidade é escondido! Portanto, podemos facilmente atualizar
os sistemas internos do carro sem mudar a forma como os motoristas de carro
seus carros!
Propriedades permitem definir e obter campos usando métodos. devidamente,
laços são uma grande característica do C #, porque eles permitem que você esconda seus campos
de seus usuários de classe, tornando-os privado , enquanto continua a fornecer
1
O novo operador eo construtor são usadas para criar um objeto. Você acessar um objeto
através de uma referência de objeto, que detém a localização do objeto real na memória.

page 35
Vahé Karamian
21
-lhes uma maneira fácil de chegar a esses campos. A propriedade é um invólucro em torno
um campo privado, através do qual o campo é acessado.
A propriedade pode definir dois métodos, chamado get e set . o get
método retornar o valor do campo, e o método conjunto define o valor
do campo. Aqui é a classe de carro com propriedades:
class Car
{
private string make;
// Store fazer como tipo de cadeia
private string modelo;
// Modelo de loja como tipo de cadeia
private int ano;
// Ano loja como tipo int
private string de cor;
// Cor loja como tipo de cadeia
Cadeia pública Marca
{
obter { return este .make; }
set { este .make = valor ; }
}
Cadeia pública Modelo
{
obter { return este .model; }
set { este .model = valor ; }
}
public int Ano
{
obter { return este .ano; }
set { este .ano = valor ; }
}
Cadeia pública Cor
{
obter { return este .Color; }
set { este .Color = valor ; }
}
pública Car () { / * construtor * / }
public void start () { / * código para ligar o carro * / }
public void Stop () { / * código para parar o carro * / }
public void Acelerar () { / * código para a aceleração * / }
}
Código Bloco 10 - classe Car usando propriedades
SimplyPut, propriedades tornam o acesso campos de dados em C # muito mais
elegante. Em uma nota final, tanto o conjunto e obter as funções da propriedade
pode ter lógica complexa antes de definir ou obter os dados.

page 36
Unity 3D - Jogo de Programação Intro
22
passagem de mensagens
Mensagens, também conhecidas como interfaces, descrever a comunicação
entre objetos usando suas interfaces acessíveis. interfaces de mensagens
oferecer dois tipos importantes de proteção. Em primeiro lugar, eles protegem um objeto de
componentes internos de serem corrompidos por outros objetos. Se outro ob-
jectos tinha acesso direto a variáveis de um objeto e métodos internos,
eventualmente, um desses outros objetos iria lidar com uma in- variável
tamente ou chamar o método errado e danificar o objeto. Um objeto
protege-se contra esse tipo de erro, ocultando suas variáveis e interna
métodos por trás de sua interface de mensagem.
O segundo e menos óbvio tipo de proteção trabalha no oposto
direção local, ocultando sua variável e métodos internos, um objeto
protege outros objectos de acordo com a sua estrutura interna. por exem-
amplo eles são poupados ter de manter o controle do nome de cada variável, a
tipo de informação que contém, a quantidade de espaço que ocupa no armazenamento
idade, e uma série de outros detalhes que iria complicar todo o seu
procedimentos de acesso e as variáveis do objeto. Com o encapsulamento, um
objeto só precisa saber como pedir outro objeto para obter informações.
Todos os detalhes sobre a forma como a informação é armazenada estão bem escondido fora
de visão por trás da interface mensagem.
Há três maneiras de passar mensagens em C #: métodos , propriedades
e eventos . A propriedade pode ser definido em uma classe para permitir que objetos dessa
escreva para anunciar e permitir a alteração de informações de estado, tais como
PartidaNoMotor propriedade. Os métodos podem ser fornecidos para que outros objectos
pode solicitar um processo a ser realizada por um objeto, como acelerômetros
comeu () método. Os eventos podem ser definidos de um objecto poder aumentar em resposta
a uma ação interna. Outros objetos podem inscrever-se a estes para que eles
pode reagir a um evento ocorrido. Um exemplo poderia ser, por colisão
detecção no âmbito do motor Unity.
Abstração
A classe de carro descrito no nosso exemplo é um exemplo de abstracção
ção. Abstração é o processo de representar versões simplificadas de
Objetos do mundo real em suas classes e objeto. A classe carro não

page 37
Vahé Karamian
23
descrever todos os detalhes possíveis de um carro, apenas as partes relevantes para a
sistema que está sendo desenvolvido. software de modelagem em torno do mundo real
objectos pode reduzir consideravelmente o tempo necessário para compreender uma solução e
ser capaz de desenvolver e manter o código durante a vida útil do sis-
TEM.
Composição
Os objetos podem trabalhar juntos de muitas maneiras dentro de um sistema. Em alguns
situações, classes e objetos podem ser fortemente acoplados em conjunto para pro-
vide funcionalidade mais complexa. Isto é conhecido como composição.
objetos compostos são importantes porque eles podem representar muito
mais estruturas sofisticadas do que simples objetos pode. Por exemplo, uma
aeronave consiste de asas, motores e outros componentes que estão longe
demasiado complexo para ser representado como números ou strings simples.
Os objetos contidos em objetos compostos podem ser eles próprios
objetos compostos, e este assentamento pode ser realizado até ao infinito! o
principais componentes de uma aeronave, são objetos muito complexos por si
certo. Em qualquer modelo razoável de uma aeronave, cada um destes componentes
seria representada por um objecto de compósito que seria composta
objectos de ainda mais compostos, e assim por diante.
Figura 6-Avião Composite Objeto

page 38
Unity 3D - Jogo de Programação Intro
24
Uma vez que os objectos podem ser compostas por outros materiais, que podem represen-
enviou objetos do mundo real no nível naturalmente pensamos sobre eles. Até
, Uma estrutura profundamente aninhada complexa tal como uma aeronave pode ser tratada como
um único, objeto unificado. E desde que o objeto complexo pode ter seu próprio
comportamento, outros objetos podem usá-lo com muito pouca consciência de sua inter-
complexidade nal. Este é um bom exemplo de como a tecnologia objeto pode
trazer ordem para sistemas de larga escala.
No nosso exemplo do carro, as rodas, painéis, motor e etc ... pode ser
pensou em aulas individuais. Para criar a classe de carro, você vai precisar
para conectar todos esses objetos juntos. Isto faz com que seja possível aumentar
o complexityof definição seu carro ao longo dos anos e introduzir uma melhor
recursos e funcionalidades. O funcionamento interno de cada classe não são
importante devido ao encapsulamento como a comunicação entre o ob-
jectos ainda é através de passar mensagens para as suas interfaces públicas.
Herança
Herança é um conceito de programação orientada a objeto interessante.
Ele permite que uma classe para ser baseada em outra, a super-classe, e herdar
toda a sua funcionalidade automaticamente. código adicional pode então ser escritos
dez para criar uma versão mais especializada da classe. Se quiséssemos
melhorar nosso modelo e design, que iria criar uma nova classe chamada
Veículo. Esta nova classe será o super-classe, ea classe carro
herdar a classe de veículo.
Hereditariedade não está limitado a um único nível, mas disporá descendentemente em cascata
qualquer número de níveis em uma hierarquia de classes. Isso faz com que a herança de um muito
mecanismo poderoso porque as classes podem ser dotado de ricos conjuntos de
capacidades simplesmente colocando-os no ramo correta de um hi-classe
erarchy. Eles vão puxar automaticamente junto toda a interface e
definições de implementação das classes acima deles na hierarquia,
definindo por si só os recursos adicionais que os tornam
única.

page 39
Vahé Karamian
25
A Figura 7-Herança Exemplo
Considere o seguinte, um sistema que representa vários tipos de
veículos. Este sistema irá conter um veículo classe genérica, com sub-
classes para todos os tipos especializados. A classe de veículo irá conter o
métodos e variáveis que são relevantes para todos os veículos. As subclasses,
por sua vez, irá conter quaisquer métodos e variáveis adicionais que eram
específico para os casos mais especializados. Isso nos ajuda a adicionar facilmente outros
tipos de veículos para a hierarquia, tais como motocicletas, helicópteros,
Barcos e etc ...
Polimorfismo
O polimorfismo é a capacidade de um objeto para alterar o seu comportamento
de acordo com a forma como ele está sendo usado. Onde a classe de um objeto herda
um super-classe ou implementa uma ou mais interfaces, que podem ser referidos
para por esses nomes de classe ou de interface. Então, se temos um método que ex-
pectos um objeto do tipo «veículo», a ser passado como um parâmetro, podemos
passar qualquer veículo, carro, moto ou avião para esse método mesmo
embora o tipo de dados pode ser tecnicamente diferentes.
Modularidade
Além dos conceitos descritos até agora, orientadas opor-pro-
gramação também permite maior modularidade. aulas individuais ou em
grupos de ramos pode ser pensado como um módulo de código que pode ser re-
usado em projeto manysoftware. Isto reduz a necessidade de re-desenvolver sim-
funcionalidade Ilar e, portanto, pode reduzir o tempo de desenvolvimento e custos.

página 40
Unity 3D - Jogo de Programação Intro
26
Esta foi uma visão geral dos conceitos presentes na object-
paradigma de programação orientada. Nós não será capaz de cobrir todos os pecado
aspecto gle do tema neste capítulo, mas eu dei uma visão justa
do tema e para aqueles que estão vindo de uma ciência da computação
fundo, que deveria ser uma revisão rápida. Se esta é a primeira vez que
ter visto ou ouvido a terminologia, então espero que você faz compreender o
ideias. Como eu estou tentando mantê-lo o mais simples possível.
Generics
Genéricos permitem definir estruturas de dados de tipo seguro, sem
comprometendo-se a tipos de dados reais. Isto resulta numa significativa penho
boost mance e código de maior qualidade, porque você começa a reutilizar os dados
algoritmos de processamento sem duplicação de código específicas do tipo.
Genéricos permitem reutilizar o código eo esforço que colocou em imple-
-as. Os tipos e dados internos pode mudar sem causar código
inchaço, independentemente de você estiver usando tipos de valor ou de referência.
Você pode desenvolver, testar e implementar o seu código uma vez, reutilizá-lo com qualquer
Tipo, incluindo tipos de futuros, todos com suporte de compilador e tipo de segurança.
A melhor maneira de compreendê-los é, provavelmente, com um exemplo simples.
O seguinte é uma implementação de um com- Estrutura de Dados Stack
Generics Out:
classe pública MyStack
{
private int index;
private ArrayList pilha;
pública MyStack ()
{
este .STACK = new ArrayList ();
index = -1;
}
int pública COUNT
{
obter { return este .stack.Count; }
}
public void push ( objeto de dados)
{

page 41
Vahé Karamian
27
este .stack.Add (dados);
este .index ++;
}
objeto público pop ()
{
objeto o = este .STACK [índice];
este .stack.RemoveAt (index);
este .index--;
devolver o;
}
public void clear ()
{
este .stack.Clear ();
este .index = -1;
}
objeto pública espiada ()
{
devolver este .STACK [ este .index];
}
}
Código Bloco 11 - Estrutura de Dados MyStack
A próxima execução está usando Generics:
classe pública MyStack1 <T>
{
private int index;
private Lista < T > pilha;
pública MyStack1 ()
{
este .STACK = nova Lista < T > ();
index = -1;
}
int pública COUNT
{
obter { return este .stack.Count; }
}
public void push ( T de dados)
{
este .stack.Add (dados);
este .index ++;
}
pública T pop ()
{
T o = este .STACK [índice];

page 42
Unity 3D - Jogo de Programação Intro
28
este .stack.RemoveAt (index);
este .index--;
devolver o;
}
public void clear ()
{
este .stack.Clear ();
este .index = -1;
}
objeto pública espiada ()
{
devolver este .STACK [ este .index];
}
}
Código Bloco 12 - Código de exemplo Generics
A vantagem deste modelo de programação é que o al- interna
gorithms e manipulação de dados permanecem os mesmos, enquanto os dados reais
tipo pode mudar de acordo com a forma como o código está sendo usado.
Interfaces
Uma interface é um contrato. Quando você está criando uma interface,
você está dizendo: "Se você deseja fornecer essa capacidade, você deve implementar
mento destes métodos, fornecem estas propriedades e indexadores, e apoio
esses eventos. "O implementador da interface concorda com o contrato
e aplique os elementos necessários. Nós não terá muito para o
detalhes da definição, mas aqui estão alguns conceitos que você deve empresas
ficar de pé:
A Interface:
Este é o contrato. Por convenção, os nomes de interface começam com um
Capital I , então sua interface pode ter um nome como IWeapon . o
IWeapon de interface pode exigir, entre outras coisas, um explode ()
função. Isto indica que qualquer classe que quer implementar IExplosion
muito implementar um explode () função, mas não especifica como isso
método funciona internamente. Isso é até você o designer.

page 43
Vahé Karamian
29
A classe de implementação:
Esta é a classe que está de acordo com o contrato descrito na inter-
cara. Por exemplo, uma bomba pode ser uma classe que implementa IWeapon
e, portanto, implementa a explodir () função dentro da classe com base em
o da bomba requisitos.
A classe Cliente:
O cliente chama funções na classe de implementação. Por exemplo,
você pode ter um Battleship classe que pode ter uma variedade de IWeapon
objectos. O cliente pode esperar para ser capaz de chamar explode () em cada ob-
jeto, e embora cada objeto individual pode implementar o método
de forma diferente, cada um vai fazê-lo de forma adequada e sem reclamar!
Você pode perguntar, qual é a diferença entre Abstract Base de Clas-
ses e uma interface? A principal diferença é que uma classe base abstrata
serve como a classe base para uma família de classes derivadas, e uma interface
é para ser misturada com outras cadeias de herança. Isto é, uma classe
pode herdar de uma única classe pai, mas pode implementar multi-
interfaces de EPP.
Além disso, quando você derivar de uma classe abstrata, você deve sobre-
montar todos os métodos abstratos na classe base abstrata, mas você não faz
tem que substituir quaisquer funções não-abstrato. Você pode simplesmente usar o
implementação que a classe base fornece. Isto é chamado Im- Parcial
plementação . Interfaces não têm qualquer aplicação, então você deve
implementar cada função definida na interface. Você não pode parcialmente
implementar uma interface.
Os delegados
Na programação, que são muitas vezes confrontados com situações onde você
precisa executar uma ação específica, mas você não sabe com antecedência
qual método, ou mesmo qual objeto, você vai querer recorrer para executar
isto. Por exemplo, você pode querer dizer um objeto para reproduzir um ficheiro multimédia
durante a execução, mas você não pode saber o objeto estará jogando o
arquivo, ou se é um vídeo, um arquivo de som, uma animação, ou algo
outro. Em vez de codificar um objeto de mídia jogador em particular, você
criaria um delegado, e depois resolver esse delegado a um determinado
método quando o programa é executado.

page 44
Unity 3D - Jogo de Programação Intro
30
Um delegado é um tipo de referência, como os outros tipos de referência que você
visto neste livro, mas em vez de se referir a um objeto, um delegado se refere
a um método. Isto é chamado de encapsular o método. Quando você cria
o delegado, você especificar uma assinatura de método e tipo de retorno; você pode
encapsular qualquer método de correspondência com esse delegado.
Por exemplo, suponha que você tenha uma classe chamada MediaStorage que
você usa para armazenar e gerenciar vários arquivos de mídia arquivos-de áudio, vídeo,
arquivos de animação; o tipo de arquivo não importa para a classe. Suponha fur-
ther que você quer esta classe para ser capaz de reproduzir os arquivos, para se certificar
eles podem ser reproduzidos com sucesso, e relatar se eles tocaram
corretamente ou não (como uma forma de testar se o arquivo é válido). o Me-
diaStorage classe não precisa saber como playThe arquivos; ele só precisa
para receber um código que indica se o arquivo reproduzido com sucesso ou não.
Você poderia cumprir este requisito com interfaces, embora possa
não valer a pena para você a definir uma interface totalmente nova e criar uma
instância dele quando você poderia usar um delegado em vez disso. Neste caso, vamos
estar testando apenas dois tipos de arquivos de mídia, por isso vamos usar delegados. Se lá
foram uma ampla gama de tipos de arquivos de mídia, você pode querer definir uma
interface apropriada.
Eventos
Os eventos são uma parte importante do modelo de programação de hoje. UMA
programa moderno apresenta a interface do usuário e espera para o usuário
tomar uma ação. O usuário pode assumir muitas ações diferentes, como
escolhendo entre opções de menu, apertar botões, atualizar campos de texto,
clicando ícones, e assim por diante. Cada ação faz com que um evento a ser levantada.
Um evento é o encapsulamento da ideia de que "alguma coisa acon-
teceu "para que o programa deve responder. Eventos e delegados são
conceitos intimamente ligados, porque a manipulação de eventos flexível requer que
a resposta para o evento ser despachado para o manipulador de eventos apropriado.
Um manipulador de eventos é tipicamente implementado em C # através de um delegado.
Qualquer objeto pode publicar um conjunto de eventos a que outras classes podem
se inscrever. Quando a classe publicação gera um evento, todos os assinantes são

page 45
Vahé Karamian
31
notificado. Com este mecanismo, o objeto pode dizer: "Eu tenho o acompanhamento
ing coisas para notificá-lo sobre a ", e outras classes pode querer assinar
-se, dizendo: "Sim, deixe-me saber quando isso acontece." Como exemplo,
fornece um manipulador de eventos para a detecção de colisão. Cada vez que um objecto
está colidindo com outro objeto, isso ainda é elevado.
Eventos em C # são implementados com os delegados. A classe de publicação
define um delegado. A classe de inscrição faz duas coisas: a primeira, cria-
ates um método que corresponde à assinatura do delegado, e segundo,
cria uma instância desse tipo delegado encapsular esse método.
Quando o evento é gerado, os métodos da classe de inscrição são invocados
através do delegado.
Aqui está um exemplo de um manipulador de eventos:
classe pública MyEventPublisher
{
evento público EventHandler eventHandler;
public void Publicar ()
{
EventHandler handler = eventHandler;
se (eventHandler! = NULL )
{
manipulador ( esta , EventArgs .Empty);
}
}
}
classe pública MyEventObserver
{
public void MyEventHandler ( objeto remetente, EventArgs args)
{
Console .WriteLine ( cadeia .format ( "Publicação: {0}" ,
remetente));
}
}
classe pública TestEventHandler
{
static void Main ( string de args [])
{
MyEventPublisher publisher = new MyEventPublisher ();

page 46
Unity 3D - Jogo de Programação Intro
32
MyEventObserver observador = new MyEventObserver ();
publisher.eventHandler + = observer.MyEventHandler;
publisher.Publish ();
}
}
Código Bloco 13 - Simples manipulador de eventos Exemplo
O exemplo acima é uma forma simplista de ilustrar evento manu-
dlers, mas não captar a estrutura necessária para a implementação.
Vamos dar uma olhada em outro exemplo. Supondo que o nosso carro de classe tem um
propriedade para combustível . Se o nível de combustível desce até um certo nível, gostaríamos
para levantar um evento que notifica o utilizador que está com pouco combustível.
O carro de classe irá publicar este evento, e a classe de usuário subscreverá
a este evento para atualizar a interface do usuário e ou realizar outras tarefas.
A seguinte listagem de código irá ilustrar o cenário:
Classe pública FuelLevelChangeEventArgs: EventArgs
{
public float fuelLevel { obter ; set interna ; }
objeto pública OldValue { obter ; set interna ; }
objeto pública NewValue { obter ; set interna ; }
públicas FuelLevelChangeEventArgs ( flutuar fuelLevel, objeto oldValue, ob-
jeto newValue)
{
este .FuelLevel = fuelLevel;
este .OldValue = oldValue;
este .NewValue = newValue;
}
}
public class Car
{
private string make;
// Store fazer como tipo de cadeia
private string modelo;
// Modelo de loja como tipo de cadeia
private int ano;
// Ano loja como tipo int
private string de cor;
// Cor loja como tipo de cadeia
Cadeia pública Marca
{
obter { return este .make; }
set { este .make = valor ; }
}
Cadeia pública Modelo
{
obter { return este .model; }

page 47
Vahé Karamian
33
set { este .model = valor ; }
}
public int Ano
{
obter { return este .ano; }
set { este .ano = valor ; }
}
Cadeia pública Cor
{
obter { return este .Color; }
set { este .Color = valor ; }
}
private float fuelLevel;
public float FUEL_LEVEL
{
obter { return este .fuelLevel; }
conjunto
{
objeto oldValue = este .fuelLevel;
este .fuelLevel = valor ;
// Nós queremos elevar o nível quando o combustível
// Queda de nível para um determinado ponto
Se ( este .fuelLevel <0.6f)
{
// Código aqui para aumentar o evento
FuelLevelChanged ( esta , novo FuelLevelChangeEven-
Targs ( este .fuelLevel, oldValue, valor ));
}
}
}
// delegado
delegado public void FuelLevelChangeHandler ( objeto remetente, FuelLevel-
ChangeEventArgs de dados);
// evento
evento público FuelLevelChangeHandler FuelLevelChanged;
protected void OnFuelLevelChanged ( objeto remetente, FuelLevelChangeEven-
Targs dados)
{
// Verificar para ver se há algum assinantes
se (FuelLevelChanged! = NULL )
{
// Chamar o evento
FuelLevelChanged ( esta , de dados);
}
}
pública Car () { este .fuelLevel = 1.0f; }

page 48
Unity 3D - Jogo de Programação Intro
34
public void start () { / * código para ligar o carro * / }
public void Stop () { / * código para parar o carro * / }
public void Acelerar () { / * código para a aceleração * / }
Cadeia pública GetMake () { return este .make; }
Cadeia pública getModel () { return este .model; }
public int GetYear () { return este .ano; }
Cadeia pública GetColor () { return este .Color; }
public void SetMake ( cadeia make) { este .make = fazer; }
public void setModel ( cadeia modelo) { este .model = modelo; }
public void setYear ( int ano) { este .ano = ano; }
public void SetColor ( string de cor) { este .Color = cor; }
}
Código Bloco 14 - Class carro com manipulador de eventos
O delegado encapsula qualquer método que leva os atributos de-
multados, este delegado deve ser implementada por todos os assinantes. o
FuelLevelChangeEventArgs classe foi criada para ajudar a controlar o velho
valor da propriedade eo novo valor da propriedade.
Neste ponto, você ter tido uma boa visão geral dos fundamentos
e também foram fornecidos com um bom pé com Orientada a Objetos
terminologia. é incentivada-se que o leitor faça sua própria investigação sobre
os tópicos discutidos neste capítulo.

page 49
Vahé Karamian
35
Capítulo 2 - Breve Introdução à Unidade IDE
Visão Geral da Interface
Antes de podermos começar com qualquer um dos aspectos legais de Unity, nós
seria necessário para obter-nos familiarizados com o ambiente. No momento
da escrita, Unity 5.3 foi o lançamento público mais recente. Por isso vamos
estar concentrando nossos esforços em Unity 5.3.
Figura 8-Unidade 5 Editor
Na Figura 8, você vai ver um projeto vazio Unidade 5. Se este for o
primeira vez que você estiver executando Unidade 5, o IDE pode apresentar uma ligeira dife-
configuração ent. Ou seja, a sua visão pode ser um pouco diferente, então
o que você vê na Figura 8. Eu gosto de configurar o meu IDE com o con- mostrado
figuração porque torna mais fácil para mim para executar as tarefas que
Estou mais interessado.
Observe também, que eu ter quebrado o IDE em cinco de trabalho principal
áreas ING. (1) Cena Janela, (2) Jogo Janela, (3) Inspector
Janela, (4) Hierarquia janela, e (5) a janela Project. Esses são
as principais áreas do IDE que você estará utilizando para os seus projectos.

página 50
Unity 3D - Jogo de Programação Intro
36
No momento, como você pode ver, o IDE é bastante desinteressante.
Isso porque não temos nada de interessante acontecendo no de-
signatário, é apenas uma tela em branco à espera de suas idéias criativas! Vamos
obter uma melhor compreensão do que cada uma dessas regiões será usado
em um nut-shell:
cena Vista
The Scene View é seu sandbox interativo. Você usará o
Cena View para selecionar e posicionar seus GameObjects. estes inclui
o jogador, a câmera, seus inimigos, e tudo o que será
usado para gerar o seu nível. Manobra e manipulação de objetos
dentro Scene View são algumas das funções mais importantes no
Unidade, por isso é importante para aprender a realizá-las de forma eficiente
caminho. À medida que avançamos ao longo dos exemplos, serão fornecidos mais dicas para im-
provar e aumentar a produtividade.
jogo Vista
O jogo de exibição é processado a partir da Câmara (s) no seu jogo. isto
é representante de seu jogo final, publicado. Você vai precisar usar
uma ou mais câmeras para controlar o que o jogador vê realmente quando eles
está jogando o seu jogo. Você também pode mudar rapidamente a proporção de aspecto
a janela do jogo de exibição para ver rapidamente como o jogo vai olhar para
diferentes resoluções e tamanhos de tela. Uma outra grande característica do
Jogo Vista da janela é que você pode realmente obter o Rendering estatís-
tiques que é uma grande utilidade para verificar o desempenho do seu jogo.
Estes dados podem então ser utilizados para optimizar o desempenho para ilustrações
cenas mais complexas.
o Inspector
A janela Inspetor exibe informações detalhadas sobre o seu
atualmente selecionado GameObject e todos os componentes ligados e
suas propriedades. Dentro da janela Inspector, você pode modificar o
funcionalidade do GameObjects em sua cena. Qualquer propriedade que é visualizado
jogado no Inspector pode ser diretamente modificado. Isto inclui roteiro
variável. Você também pode usar o Inspector para alterar as propriedades para ver o
resultado real durante a execução! O Inspector é outra parte da Unidade

page 51
Vahé Karamian
37
IDE que você precisa para obter-se muito familiarizado. Você será spend-
ing maioria de seu tempo na Scene View, a janela Inspector, e
seus scripts.
Janela hierarquia
A Hierarquia contém todos os GameObject na cena atual.
Alguns destes são exemplos diretos de arquivos de recursos, como modelos 3D e
outros são exemplos de Prefabs
2
. A Janela Hierarquia também irá descartar
jogar o relacionamento pai-filho de todos os GameObjects no
Janela hierarquia. É basicamente uma exibição ao vivo de todos os existentes
GameObject em sua cena.
Janela de projeto
A janela Projeto é onde seus ativos do projeto são exibidos.
Este é um relacionamento um-para-um para o sistema de arquivo real, onde o
arquivos de projeto estão sendo salvas em sua máquina local. tudo a partir de
Jogo Objectos, scripts, texturas, modelos, áudio, vídeo e etc ... Será
ser acessível e conseguiu nesta janela. O painel esquerdo da
navegador mostra a estrutura de pastas do projeto como uma lista hierárquica.
Acima da lista de estrutura de projeto é uma seção Favoritos onde você pode
manter os itens utilizados com frequência para facilitar o acesso. Você pode arrastar itens de
a lista de estrutura do projeto para os seus favoritos e também salvar consultas de pesquisa
há. Isso vai ser útil em grandes projetos com centenas ou milhares
de GameObjects.
Como você pode ver, Unidade tem feito um trabalho maravilhoso de criar um IDE
que é fácil de usar e de acesso de ambos os designers e desenvolvedores.
Há outros pontos de vista e janelas que oferecem mais recursos e
funções. É simplesmente impossível cobri-los todos em uma sessão. eu tenho
fornecido com o melhor lugar para começar, e cada leitor
deve realizar sua própria iniciativa e mergulhar mais fundo com base na sua
juros e profissão. Neste livro, são maioritariamente inclinado para o
lado a programação do design de jogos e desenvolvimento. Tenha em mente que
o IDE é muito poderoso e tem mais recursos que irá abranger mais tarde
no livro. Mas, por agora, vamos ficar com o básico.
2
objetos personalizados que são feitas pelo usuário.

page 52
Unity 3D - Jogo de Programação Intro
38
Criando Nosso primeiro objeto do jogo
Unity 3D não é um software de modelagem 3D, então não espere para criar
modelos sofisticados, utilizando Unity 3D. Unity 3D é um pri- Game Engine
Marily, que também lhe proporciona alguma flexibilidade sobre como modificar e
ou a criação de conteúdo 3D simples! Para sua modelagem 3D precisa, você vai
precisa trabalhar com um software como o 3D Studio Max, Maya, Rhino e
etc ... Generallyspeaking, seus modelos serão criados bya 3D Modeler
e Designer e você vai importá-los e usá-los dentro de seu jogo.
Por padrão, existem várias primitivas que podem ser criados a partir de
a Caixa. Estes são o Cubo primitiva, a Esfera primitivo, o Cap
sule primitivo, o cilindro primitivo, o primitivo Plane eo Quad
primitivo. Para o propósito desta demonstração que irá colocar um cubo
primitiva na cena.
NOTA: O processo de criar e modificar qualquer tipo primitivo
é o mesmo. Na verdade, a modificação, na medida em que a transformação é con-
causa é a mesma para cada Object Game.
Figura 9-Cube Primitive
A fim de criar um cubo primitivo, a partir do menu principal, selecione
GameObject-> 3D Objeto-> Cube. Esta acção irá resultar na colocação de um
cubo em sua cena ativa. Antes de prosseguir, vamos em frente

page 53
Vahé Karamian
39
e também salvar a nossa cena. Para salvar a cena, a partir do menu principal, selecione
Arquivo-> Salvar Cena ... Unity 3D irá pedir-lhe para guardar a sua cena em
a pasta do projeto na pasta Assets. Faça uma nova pasta chamada
cenas, e depois salvar sua cena dentro desta pasta e nomeá-la
CH1EX1.
O objetivo deste ficará claro mais tarde, quando começamos a entrar em
cenários mais complexos. Assim como qualquer outro projeto que você tem compreensão
intervindo anteriormente, você precisa ter algum tipo de estrutura e
organização, então porque não começar a fazê-lo desde o início?
Se você seguiu as instruções que você deve ter um semelhante
olhando IDE como na Figura 9 . Observe como o Editor de Unidade tem vindo a
vida agora.
1. Nós temos nosso cubo primitivo colocado na Cena janela.
2. A Hierarquia janela está exibindo todo o jogo Obser-
jectos presentes em nossa cena.
3. O Jogo janela está exibindo o cubo através dos olhos
da câmara.
4. O Inspector janela está exibindo todos os componentes
e as propriedades que estão ligados ao Game Cube Obser-
jeto.
5. O Projeto janela está exibindo todos os ativos que temos
no nosso projeto até agora, que no momento é apenas a cena
que temos guardado.
Tome um momento para estudar tudo o que você vê na tela. Veja-
ing na janela do Inspector, você pode ver que há um monte de
informação que está sendo exibido para o cubo selecionado.
Temos vários componentes ligados ao cubo primitivo pelos de-
falha. Estes são os Transform, filtro de rede, Box Collider, Malha
Renderizador e um material padrão ligado ao GameObject cubo.

page 54
Unity 3D - Jogo de Programação Intro
40
Figura 10 Inspector Janela
Tomar um olhar mais atento ao In-
janela de Spector na Figura 10, podemos
veja sete regiões diferentes.
Região 1 contêm as propriedades
para o nome do GameObject, o
Tag, ea camada. Vamos entrar em
os detalhes mais adiante.
Regiões de 2 a 6 são a dife-
ferentes componentes que tenham sido
ligado ao GameObject.
Transformar componentes
que armazena a posição, a rotação e
escala do GameObject.
O filtro de rede, definindo a
malha do cubo.
Os componentes da caixa Collider.
Este é utilizado para a detecção de colisão.
O componente de malha Prestados
detalhando como a malha deve ser Ren-
derada.
O componente padrão de materiais
que é o material usado para processar
nosso cubo.
Região 7 tem um Add Component
função que pode ser usado para adicionar mais
componentes para o GameObject
Tomando uma olhada nas informações Transform, vemos que o cubo
posição, a rotação e a escala são representados pela propriedade de transformar
que é composto por três objetos Vector3D. Neste caso, o cubo
GameObject é colocada na posição (0,0,0) representando o (x, y, z) denação
coorde- respectivamente. O vector de rotação do cubo é de (0,0,0) sobre o
(X, y, z) do eixo. E o vector escala também é definida para (1,1,1) sobre o (, y, x z) do eixo.

página 55
Vahé Karamian
41
Figura 11-Transform Tools
Para começar a fazer quaisquer alterações à propriedade transform do cubo
GameObject, precisamos estar familiarizado com as ferramentas de transformação localizadas em
a parte superior da unidade 3D IDE como mostrado na Figura 11:
1. Dá-lhe a capacidade de posicionar o objeto em seu x, y e z
eixo na cena.
2. Dá-lhe a capacidade para girar o objeto em seu x, y e z
eixo na cena.
3. Dá-lhe a capacidade de dimensionar o objeto em seu x, y e z
eixo na cena.
Quando você seleciona o cubo e escolher qualquer uma das ferramentas de transformação,
você terá os seguintes modificadores na janela de cena:
Figura 12-Posição
Figura 13 Rotação
Figura 14 Escala
Usando essas ferramentas, você pode transformar o GameObject selecionado na
qualquer forma que irá satisfazer suas necessidades. A melhor maneira de começar uma sensação
para
-los é tentar-los. Outra maneira de modificar o GameObject de
propriedades de transformação, é introduzindo directamente os valores para cada nu- parte
merically através da janela do Inspector. Eu geralmente acham mais fácil
fazer o posicionamento, rotação e escala de meus GameObjects através
a vista da cena, e depois afinar-los através da entrada numérica
campos na janela Inspector.

página 56
Unity 3D - Jogo de Programação Intro
42
Os componentes próximos representando o filtro de malha e malha Ren-
derer será discutido mais tarde nos capítulos. A única coisa que você deve
estar ciente de que estes componentes são a representação real de
o wireframe ea forma como o GameObject vai ser processado no
cena. Também vamos discutir o componente Collider em capítulos posteriores
quando estamos construindo nossas demos de jogos. Por enquanto você só deve ser
ciente de que aceleradores são usados para qualquer detecção de colisão, e eles são
muito importante para entender e configurar corretamente. Especialmente em
modelos mais complexos.
O componente de material é usado para definir o tipo de material que
vai ser aplicada ao GameObject seleccionado. Os materiais são utilizados em con-
junção com malha de processadores, sistemas de partículas e outros renderização
componentes. Eles desempenham um papel essencial na definição de como o objeto é
exibida. As propriedades que um material do inspector da janela apresenta
são determinados pela Shader que usa o material. Um shader é um espe-
tipo cializados de programa gráfico que determina a textura e
informações de iluminação são combinados para gerar os pixels do rendeu
objeto na tela. Nós não estaremos cobrindo shaders neste livro, pois não é
nosso tema principal e há muito mais adequado livros para discutir e
cobrir o tema.
Figura 15-New Material nomes CH1EX1MAT

page 57
Vahé Karamian
43
Por padrão, cada primitiva que você criar terão a ma- cinza
terial definido pela Unidade atribuído a ele. Você pode facilmente criar um novo
materiais, selecionando Assets-> Create-> material a partir do menu principal,
isso vai colocar um novo objeto material na pasta selecionada. Alternativamente,
você também pode criar um material clicando com o botão direito na janela Project
e selecionando Create-> Matéria. Em ambos os casos, você deve se certificar
você está na pasta correta antes de executar essas operações.
Vamos criar uma nova pasta chamada materiais Sob os bens e
vamos criar um material chamado CH1EX1MAT clicando com o botão direito sobre o
pasta de material e selecionando criar material. Dê uma olhada na Figura 15
se você tiver feito tudo corretamente, você deve estar vendo re- semelhante
sultados.
Como você pode ver, há um monte de propriedades associada ao
materiais como mostrado na janela Inspetor. Por agora, gostaríamos
para mudar apenas a Albedo propriedade para ser de cor verde, para fazer isso, selecione
o selector de cor na janela Inspetor para a propriedade Albedo e
selecione a cor verde. Você pode selecionar a cor verde movendo
o mouse na janela do seletor de cores ou digite o numérico real
valores no campo RGB. Pus o meu valor para a seguinte: R = 0;
G = 255; B = 0, e Alpha a 255 bem. Para aplicar o recém-criado
material a nosso cubo, basta arrastar e soltá-lo para o cubo GameOb-
jeto dentro de nossa cena. Agora vá em frente e selecione o cubo GameObject
e você vai notar as mudanças, como mostrado na Figura 16.

page 58
Unity 3D - Jogo de Programação Intro
44
Figura 16 Aplicando o material CH1EX1MAT ao cubo GameObject
Como mencionado anteriormente, este livro é mais concentrado na pro-
gramação parte do desenvolvimento do jogo. Por isso não vamos aprofundar demais
tanto em gráficos tópico relacionado da perspectiva de um designer.
Então, nós olhamos o aspecto mais básico de qualquer GameObject de
propriedades. Vamos em frente e criar alguns dos outros tipos primitivos
para obter uma sensação de-los e também praticar um pouco do design trans- tempo
formação dos GameObjects. Antes de seguir em frente com que excersise,
há um mais importante recurso de tempo de design que gostaria de
chamar a sua atenção.
Um item mais importante em relação a janela a cena é a capacidade
a olhar para o projeto de design cena ou nível de diferentes pontos de vista.
A fim de conseguir isso, você precisará ter o mouse na cena
janela e mantendo a tecla Alt
3
para baixo, na janela de cena que você
vai notar que o ícone do mouse mudou para o ícone do olho, agora
você pode clicar em e mova o mouse para mudar o ponto de vista no de-
assinar tempo na janela de cena. Isso irá ajudá-lo a rodar dentro do
cena. Para zoom in e out você pode usar o botão do meio do mouse. Se vocês
ter usado outras ferramentas de modelagem 3D, a função funciona de forma semelhante.
3
Para usuários de Mac, você precisará usar a tecla de comando.

página 59
Vahé Karamian
45
Vá em frente e aumentar um pouco fora da vista de cena para que você possa ver um
área maior para brincar. Em seguida vá em frente e criar outro cubo
GameObject. Por defeito, cada GameObject será colocado na origem
(0,0,0). Vamos fazer algumas modificações para a transformação do recém
criado cubo. Observe também que o novo GameObject Cube é nomeado Cube
(1), para que você mude o nome do recém-criado GameOb-
jeto, selecione-o e a partir da janela Inspector mudar o nome do objeto para
CUBE2 . Você também pode renomear um GameObject da Hierarquia-ganha
dow selecionando-o e clicando em uma vez ou pressionar a tecla F2. este
funciona de forma semelhante ao seu sistema de arquivos.
Vamos em frente e utilizar as ferramentas de transformação para mover CUBE2 para posicionar
ção (2,0,0) e, em seguida, escala-lo para que ele seja metade do seu tamanho original. Você
pode fazê-lo seleccionando a seta vermelha que representa o eixo x, consulte
Figura 12, para arrastá-lo na direção positiva ou negativa. Você vai No-
Tice que objetos em movimento para locais específicos não vai ser tão fácil
com a ferramenta de transformação, se você precisa para chegar a posições muito específicas tais
como (2.33,0,0). Para este tipo de coordenadas, será melhor usar o
Inspector Janela e directamente entrada coordena a posição.
Agora vamos expandir nossa GameObject a metade do seu tamanho. Selecione a escala
ferramenta e utilizar os indicadores, referem-se a Figura 14, para obter o tamanho da
objeto até metade do seu tamanho. Note que você terá que fazer isso em todos 3-
eixo respectivamente. Como você pode ver, dimensionar o objeto a exatamente 0,5 em
todos os três eixos é difícil! Tornar a vida fácil e usar a janela Inspetor
para entrar nos valores numéricos para o vetor de escala para ser (0.5,0.5,0.5).
Uma última transformação e vamos ser bom com este exercício.
Vamos em frente e gire CUBE2 por 33 graus no eixo xyz. selecionar
a ferramenta de rotação e usar os indicadores, referem-se a Figura 13, para rodar a
objeto. Se você seguiu os passos sua tela deve se parecer com Fi-
ure 17.

página 60
Unity 3D - Jogo de Programação Intro
46
Figura 17-CUBE2 posição, rotação, escala
Há mais um ponto de vista que é veryimportant estar familiarizado com,
e que é a janela do console. Vamos olhar para a janela da consola
em mais detalhes quando começamos a fazer a nossa programação. Isso é importante
para fins de depuração, ele irá mostrar erros, avisos e outros sagem
sábios gerados pela unidade.
Neste ponto, você deve ter uma compreensão justa do re- principal
regiões no Editor de Unidade, e seu propósito. Você também deve ter um
boa compreensão de como fazer suas transformações de objetos em tempo de design.
Vamos olhar para transformação do objeto em tempo de execução em capítulo posterior.
Digite de programação C # e Unity 3D
Ao projetar um jogo ou uma simulação, você precisa ser capaz
para manipular o seu ambiente não apenas através do designer, mas também
em tempo de execução, de forma dinâmica. Este é o lugar onde você vai ter que começar a aplicar
seus conhecimentos e habilidades de programação para dar vida ao ambiente
mento. De modo que não está ocioso. Felizmente ou infelizmente, não há
não há maneira de contornar isso!
Então, para começar, vamos olhar para as noções básicas de manipulação
dos objetos por meio de código. Digamos que pretende rodar nosso cubo em seu

página 61
Vahé Karamian
47
Y-Axis quando criar ou executar nossa aplicação. Há várias etapas
você terá de tomar:
1. Você precisará criar um script C #
2. No script C # você precisará escrever o código que será
aplicar a rotação para o objecto
3. Finalmente, você precisará associar o script com o de-
Objeto do jogo desejado
Neste ponto, eu não vou discutir a estrutura e organização
ção do seu projeto e sistema de arquivos para o seu projeto. Discutiremos
isso nos próximos capítulos à medida que começar a construir o nosso conhecimento ao longo
o livro.
Para que você para criar um script C # no seu projeto, dentro do
Janela de Projeto, clique direito para obter o seu menu de contexto, selecione Cre
ate-> C # Script. Esta ação criará um arquivo de script C # no especificada
localização, e irá pedir-lhe para o nomear. Neste ponto, o nome que você dá
o script não é um grande negócio, mas como sempre você deve considerar a utilização de
melhores práticas para a convenção de nomenclatura, tal como definido dentro de sua organização
ção ou a si mesmo. Em qualquer caso, eu chamo meus cubeRotate.cs script. Duplo
clique no script para abri-lo no Editor de Mono (editor padrão), você pode
alterá-lo para qualquer outro editor de C # de sua escolha. O código deve
algo parecido com isto:
usando UnityEngine;
usando System.Collections;
classe pública articleRotate : MonoBehaviour {
// Use isso para inicialização
vazio Iniciar () {
}
// Update é chamado uma vez por quadro
vazio Update () {
este .transform.Rotate ( novo Vector3 (0, 1, 0), 1);
}
}

página 62
Unity 3D - Jogo de Programação Intro
48
Algumas coisas a explicar, antes de seguir em frente. Cada script que
você cria vontade de herdar padrão de MonoBehaviour . Vamos dis-
xingar essa classe em um momento posterior. Cada script que você cria também terá
duas funções definidas como: Iniciar () e Update () .
O Start () função será executado apenas uma vez no início do pro-
grama. Assim, qualquer lógica e dados initializations que você precisa ou quer fazer
pode ser colocada na função Iniciar ().
O Update () função é onde a maioria da magia acontece. este
é a função que é chamada continuamente ao longo da vida do seu
jogo ou simulação. Esta é a função onde você vai atualizar o seu
objetos do jogo. Em suma, é a função que será chamado cada quadro
antes de renderizar a cena.
A linha esta .transform.Rotate ( novo Vector3 (0, 1, 0), 1); vai per-
formar a rotação desejada estamos procurando em um determinado objeto é
aplicado a. Sem entrar muito em detalhes e por trás do
cena complicação dessa função. Podemos utilizar a função Rodar
definido no componente transformada de nosso objeto para passar em um Vector3
objeto, o que representa a nossa (X, Y, Z), e o ângulo de rotação.
Uma vez que estamos planejando para girar sobre o eixo Y, temos que definir
nossa Vector3 como (0,1,0). A função irá fazer todo o transporte necessário
formações e lidar com a computação para você. O próximo parâmetro é
o ângulo de rotação, o que temos definido como 1.
Existem várias maneiras de aplicar um script para um jogo de objeto. o
maneira mais simples seria a de arrastar e soltar o seu roteiro para o desejado
jogo de objetos em cena. Depois de ter aplicado o script, na In-
Spector Windows, você vai ver que o script é um componente do
cubo.

página 63
Vahé Karamian
49
Figura 18-Script Anexado ao jogo de objetos
Quando você aplicar este código ao seu Cube e executar o seu programa, você
notará que o seu Cube está agora girando em seu eixo Y, um grau
continuamente. Isso é porque nossa lógica de rotação está no Update () função
ção, que é chamado continuouslybythe motor de jogo enquanto o programa
está correndo. E cada vez, a rotação de um grau é aplicada ao
Cubo de transformar componente! Daí você obter o efeito de rotação.
Publishing Construir e configurações do leitor
Quando estiver satisfeito com a sua criação jogo, você vai querer
realmente construí-lo para ver como ele se sente e parece na plataforma pretendida.
Uma das principais atrações e benefícios da Unidade é que você pode alvejar
um monte de plataforma diferente com praticamente a mesma base de código. Sim,
haverá algumas pequenas alterações de uma plataforma para o próximo, este é
esperado devido aos fatores de forma diferentes entre os diferentes plataforma
formas. A implantação PC é muito diferente, em seguida, uma implantação Web, em seguida,
uma implantação Mobile. arquitetura diferente, uma quantidade diferente de re-
fontes e diferentes resoluções e tipos de entrada! Por agora você pode apenas
dê uma olhada nas opções de implantação disponíveis para você, selecionando Arquivo-
> Construir configurações ... Você terá diferentes opções com base na sua li-
incenso.

página 64

página 65
Vahé Karamian
51
Capítulo 3 - objetos do jogo e Componentes
O que é um GameObject?
GameObjects são o conceito mais importante na Unidade. É muito
importante entender o que é um GameObject é. Cada objeto em seu
jogo é um GameObject. Pense em um GameObject como um recipiente vazio
que pode conter diferentes componentes
4
. Estes componentes são então utilizados
para implementar a funcionalidade do GameObject. Dependendo de quais
tipo de objeto que você deseja criar, você irá adicionar diferentes combinações
de componentes para o GameObject.
No Capítulo 2 - Breve Introdução à Unidade IDE, se você se lembra de
a janela Inspector , quando criou o primitivo Cube GameOb-
jeto, todos os pré-definidos componentes que compõem o que nós vemos como o
Cube em nossos Ver Cena . Como um lembrete, tivemos a seguinte Compo-
nentes ligados ao GameObject Cube:
1. Nome
2. Tag
3. Camada
4. Transform
5. filtro de rede
6. Box Collider
7. malha Renderer
8. material
Cada GameObject terá os 3 primeiros atributos e da Trans-
formulário Componentes ligado a ele. Isto é obrigatório. a Transform
Componente é um dos componentes mais importantes. Ele define o
posição, rotação e escala de GameObject no mundo do jogo.
Uma nota importante sobre a propriedade Tag. Você vai definir um Tag
palavra para ligar, ou mais precisamente identificar, um ou mais GameObjects. Para
4
Os componentes são as porcas e parafusos de objetos e comportamentos em um jogo. Eles são os
peças funcionais de cada GameObject.

página 66
Unity 3D - Jogo de Programação Intro
52
exemplo, você vai ter um Tag definido que será associado com você
personagem do jogador, você vai ter um Tag definido que será associado
com os seus inimigos e assim por diante. É uma outra maneira de identificar e consulta
GameObjects em sua cena durante a execução.
É importante tirar desta seção que um GameObject é
um recipiente para componentes, que em troca definir o que GameOb-
jeto será semelhante e como ele irá se comportar. Saltar um pouco à frente,
até mesmo os programas que escrevemos estão ligados como componentes para a
GameObject para dar-lhe as funções e recursos avançados.
Adicionando e componentes de edição
Você pode adicionar componentes ao GameObject selecionados através do
Menu de componentes ou a adicionar o componente botão no Inspetor Win-
dow . Há um monte de componentes pré-definidos fora da caixa
já que vêm com o Unity. Nós não será capaz de entrar em todo o
componentes, mas vamos dar uma olhada em alguns dos mais utilizados e
vai deixar o leitor fazer a sua própria investigação.
Você pode anexar qualquer número ou combinação de componentes para um
GameObject única. Alguns componentes funcionam melhor em combinação com
outras. Por exemplo, o corpo rígido funciona com qualquer LHC . o
Corpo rígido controlar a transformar através da física NVIDIA PhysX
motor, e o LHC permite que o corpo rígido de colidir e interagir
com outros Colliders. Consulte a documentação da unidade para saber mais
sobre cada tipo diferente de componente que está disponível fora da caixa.
Um dos grandes aspectos dos componentes é a flexibilidade. Quando você
anexar um componente a um GameObject, existem diferentes propriedades
O componente que pode ser ajustado no editor enquanto concepção de um
jogo, ou por scripts durante a execução do jogo. Existem dois tipos principais
de Propriedades:
 Valores - propriedades de valor pode ser ajustado através do de-
signatário ou em tempo de execução. Eles podem ser de qualquer tipo de dados.
 Referências - propriedades de referência são como ponteiros para outras
GameObjects, áudio, scripts, materiais, pré-fabricados, e etc ...

página 67
Vahé Karamian
53
Figura 19 - Tipos de propriedade, referência e valor
Os componentes podem incluir referências a qualquer outro tipo de Compo-
nentes, GameObjects, ou bens. Na Figura 19, você pode ver um exemplo de
ambos tipos de referência de propriedade e tipos de propriedade valor.
Scripts como componentes
Quando você cria um script e anexá-lo a um GameObject, o script
aparece em Inspector Janela do GameObject como um componente. este
é porque os scripts tornam-se componentes quando eles são salvos. em logia
termos téc-, um script compila como um tipo de componente, e é tratada
como qualquer outro componente do motor Unity.

página 68
Unity 3D - Jogo de Programação Intro
54
Basicamente um script é um componente que você mesmo cria. Tu es
o autor define os membros para ser exposto ao inspector, eo
componente / script irá executar a funcionalidade projetada.
Em outras palavras, cada um de seus scripts é uma classe única, e como
discutido em Conceitos de programação orientada a objetos, a sua defi- classe
definição vai ditar como seu componente irá se comportar no momento da concepção, e
em tempo de execução. Os campos de dados que têm um público modificador de acesso será
disponível na janela Inspetor para edição.
Figura 20 - Propriedades de Classe Car
No entanto, na Unidade para expor as propriedades, você vai precisar para pro-
vide a seguinte declaração sobre cada campo:
[SerializeField]
private string make;
// Store fazer como tipo de cadeia
[SerializeField]
private string modelo;
// Modelo de loja como tipo de cadeia
[SerializeField]
private int ano;
// Ano loja como tipo int
[SerializeField]
private string de cor;
// Cor loja como tipo de cadeia
Código Bloco 15 - SerializeField para Inspector Janela
Esta é a maneira mais fácil de expor os campos privados de uma classe na
Janela Inspector .
GameObjets estáticos
Muitas otimizações precisa de saber se um objeto pode se mover durante
jogabilidade. Informações sobre um estático, não-movimento, objeto muitas vezes pode ser
pré-calculado no editor assumindo que ele não será invalidada por uma

página 69
Vahé Karamian
55
mudança de posição do objeto. Isso vai ajudar com a prestação e
taxa de quadros de seu jogo. Tais técnicas são utilizadas para a optimização e
é uma boa idéia para aprender sobre os benefícios de-los como você projetar e
desenvolver o seu jogo. Para identificar um GameObject como estático ou não-estático ,
há uma caixa de seleção na janela Inspetor . Se a opção for marcada,
em seguida, a Unidade informará vários sistemas internos que o objeto não será
mover. A idéia aqui é melhoria de desempenho! estes inter-
sistemas finais são as seguintes:
1. Global Illumination : Iluminação avançada para uma cena.
2. Occluder e Occludee : otimização de renderização baseada em
a visibilidade de objetos a partir de posições de câmera específicos.
3. dosagem : Rendição de otimização que combina vários ob-
jectos em um objeto maior.
4. Navigation : o sistema que permite que os personagens para negociar
obstáculos na cena.
5. Off-Mesh Ligações : conexões feitas pelo Navigation sis-
TEM entre áreas descontínuas da cena.
6. Reflexão Probe : captura uma vista esférica da sua surround
Ings em todas as direções.
iluminação global
Global Illumination é um sistema que modelos como a luz é devolvida
off de superfícies para outras superfícies, luz indireta, ao invés de ser limi-
ITED apenas a luz que atinge uma superfície diretamente de uma fonte de luz, direta
leve. Modelagem de luz indireta permite efeitos que tornam o virtual
mundo parecer mais realista e conectado, uma vez objeto de afectar cada
aparência do outro. Um exemplo seria quando a luz solar bate no chão
na abertura de um caso e salta ao redor dentro para que as partes internas
o caso são iluminados também.
Tradicionalmente, os jogos de vídeo e outros em tempo real gráficos aplicação
ções foram limitados a iluminação directa, porque os cálculos
necessário para a iluminação indireta eram demasiado lento para que eles só poderiam ser usados
em situação de não-tempo real, como gerado por computador filmes. Um caminho para
jogos de contornar esta limitação é calcular apenas a luz indireta
para objetos e superfícies que são conhecidos de antemão que não têm mo-
ção, objeto estático.

página 70
Unity 3D - Jogo de Programação Intro
56
Isso ajudará a pré-calcular o efeito de iluminação indireta. apoio Unity
portos esta técnica, chamada cozidas lightmaps
5
. Além indirecta
luz, cozidos lightmaps, também tirar proveito da maior computação
tempo disponível para gerar mais realistas sombras suaves de luzes de área
e luz indirecta do que o que pode normalmente ser conseguida em tempo real com
técnicas.
oclusão Culling
Oclusão Culling é um recurso que desativa o processamento de objetos
quando eles não estão actualmente visto pela câmera, porque eles são ob-
scured (ocluída) byother objectos. Isso não acontece automaticamente,
já que a maioria dos objetos de tempo mais distante longe da câmera são atraídos
primeiro e mais estreitos os objetos são desenhados por cima. Isto é diferente de
Frustum Culling , como Frustum Culling única desativa os representantes para
objetos que estão fora da área de visão da câmera, mas não desativar
nada escondido da vista por overdraw.
O processo de oclusão abate irá percorrer a cena usando um
câmara virtual para construir uma hierarquia de conjuntos de objectos potencialmente visíveis.
Estes são os dados que é usado por cada câmera em tempo de execução para determinar
o que é visível eo que não é. Isso reduz o número de chamadas sorteio
e aumenta o desempenho do jogo.
batching
Para desenhar um objeto na tela, motor Unity tem de emitir um empate
chamada para a API gráfica
6
. Desenhe chamadas são muitas vezes caros, com o
API gráfica fazendo um trabalho significativo para cada chamada de desenho, fazendo com que per-
desempenho sobrecarga no lado do CPU.
Unidade usa lotes estática para resolver esta questão. O objetivo da estática
dosagem é de reagrupar o maior número de malhas em menos buffers para obter melhores per-
desempenho, tornando gigante malhas em vez de um monte de pequenas malhas
o que é ineficiente.
5
O processo no qual a luz indirecta é pré-calculada e armazenada.
6
OpenGL ou Direct3D
página 71
Vahé Karamian
57
Navegação
O sistema de navegação permite criar personagens que podem in-
telligently mover no mundo do jogo. Os usos do sistema de navegação
navegação malhas para raciocinar sobre o meio ambiente. a navegação
malhas são criados automaticamente de sua Cena Geometry .
sistema Unity NavMesh consiste das seguintes peças:
Figura 21 - Componentes NavMesh
1. NavMesh : é uma estrutura de dados que descreve o tranquilas
superfícies do mundo do jogo e permite encontrar o caminho de
um local de percorrer para outro no mundo do jogo. este
estrutura de dados é construído, de forma automática a partir do nível de geome-
experimentar.
2. Agente NavMesh : é um componente ajudando-o a criar char-
acters que evitam uns aos outros enquanto se move para a sua

página 72
Unity 3D - Jogo de Programação Intro
58
objetivo. Agentes razão sobre o mundo do jogo usando o
NavMesh e eles sabem como evitar um ao outro, bem como
obstáculos em movimento.
3. Off-Mesh Ligação : é um componente que lhe permite incorporar
atalhos de navegação, que não podem ser representados usando um
superfície tranquilas. Por exemplo, saltando sobre uma vala ou um
cerca, ou abrir uma porta antes de caminhar através dele.
4. NavMesh obstáculo : é um componente que lhe permite de-
escriba mover obstáculos o agente deve evitar ao
navegar no mundo. Um barril ou uma grade controlado pelo
sistema de física é um bom exemplo de um obstáculo.
Off-Mesh Ligações
As conexões entre os polígonos NavMesh são descritos US-
ing ligações dentro do sistema pathfinding. Às vezes é necessário deixar
o agente de navegar através de locais que não são de percorrer, por exemplo,
salta sobre uma cerca, ou atravessando através de uma porta fechada. estes casos
precisa saber o local da ação. Estas acções podem ser anotada
usando Off-Mesh links, que contam a pathfinder que existe uma rota
através do link especificado. Este link pode ser acessado quando mais tarde acompanhamento
ing o caminho, ea ação especial pode ser executado.
Probe reflexão
Uma sonda de reflexão é como uma câmera que captura uma vista esférica
de seus arredores em todas as direções. A imagem capturada é então armazenado
num Cubemap
7
que pode ser utilizado por objectos com materiais reflectores.
sondas de reflexão sevral pode ser utilizado num determinado local e objectos podem
ser configurado para usar o Cubemap produzido pela sonda mais próxima.
filmes e animações CG comumente apresentam reflexão altamente realista
ções, que são importantes para dar um senso de conexão entre
os objetos na cena. A precisão dessas reflexões vem com
um alto custo em tempo de processador. Este é um problema, uma vez que limita severamente a
O uso de objetos reflexivos em jogos em tempo real. Tradicionalmente, os jogos têm
7
A Cubemap é uma coleção de seis texturas quadrados que representam as reflexões sobre uma
meio Ambiente.

página 73
Vahé Karamian
59
usaram uma técnica chamada mapeamento de reflexão para simular os reflexos de
objetos, mantendo a carga de processamento a um nível aceitável.
Unidade melhora no mapeamento básico reflexão através do uso de Re-
Sondas de flexão, que permitem que o meio ambiente visual para ser em amostras
pontos estratégicos na cena. Geralmente, você deve colocá-los em todos os
ponto em que o aparecimento de um objecto reflector mudaria perceptível
habilmente. Quando um objecto reflector passa perto de uma sonda, a reflexão
amostras pela sonda pode ser usado para mapa de reflexão do objecto. Quando
várias sondas estão nas proximidades, Unidade pode interpolar entre eles para permitir
por mudanças graduais na reflexão. Como você observar, há muitos
detalhes técnicos e complexidades para cobrir neste livro, portanto, é
encorajados que o leitor estudar os temas sobre a sua própria, pesquisando
os detalhes adiante.
Prefabs - Conceitos e Uso
Como você projetar e desenvolver o seu jogo, você estará criando muitos
GameObjects com vários componentes e propriedades. Alguns dos
GameObjects que você estará criando vão ser bastante complexo.
Ao mesmo tempo, pode haver momentos em que você vai querer duplicar
ou replicar o mesmo GameObject exata dentro da mesma cena ou em um
cena diferente.
Figura 22 - Conceito Prefab

página 74
Unity 3D - Jogo de Programação Intro
60
A Prefab é um poderoso recurso no prazo de unidade que lhe permite
fazer uma cópia do seu GameObject e armazená-lo para uso posterior. o Prefab
age como um modelo a partir do qual você pode criar novas instâncias de objetos em
a cena. Outro poderoso recurso fornecido pelo Prefab é a capaci-
dade para editar e modificar o Prefab e automaticamente todas as instâncias ativas
do Prefab será refletido pelas últimas atualizações. Você também pode quebrar
uma ligação entre uma instância de uma casa pré-fabricada e do Prefab para substituir o
propriedades ou fazer alterações especiais para que in- não-relacionada particular,
posição. Você vai ter uma melhor caiu do que Prefabs são e por que eles são
tão útil em capítulos posteriores.
Pai-filho do relacionamento
Unidade usa um conceito chamado de Parenting . Parentalidade é um dos mais
conceitos importantes para entender quando se usa Unidade. Quando um GameOb-
jeto é um pai para outro GameObject, a Criança GameObject vai
mover, girar e dimensionar exatamente como seu pai faz. Você pode pensar em
parentalidade como sendo a relação entre os seus braços e seu
corpo; sempre que o seu corpo se move, os braços também se movem junto com ele.
objetos filho também pode ter seus próprios filhos e etc
8
...
Para fazer qualquer GameObject o filho de outro, arraste o desejado
criança para o pai desejado na hierarquia . A criança vai herdar o
movimento e rotação de seu pai. Você pode usar bicicleta dobrável de um objeto pai
a seta para mostrar ou ocultar as suas crianças, se necessário. O pai-filho
relacionamento de um GameObject é representado visualmente na Hierarquia
Janela. A GameObject pode ter um pai-filho muito complexa estru-
tura.
8
Qualquer objeto pode ter vários filhos, mas apenas um dos pais.

página 75
Vahé Karamian
61
Capítulo 4 - Regras e Mecânica de jogo
Conceitos básicos de Mecânica de jogo
A atividade subjacente em jogos é jogar. O jogo pode ser encontrado em todos
culturas humanas. Play oferece ensino e aprendizagem oportunidades.
As crianças pequenas vão jogar para ajudá-los na prática de habilidades para a vida. A chave
elemento em jogo é a natureza de causa e efeito que reforça certa
comportamentos. Para a prática é a tentativa de obter melhor em algum conjunto de habilidades.
Quando o jogo torna-se estruturas e metas, regras e ações são apro-
dobraram eles se transformam em jogos. No playground, simples jogo envolvendo
perseguir outras crianças se transforma em um jogo de Tag quando uma criança BE
vem "it" e o objetivo é guia outra criança, a fim de fazer
ele ou ela "isso".
Essas ações fundamentais do comportamento humano encontrados no jogo
e jogos de crianças são encontrados no centro de jogos de computador
e tornar-se o conjunto de mecânica de jogo código.
Procurando
A pesquisa é um processo cognitivo humano básico que envolve a percepção
ção e digitalização de um ambiente. Em jogos de computador, essa capacidade é
aproveitados para fazer o olhar do leitor para uma parte específica de informação,
item, localização, ou personagem em um ambiente. O objectivo da
Pesquisa do jogador pode ser a de encontrar um item necessário para avançar no jogo,
por exemplo, uma chave para abrir uma porta, ou para percorrer um labirinto para ir de
um lugar para outro.
correspondente
Matching é uma atividade que faz parte do processo de pesquisa. Para o
cérebro humano, identificando um objeto como sendo semelhante a outra é uma sim-
coisa ple. Para estar à procura de alguma coisa é ser capaz de identificar quando
a imagem mental que você tem da coisa que você está procurando é a mesma
coisa que você está olhando; ou seja, eles combinam. Muitas atividades do dia-a-dia

página 76
Unity 3D - Jogo de Programação Intro
62
envolvem correspondentes, tais como encontrar um par de meias de marcar para a direita
PIN em um caixa eletrônico.
Em um jogo, a correspondência é usado para obter os jogadores para colocar um ou mais coisas
juntos, porque eles são pequenos pedaços de um todo, ou são os mesmos
cor ou forma ou têm outras características semelhantes. Esta ac- comum
ção pode encontrar jogadores que une peça de uma máquina para torná-lo
funcionam como um todo, ou colocando as mesmas peças de cor próximas umas das outras
sobre uma grelha.
classificando
A tentativa de colocar ordem no caos é um tamento humano comum
eu ou. Pessoas com casos muito extremos de exigir que tudo seja em sua
lugar pode sofrer de transtorno obsessivo compulsivo. No entanto, em
muitos casos, quando as coisas estão ordenados, a vida é muito mais fácil. Quando as coisas são
em ordem e podemos contar com eles estar em ordem, ele levanta algumas das
carga cognitiva fora de fazer outras tarefas.
Jogos usam esse desejo de classificação para motivar os jogadores para organizar dois ou
mais itens de acordo com suas características, como tamanho, cor, espe-
cies, idade ou nome. Triagem pode também ser empregue em actividades em que
executar tarefas em ordem é necessário para completar um desafio.
chancing
dispositivos chance como morrer e o desenho de palhas para fins
de triagem, seleção e divisão são comuns entre muitas culturas,
ea prática é referenciado na literatura grega clássica como o cavalo de Tróia
guerras e de antemão em artefatos egípcios.
Usando chance na tomada de decisão é referido como de risco. Pesquisa
demonstrou que os tipos de riscos as pessoas tomam-tronco hoje de volta à situação
ções encontradas pelos nossos antepassados, incluindo a concorrência com outros
indivíduos, a concorrência com as culturas dos outros, acasalamento, recurso alocação
ção, e meio ambiente.
Nos jogos, a chance é usado para determinar a probabilidade de futura saída
vem. Esta é uma das ações mais antigas usadas em jogos que envolvem a

página 77
Vahé Karamian
63
uso de dados: rolamento ou lançamentos de moeda para determinar um resultado com base em
chance. Sem algum elemento de probabilidade em que os jogadores sabiam
que o resultado de suas ações seria antes que eles fizeram eles, há
não haveria qualquer necessidade de assumir um risco. A pesquisa mostrou a maior
o risco, maior a recompensa neuroquímica.
misturando
Misturando ações envolve a combinação de objetos ou ações para pro-
duzir um resultado inatingível de outra forma. No dia-a-dia, as pessoas
misturar os ingredientes para fazer pigmentos de alimentos, tintas para fazer novas cores, e
ações multi-tarefa para obter as tarefas concluídas mais rapidamente.
Em jogos de computador, as ações podem ser combinados para permitir caracteres
para executar tarefas que não poderiam fazer com ações individuais, por exemplo,
saltar durante a execução de saltar através de uma fenda no mundo do jogo ou
combinando várias combinações de teclas para executar movimentos especiais.
Combinando objetos do jogo para produzir outros objetos do jogo é também um
exemplo de mistura.
Cronometragem
A sociedade humana é executado por vez. Mesmo antes do advento da mechan-
dispositivos de medição do tempo iCal, revolução da Terra em torno do sol significava
os seres humanos eram constantemente em um horário.
O uso de tempo num jogo de computador pode ser aplicado como um jogo
mecânico. Pode envolver a realização de uma tarefa dentro de um certo tempo,
cronometrando uma ação, ou à espera de algum evento para ocorrer. este mecanismo
é usado para instigar a urgência em situações como corridas, seja
contra o relógio ou um oponente ou para gerar expectativa quando esperar-
ing algo para ocorrer ou forçar a paciência em cima de um jogador que tem
que esperar para o ambiente do jogo para mudar.
O tempo pode ser usado para adicionar respeito ao longo processo de formação
um personagem com novas habilidades, adquirir novo conjunto de habilidades e assim por diante.
Às vezes, isso tende a levar muitas horas e às vezes dias. Em um
jogo on-line, isso pode continuar enquanto o jogador está longe da

página 78
Unity 3D - Jogo de Programação Intro
64
avatar. Esta é outra boa maneira de manter o jogador se envolver e trazer
-los de volta para o jogo ao longo do tempo para o progresso ainda mais.
progredindo
A vida é sobre a progredir, se estar a crescer a partir de um bebê a um
adulto, recebendo um diploma universitário, ou obter uma promoção no trabalho. Humanos,
em geral, a experiência estágios em suas vidas que se correlacionam com a sua idade
e realizações.
Jogos empregar esquema de progressão em que o jogador começa como
um noob e progride para o nível do perito na extremidade. Ao longo desta Jour-
ney, esquemas de progressão são colocadas no lugar que dar aos jogadores uma sensação
a atingir por seus esforços.
capturar
Para capturar é tomar algo que pertence a outra pessoa
através da força ou de seus próprios esforços. Ao longo da história, há uma longa
lista de tribos capturar membros de outras tribos, os exércitos capturar cidades,
e os piratas tomando navios.
Alguns jogos incorporar este mecânico como o objectivo primordial do
jogo. A maioria dos jogos de estratégia em tempo real exigem que os jogadores capturar e prender
recursos e bases, enquanto a acumular suas forças armadas e da economia para
atacar e capturar ou destruir o adversário. Ou pode ser tão simples como
jogar capture a bandeira.
conquistando
Na mesma linha de captura é a ação de conquista. enquanto que
captura é mais ligada ao roubo, a conquista é de cerca de suplantar ou
destruir a concorrência. Como a captura, raças humanas têm uma longa
história da conquista.
Suplantar um adversário é uma meta clássico jogo. No xadrez, o
objetivo é obter o seu oponente em xeque-mate, tendo peças ao longo
o caminho para fazê-los render.

página 79
Vahé Karamian
65
anulação
Uma chave para a sobrevivência humana é a prevenção de não gostou e inofensivo
coisas ful. Isto não inclui comer substâncias venenosas, não jogando
com fogo, e olhando antes de atravessar a rua.
Alguns jogos incorporar tais mecânica, onde o jogador tem para o
evitar certas situações e ou objetos no jogo. Por exemplo, uma ve-
culo deve evitar bater pedestres ao descer a rua. UMA
tanque militar deve evitar as minas terrestres, enquanto em seu caminho para o dado
destino.
Em vez de dizer os jogadores que eles podem fazer, a evasão é tudo sobre
mostrando-lhes o que eles não podem fazer. Isto pode ser implementado por penalidades
nalizar o jogador quando eles realizam uma ação em um ambiente de jogo
onde deveriam ter evitado.
Evitar coloca restrições sobre as ações dos jogadores de tal forma que
eles devem manter em mente o que eles não podem fazer ao tentar progredir
em todo o ambiente do jogo.
Coletando
Coleta é outro comportamento humano natural. No extremo,
alguém que não pode controlar a coleta e deixando de lado sua recolhido
itens pode ser chamado de um coletor de lixo.
Em um ambiente de jogo, os itens estão lá para ser recolhidos para UM FIM
representar ou um objectivo. Alguns itens podem ser recolhidos e colocados em um
inventário para ser usado em um momento posterior. A mecânica de coleta é muitas vezes
usado com a pesquisa.
Por exemplo, alguns jogos podem pedir ao jogador para recolher o maior número
moedas de ouro quanto possível em um determinado período de tempo.
De um modo geral, todos os jogos de usar uma combinação de toda a base
mecânica de jogo que temos discutido. A maioria dos jogos de RPG
implementar todas as mecânicas de jogo para fazer o jogo jogar muito
mais interessante e envolvente. Obviamente, isso leva a mais complexa

página 80
Unity 3D - Jogo de Programação Intro
66
design de jogo e esforço sobre os game designers e desenvolvedores para im-
plementação.
Exemplos simples da Mecânica
Nesta seção, vamos olhar para o uso e implementação da
mecânica que foram discutidos anteriormente. Os exemplos que se irá combinar um
ou mais de a mecânica para ilustrar alguns conceitos básicos do jogo do jogo.
O jogo Batalha Naval iremos desenvolver no Capítulo 6 - Criando BAT-
tleship e Capítulo 7 - Delving o Código usar algum do jogo
mecânica que temos listados e descritos na seção anterior.
Os seguintes mecanismos são fáceis de detectar no jogo: pesquisa,
calhante, e conquistando.
O jogador precisa procurar navio do adversário para ser de-
stroyed. O jogador está tendo uma chance, colocando seus navios para
o tabuleiro de jogo, da mesma forma, o jogador está tendo uma chance sempre que ele ou
ela está escolhendo um alvo a atingir. Finalmente, o objetivo do jogo é
conquistar o oponente por destruir totalmente todas as suas peças do jogo.
Vamos colocar rapidamente em conjunto um novo projeto para construir e demonstrar
a implementação dos diferentes mecanismos.
 Nível 1: pesquisa; coleta; correspondência e classificação.
 Nível 2: Chancing; mistura e temporização
 Nível 3: progredindo; evasão; capturando e conquistar
Desenvolvimento de Nível 1
O objetivo deste nível é para ajudar a entender e implementar o
quatro mecanismos de busca, coleta, correspondência e classificação. Deixe-nos
começar por abordar a pesquisa e coleta de primeira. O objetivo inicial
do jogador será para pesquisar o mundo do jogo e recolher um conjunto de ob-
projectos que serão então usados para combinar e triagem.
 Objectivo 1: Pesquisar e recolher objetos X, Y e Z
 Objectivo 2: Organizar os objetos coletados por seu tamanho.

página 81
Vahé Karamian
67
Acabamos de definir o nosso objectivo baseado na mecânica de jogo
descrito. Agora é hora de colocar realmente em conjunto um exemplo simples para
ilustrar o conceito.
Supondo que você tenha iniciado um novo cenário para efeitos do presente
prática, vamos ir em frente e criar o nosso primeiro objeto jogo, um terreno.
Para criar um terreno, você terá de escolher:
 GameObject-> 3D Objeto-> Terrain
A partir do menu principal. O tamanho padrão do terreno será muito
grande, para os fins da presente prática, será necessário reduzi-lo a cerca de
50 x 50. Isso é bom o suficiente para a demonstração. Além disso, não se esqueça
que, esta é o equivalente de 2,500 metros quadrados de área! Não um fácil
tarefa para preencher!
Figura 23 - Simples Terreno 50x50
Seu terreno deve ser semelhante t o Figura 23 . O cubo foi colocado
apenas para uma pista visual no tamanho do terreno. Usando o construído em terreno

página 82
Unity 3D - Jogo de Programação Intro
68
ferramenta, que pode dar algumas agradáveis contornos da superfície do terreno a fim de
torná-lo mais agradável.
Figura 24 - Snap Shot of Terrain
Ferramenta
Isto pode ser alcançado dentro do
IDE da unidade através da Inspecção
tor janela:
1. Levante / Baixa Terrain
2. Pintura Altura
3. suave Altura
Textura 4. pintura
5. Coloque Árvores
6. Os detalhes de pintura
7. Configurações de terreno
A finalidade de cada numerada
ícone foi listado acima.
Figura 25 - Terreno projeto

página 83
Vahé Karamian
69
Você pode usar recursos de um a sete para modificar e moldar o
terreno. Vá em frente e jogar com as opções e chegar a um terreno
modelo que você está consentimento com.
Olhando para a Figura 25 y ocê pode ver que é muito fácil criar in-
terrenos ressantes com as ferramentas fornecidas para prototipagem rápida. eu sou
feliz com o mapa do terreno, agora o próximo passo seria aplicar algum
texturas e outros objetos ambientais, tais como árvores e pedras. Para
adicionar textura ao terreno, selecione Texture Dor do Inspector Win-
Dow e aplicar a textura desejada para o terreno.
Figura 26 - Terreno com textura aplicada
Nada mau para um programador se você me perguntar. Então, agora nós definimos
nosso terreno, e temos de colocar alguns objetos do jogo a ser procurado
e recolhidos. Para manter os gráficos simples, usaremos esfera e cubo
com a finalidade de demonstrar os conceitos. Nosso jogador será represen-
ressentido como uma esfera, e os nossos objetos do jogo pode ser representado por qualquer
um dos tipos de primitivas.

página 84
Unity 3D - Jogo de Programação Intro
70
Para a busca de objeto e coleção, podemos utilizar três tamanhos diferentes
de cubos. Para a pesquisa, o jogador terá que encontrar todos os três
cubos, e para a classificação, o jogador terá de empilhá-los em cima de um
outro que tenha o maior cubo como a base. Isto irá lidar com o nosso Obser-
jectivos um e dois como listado.
Figura 27 - Busca e recolher objetos do jogo
NOTA: Existem melhores opções e ferramentas projetadas especificamente para o edifício
terrenos e ambientes naturais complexos. Em um cenário de vida real, você será mais
provável usar uma ferramenta externa para criar o seu terreno e, em seguida, importá-lo para a
Unidade de
programação.
Podemos posicionar aleatoriamente os três cubos de diferentes tamanhos na
terreno como indicado i n Figura 2 7. No jogo que seria necessário para ser capaz
para identificar estes objectos a partir de um certo tipo. Isto irá permitir-nos
tratá-los adequadamente internamente através do código.

página 85
Vahé Karamian
71
Então, aqui estão alguns requisitos que precisamos definir para atender a nossa
primeiros objetivos no jogo:
 O jogador pode recolher o objeto, passando por eles ou por
clicando sobre o objeto quando estão no intervalo.
 jogador terá de mover os objetos para a área designada de modo
empilhamento.
 Jogador precisa identificar os objetos a serem recolhidos.
 jogador precisa recuperar dados de objeto do recolhida ob-
projectos para processamento posterior.
Antes de continuar com o nosso exemplo, eu gostaria de aproveitar a
tempo e introduzir alguns temas e conceitos muito importantes para que nós
ter um bom entendimento e de fundo a respeito de como Unity Han-
DLES a interação entre diferentes GameObjects.
Física para Jogos
Um motor de física é um software de computador que fornece uma aproximação
simulação companheiro de certos sistemas físicos, tais como corpo rígido
dinâmica, detecção de colisão, dinâmica de corpo macio, e dinâmica de fluidos.
Há geralmente dois tipos de motores de física, em tempo real e de alta
precisão .
Alta precisão
motores de física de alta precisão exigem mais poder de processamento para
calcular a física muito precisa e são normalmente utilizados por cientistas e
engenheiros para simulações complexas.
Tempo real
motores de física em tempo real são usados em jogos de vídeo e outras formas
de computação interactiva. Eles usam cálculos simplificados e de-
a precisão aumentou para calcular a tempo para o jogo de responder a um
taxa adequada para o jogo.
motores de jogo
Na maioria dos jogos de computador, a velocidade dos processadores e jogabilidade
são mais importantes do que a precisão da simulação. Isto conduz aos desenhadores

página 86
Unity 3D - Jogo de Programação Intro
72
para motores de física que produzem resultados em tempo real, mas que replica
física do mundo real apenas para casos simples e tipicamente com algum AP-
aproxi-.
Objetos em jogos interagem com o jogador, o ambiente, e
entre si. Normalmente, a maioria dos objetos 3D em jogos são representados por dois
malhas ou formas separadas. Um destes é o malhas altamente complexo
e forma detalhada visível para o jogador no jogo, e um segundo sim-
plified malha invisível é usado para representar o objeto para a física
motor, de modo que o motor de física pode interagir com ele.
Digite o Componente Collider
Aceleradores são usados para definir a forma de um objecto para o objectivo
de colisões físicas. O colisor não precisa necessariamente ser o
mesma forma de malha do objeto jogo. Normalmente, uma estimativa aproximada é de-
dez mais eficiente e indistinguíveis na jogabilidade.
Os aceleradores mais simples, que são também o menos processador de intenção
sive, são os tipos colisor primitivos: Box Collider , Sphere Collider ,
eo Collider Capsule . Ao combinar um posicionamento desses aceleradores
você pode muito bem criar um colisor composto que mais irá satisfazer
qualquer objeto jogo para detecção de colisão.
Aceleradores podem ser adicionados a um objecto, sem uma compo- corpo rígido
nente para criar pisos, paredes e outros elementos imóveis de uma cena.
Estes são referidos como estático
9
colisores.
Gatilhos
O sistema de scripting pode detectar quando ocorrem colisões e iniciar
ações usando o OnCollisionEnter () função. No entanto, também podemos
usar o motor de física simples para detectar quando um colisor entra no
espaço de outra sem a criação de uma colisão. Um colisor configurado como
um gatilho, usando o IsTrigger propriedade, não se comporta como um ob- sólida
jeto e simplesmente permitir que outros aceleradores para passar. Quando um
9
colliders estáticos pode interagir com aceleradores dinâmicos, mas desde que eles não têm corpo
rígido,
eles não se move em resposta às colisões.

página 87
Vahé Karamian
73
colisor entra no seu espaço, um gatilho irá chamar o OnTriggerEnter () função
ção em scripts do objeto gatilho.
Ações de script em Collision
Quando ocorrem colisões, o motor de física chama funções com espe-
nomes espe- sobre quaisquer scripts anexados aos objetos envolvidos. Você irá
preciso implementar a lógica de código nessas funções para responder à
caso de colisão.
No primeiro actualização física em que a colisão é detectada, o On-
CollisionEnter () função é chamada. Durante as atualizações onde o contato é
mantida, OnCollisionStay () função é chamada e, finalmente, OnColli-
sionExit () função é chamada indicando que o contato tenha sido quebrado.
Da mesma forma, aceleradores de gatilho chamar o análogo OnTriggerEnter () função
ção, OnTriggerStay () função ea OnTriggerExit () funções.
Interações collider
Aceleradores de interagir umas com as outras de maneira diferente dependendo de quão
seus componentes corpo rígido foram configurados.
estática Collider
Esta é uma GameObject que tem um colisor mas nenhum corpo rígido. Estático
aceleradores são usados para a geometria nível que permanece sempre no mesmo
lugar e nunca se move ao redor. objetos corpo rígido de entrada irá colidir
com o colisor estático, mas não vai movê-lo.
corpo rígido Collider
Este é um GameObject com um colisor e A, não-normal de cinemática
Corpo rígido em anexo. colliders corpo rígido são totalmente simulada pelo
motor de física e pode reagir a colisões e forças aplicadas a partir de um
script. Eles podem colidir com outros objetos, incluindo aceleradores estáticos,
e são a configuração colisor mais vulgarmente utilizado nos jogos que
usar a física.
Cinemática corpo rígido Collider
Esta é uma GameObject com um colisor e de um corpo rígido cinemática
anexado, o IsKinematic propriedade do corpo rígido está habilitado. Você
pode mover um objeto corpo rígido cinemática de um script, modificando a sua

página 88
Unity 3D - Jogo de Programação Intro
74
Transformar componente, mas não vai responder a colisão e forças
como um corpo rígido não-cinemática. rigidbodies cinemática deve ser utilizada
para aceleradores que podem ser movidos ou com deficiência / habilitado ocasionalmente, mas
que deveria de outra forma se comportam como aceleradores estáticos. O melhor exemplo para
ilustrar este conceito seria uma porta de correr. A porta deve nor-
malmente actuar como um obstáculo físico bens, mas pode ser aberta quando
necessário. Ao contrário de um colisor estático, um corpo rígido cinemática em movimento vai
aplicar fricção para outros objetos e vai "acordar" outros rigidbodies
quando fazem contato.
Corpo rígido
Um corpo rígido é o principal componente que permite um comportamento físico
para um objeto. Com um corpo rígido em anexo, o objeto será imediatamente
responder à gravidade. Se um ou mais componentes Collider também são adicionados,
em seguida, o objecto será movido por colisões de entrada.
Rigidbodies permitir que seus GameObjects de agir sob o controle do
motor de física. Isso abre a porta de entrada para colisões realistas, variada
tipos de juntas, e outros comportamentos muito legal. manipulando o seu
GameObject pela adição de forças para o corpo rígido cria uma muito diferente
comportamento do que ajustar o Transform componente diretamente. Como um bom
regra geral, você não deve manipular o corpo rígido ea Trans-
forma da mesma GameObject, apenas um ou o outro.
articulações
Você pode anexar um corpo rígido para outro ou para um ponto fixo no espaço
usando um componente comum. Geralmente, você quer uma articulação para permitir que pelo
menos
alguma liberdade de movimento. Unity fornece o seguinte Junte-nente
nentes que impõem restrições diferentes: Dobradiça conjuntas e Primavera conjuntas .
Dobradiça conjunta permite a rotação em torno de um ponto e eixo específico, enquanto
Primavera Comum mantém o objeto distante, mas permite que a distância entre eles
esticar ligeiramente. As articulações também tem outras opções que podem ser habilitados para
efeitos específicos.

página 89
Vahé Karamian
75
dobradiça Joint
Os grupos dobradiça Joint dois Rigidbodies juntos, restringindo
-os a mover-se como eles são ligados por uma charneira. Melhor exemplo seria
ser uma porta, mas também pode ser aplicado e utilizado para modelar as cadeias, e etc ..
Uma única dobradiça Misto deve ser aplicado a uma GameObject. o
dobradiça irá girar no ponto especificado pela Anchor propriedade, que se deslocam
em torno do especificado Eixo propriedade.
primavera conjunta
O Conjunto Primavera junta duas corpo rígido juntos, mas permite que o dis-
tância entre eles para alterar como se estivessem conectados por um
Primavera.
Os mola actua como um pedaço de elástico que tenta puxar os dois an-
chor aponta juntos para exatamente a mesma posição. A força do puxão
é proporcional à distância existente entre os pontos com a força
por unidade de distância determinada pelo Primavera propriedade. Para evitar que a mola
de oscilação infinitamente você pode definir o Damper valor que reduz
a força da mola em proporção com a velocidade relativa entre os dois ob-
jectos. Quanto mais alto o valor, mais rapidamente a oscilação vai morrer
baixa.
Figura 28 - Cube Prefab com Cube Collider

página 90
Unity 3D - Jogo de Programação Intro
76
Agora que temos uma melhor compreensão de como o sistema funciona,
podemos continuar com a implementação do nosso nível 1. Observe que
para cada uma das primitivas de cubo que criamos, uma caixa Collider tem
foi automaticamente anexada ao objeto jogo. Isto é mostrado na Figura
28.
Figura 29 - Janela Inspector
mostrando Box Collider
Dando uma olhada no Inspetor
Janela, na F igura 29 f ou a se-
cionado cubo, temos de ver o
detalhes dos componentes AT-
tached ao objeto jogo do cubo.
Eu gostaria de transformar sua atenção
ção ao Box Collider
componente ligado ao jogo
objeto. Observe que, por padrão,
é exactamente o mesmo tamanho e
forma como o próprio cubo, e é
centrado na origem local.
Estes são valores ajustáveis e
você pode ir em frente e modificar
-los no editor e visualmente
ver o resultado.
A outra característica principal é a
IsTrigger propriedade indicada através de
a flecha. Por padrão, esta é visualizada
abled, nós estamos indo para ir em frente
e habilitar o prop- IsTrigger
erty para que possamos usar o
OnTriggerEnter function () a partir de
o script para lidar com colisão.
A próxima propriedade que eu gostaria que você prestar atenção é o
Tag propriedade. Observe que, por padrão, todos os objetos do jogo que você
criar na cena vai ser não identificado. Nós vamos fazer uma

página 91
Vahé Karamian
77
nova tag e associar o nosso jogo objetos com a marca recém-criada. este
propriedade, em seguida, pode ser usado dentro do script para identificar o objeto que
estão interagindo com.
Para criar uma nova tag, basta usar o menu drop-down e selecione
Adicionar Tag ... para exibir a interface do usuário para introduzir um novo elemento tag
na lista. Se uma marca já está na lista, então você pode simplesmente selecioná-lo
sem ter de o adicionar à lista. Vou usar MyCollectable como um novo
elemento tag. Suas prefabs cubo deve ter a seguinte configuração
ções:
Cube 1
Cube 2
Cube 3
ID: C1
ID: C2
ID: C3
Tag: MyCollectable
Tag: MyCollectable
Tag: MyCollectable
Escala: <0.25,0.25,0.25>
Escala: <0.50,0.50,0.50>
Escala: <0.75,0.75,0.75>
Eu não estou listando a posição e orientação que será diferente
para você com base na formação de seu terreno e posicionamento do
cubos. Temos configurado nossos objetos de pesquisa e recolha,
agora precisamos trabalhar no roteiro. Vá em frente e criar um novo script
chamados MyCollectable.cs . No momento em que gostaria de implementar
a detecção de colisão.
classe pública MyCollectable: MonoBehaviour {
// Use isso para inicialização
vazio Iniciar () {
}
// Update é chamado uma vez por quadro
vazio Update () {}
// FUNÇÃO para detectar se há uma colisão
// Com este objeto específico
vazio OnTriggerEnter (Collider c)
{
Debug.log ( "Você esbarrou em mim !!!" );
}
}
Código Bloco 16 - MyCollectable.cs lista
Vá em frente e anexar o script para todos os objetos de cubo que são
vai ser recolhidos. No momento, não vamos ir mais longe. O código
vai imprimir no console uma mensagem indicando que temos
colidiu com o objeto. Antes de continuarmos, vamos em frente e trabalhar

página 92
Unity 3D - Jogo de Programação Intro
78
em nosso personagem do jogador. Isto irá permitir-nos realmente navegar no
mundo e testar o nosso código e ter uma idéia de como ele vai funcionar.
Mecânica de caracteres
Entrada do jogador
Em algum ponto no tempo, você vai precisar para começar a receber a entrada do
jogador e ser capaz de traduzir a entrada em algum tipo de uma ação.
Dependendo do jogo e do design, este elemento por si só poderia ser
muito complexo. Para efeitos de demonstração, vamos manter
coisas simples e direto ao ponto.
Então, como discutido anteriormente, usaremos uma esfera primitiva para representar
nosso jogador. Para esta esfera que será necessário anexar algum tipo de um script
para lidar com o movimento. Vamos chamar-lhe PlayerInput.cs . este script
vai lidar com o movimento inicial do nosso personagem no mundo.
usando UnityEngine;
usando System.Collections;
classe pública PlayerInput : MonoBehaviour {
// Use isso para inicialização
vazio Iniciar () {
}
// Update é chamado uma vez por quadro
vazio Update () {
// Código para o movimento do jogador (CP) para a frente
se ( Input .GetKey ( KeyCode .UpArrow))
{
este .transform.Translate ( Vector3 .forward * Tempo .deltaTime);
}
// Código para o movimento do jogador (CP) para trás
se ( Input .GetKey ( KeyCode .DownArrow))
{
este .transform.Translate ( Vector3 .Contra * Tempo .deltaTime);
}
// Código para o movimento do jogador (CP) esquerda
se ( Input .GetKey ( KeyCode .LeftArrow))
{
este (.transform.Rotate Vector3 .Até, -5);
}
// Código para o movimento do jogador (CP) à direita
se ( Input .GetKey ( KeyCode .RightArrow))
{
este (.transform.Rotate Vector3 .Até, 5);

página 93
Vahé Karamian
79
}
}
}
Código Bloco 17 - PlayerInput () versão inicial
Vá em frente e anexar o script para a esfera
10
, E use a seta
chaves para se deslocar no terreno. Observe como o motor internacional de física
age com o corpo rígido do jogador. Isto é especialmente visível quando
você está tentando subir um morro ou montanha. Você vai notar que a
esfera que é suposto representar o personagem do jogador vai rolar
para baixo e ficar afectado pelas forças aplicadas a ele por meio da interacção
da colisão das malhas entre si eo terreno pela phys-
motor ics.
Para resolver esse problema, você terá que colocar algumas restrições sobre a
Corpo rígido componentes e a forma como ela vai reagir ao motor de física.
As limitações seriam para desactivar a rotação sobre o X , Y e Z
Axis para este objeto jogo particular.
Figura 30 - corpo rígido Congelar Rotação
Quando você executa o jogo agora, você vai notar que o jogador char-
O Acter não entrar em um modo caótico de rotação quando colidir com
10
O objeto do jogo primitiva representando seu personagem jogador precisa também ter um
componente de corpo rígido ligado a ele. Leia a seção Física para obter uma melhor compreensão
do
como aceleradores de trabalho.
página 94
Unity 3D - Jogo de Programação Intro
80
a malha de terreno. Isto está mais próximo do comportamento que deseja simular, em
Neste ponto, para efeitos de demonstração.
Configuração da câmara
Mais uma melhoria eu gostaria de fazer é o posicionamento da
objeto de câmera. Gostaria que a câmera para acompanhar o personagem do jogador
por trás, e um pouco elevado, como uma espécie de câmera em terceira pessoa
configuração. É realmente muito fácil de configurar essa configuração. Aqui está o
passos:
Figura 31 - Terceira Pessoa Configuração da Câmara
1. No designer cena, orientar a vista de modo a que você está atrás
o personagem do jogador e um pouco acima dela.
2. Selecione a câmera principal objeto jogo e do
Menu de GameObject selecionar GameObject-> Alinhar Com Vista
opção
11
.
11
Isto irá mover o objeto do jogo Câmera principal e colocá-lo e orientar a vista de ex-
actly o que você vê no designer cena.

página 95
Vahé Karamian
81
3. Tornar o jogo Câmera principal objeto um filho do jogador
caráter, arrastando-a com o jogo personagem do jogador
objeto
12
.
4. Agora você pode usar transformar o local de portagens disponíveis para o
Câmera principal para afinar os ângulos e vista para o porto.
No final das etapas, você deve ter uma relação entre o
personagem do jogador ea câmera semelhante ao o f Figura 31 . Vá em frente
e executar o jogo, e você verá que nós temos algo que é muito
mais agradável. Vá em frente e veja se você pode recolher o cubo temos
configuração no nível. Você vai notar que você colidir com eles, mas comunicação nada
ing acontece. Nossa declaração de depuração não é mesmo mostrando-se, isto é,
porque nunca permitiu que a IsTrigger propriedade para verdadeiro no cubo de
objeto jogo. Vá em frente e pô-los a verdade, e executar mais uma vez.
Figura 32 - Collider Interação após IsTrigger é Ativado
Note-se que a interação de aceleradores do objeto dois jogos são
tratadas de forma diferente pelo motor de física uma vez, vamos definir o IsTrigger
propriedade sobre os objetos colecionáveis para true. Agora, você vai notar também
que o console está nos dando a saída esperada:
12
Isto irá criar uma relação pai / filho entre os dois objetos do jogo.

página 96
Unity 3D - Jogo de Programação Intro
82
Figura 33 - saída do console para detecção de colisão
Agora podemos começar a parte divertida, a magia da programação através
script que nos permitirá manter o controle dos itens coletados. Nós
seria necessário para expandir nossos scripts um pouco mais para lidar com a coleta de
nossos objetos do jogo, que também pode ter de introduzir um novo roteiro para o
nó de dados. Vamos começar pela expansão do MyCollectable.cs script.
usando UnityEngine;
usando System.Collections;
classe pública MyCollectable : MonoBehaviour {
public int ID;
public float size;
// Use isso para inicialização
vazio Iniciar () {
este .transform.localScale = new Vector3 (tamanho, tamanho, tamanho);
}
// Update é chamado uma vez por quadro
vazio Update () {
}
}
Código Bloco 18 - MyCollectable.cs ver 2
Eu adicionei dois membros públicos que representam o ID eo tamanho
do objeto colecionáveis. O Start () função irá usar a propriedade de tamanho
para dimensionar o objeto jogo colecionáveis quando o jogo começa. Notar que
não temos mais o OnTriggerEnter () função listada. Vamos Han-
dle a detecção de colisão na PlayerInput.cs script.
Enquanto isso, tivemos que introduzir um novo script que é usado para
unicamente armazenar dados que serão utilizados durante o jogo. Este novo roteiro é
chamados MyCollectableData.cs . Aqui está a lista para ele:

página 97
Vahé Karamian
83
usando UnityEngine;
usando System.Collections;
classe pública MyCollectableData {
public int ID;
public float size;
pública MyCollectableData () {}
}
Código Bloco 19 - MyCollectableData.cs
Esta é uma classe simples que será usado para armazenar e recuperar apenas a
dois atributos ID e tamanho . A principal script que irá lidar com a colisão
eo registro do objeto pick-up é implementado no Player-
Input.cs script.
usando UnityEngine;
utilizando System.Collections.Generic;
classe pública PlayerInput : MonoBehaviour {
pública Lista < MyCollectableData > myCollection = nova Lista < MyCollecta-
bleData > ();
anular Awake ()
{
// Certifique-se que comece a limpo
este .myCollection.Clear ();
}
// Use isso para inicialização
vazio Iniciar () {
}
// Update é chamado uma vez por quadro
vazio Update () {
// Código para o movimento do jogador (CP) para a frente
se ( Input .GetKey ( KeyCode .UpArrow))
{
este .transform.Translate ( Vector3 .forward * Tempo .deltaTime);
}
// Código para o movimento do jogador (CP) para trás
se ( Input .GetKey ( KeyCode .DownArrow))
{
este .transform.Translate ( Vector3 .Contra * Tempo .deltaTime);
}
// Código para o movimento do jogador (CP) esquerda
se ( Input .GetKey ( KeyCode .LeftArrow))
{
este (.transform.Rotate Vector3 .Até, -5);
}

página 98
Unity 3D - Jogo de Programação Intro
84
// Código para o movimento do jogador (CP) à direita
se ( Input .GetKey ( KeyCode .RightArrow))
{
este (.transform.Rotate Vector3 .Até, 5);
}
se ( Input .GetKeyUp ( KeyCode .Z))
{
foreach ( var d neste .myCollection)
{
Debug log (d.ID);
}
}
}
vazio OnTriggerEnter ( Collider c)
{
Se (c.tag.Equals ( "MyCollectable" ))
{
var recolher = c.gameObject.GetComponent < MyCollectable > ();
MyCollectableData dados = novas MyCollectableData ();
data.ID = collect.ID;
data.size = collect.size;
este .myCollection.Add (dados);
Destroy (c.gameObject);
}
}
}
Código Bloco 20 - PlayerInput.cs Ver. 2
Você vai notar algumas mudanças de versão 1 do script. Primeiro,
notar que temos uma lista de coleção do tipo MyCollectionData . este
é o conjunto que vai ser utilizado para armazenar os itens coleccionáveis.
A segunda adição é o OnTriggerEnter () função. Gostaríamos
gostaria de lidar com a colisão neste script particular, porque ele vai fazer
mais fácil para nós para lidar com os dados para este cenário particular. No
função, estamos verificando para ver quem temos colidiu com. Isto é
feito através da verificação da Tag propriedade do jogo objetar que o colisor
pertence a. Se o objeto é marcado como MyCollectable , então extrair o
Componente MyCollectable do Object Game. Este componente é
basicamente o MyCollectable.cs script que está ligado ao pré-fabricada cubo.

página 99
Vahé Karamian
85
Uma vez, os componentes são recuperados, criamos um MyCollectableData
opor-se a copiar o ID eo tamanho recuperado do MyCollectable
Componente. Este objeto, é então armazenado em nossa lista coleção chamada
myCollection . Uma vez que tenhamos recuperado com segurança os dados, que chamamos de De-
stroy () função que irá destruir o objeto jogo de cena.
O que temos feito é muito simples, mas muito poderoso, uma vez que
perceber como aplicá-la para projetos maiores e casos de uso. Não estamos concluir sua
ished ainda, precisamos ser capazes de recuperar os itens e recriá-las em
o mundo em outro local. Precisamos agora de conceber e implementar
a mecânica para lidar com o próximo cenário.
Descarregamento Nossa coleção
Precisamos identificar um local para o nosso descarregamento da recolhido
objeto. Usando um cilindro primitivo , podemos marcar uma área onde após a
jogador tenha coletado todos os itens colecionáveis pode descarregar. Assim, na cria- desenhador
comeu um novo objeto de jogo do tipo cilindro e colocá-lo em algum lugar que
será acessível para o jogador. Meu projeto é semelhante ao seguinte:
Figura 34 - Plataforma Drop-Off
Então, nós introduzimos um novo objeto jogo que é uma representação
de uma plataforma para ser usado para a devolução dos itens coleccionáveis. Nós

página 100
Unity 3D - Jogo de Programação Intro
86
também precisa lidar com a detecção de colisão para este objeto. Desde que nós
estão manipulando o evento colisor na PlayerInput.cs roteiro, podemos ex-
PAND na função para lidar com também o novo objeto jogo. Isso seria
faz sentido, uma vez que os dados que precisam acessar para os cubos também é
armazenado na mesma classe.
Portanto, tudo o que precisamos fazer tecnicamente é criar um único Tag para o
identificação da plataforma, e implementar o código para lidar com o
de colisão e a criação dos cubos no local apropriado. eu estou indo
para chamar a tag DropOffZone .
Vamos ir em frente e juntar tudo e ver como ele vai
trabalho. O que se segue é uma lista de PlayerInput.cs modificado para atender a nossa
novos critérios.
usando UnityEngine;
utilizando System.Collections.Generic;
classe pública PlayerInput : MonoBehaviour {
pública Lista < MyCollectableData > myCollection = nova Lista < MyCollecta-
bleData > ();
pública de materiais CubeMaterial;
anular Awake ()
{
// Certifique-se que comece a limpo
este .myCollection.Clear ();
}
// Use isso para inicialização
vazio Iniciar () {
}
// Update é chamado uma vez por quadro
vazio Update () {
// Código para o movimento do jogador (CP) para a frente
se ( Input .GetKey ( KeyCode .UpArrow))
{
este .transform.Translate ( Vector3 .forward * Tempo .deltaTime);
}
// Código para o movimento do jogador (CP) para trás
se ( Input .GetKey ( KeyCode .DownArrow))
{
este .transform.Translate ( Vector3 .Contra * Tempo .deltaTime);
}
// Código para o movimento do jogador (CP) esquerda

página 101
Vahé Karamian
87
se ( Input .GetKey ( KeyCode .LeftArrow))
{
este (.transform.Rotate Vector3 .Até, -5);
}
// Código para o movimento do jogador (CP) à direita
se ( Input .GetKey ( KeyCode .RightArrow))
{
este (.transform.Rotate Vector3 .Até, 5);
}
}
// Essa função manipula a colisão de aceleradores como um gatilho
vazio OnTriggerEnter ( Collider c)
{
Se (c.tag.Equals ( "MyCollectable" ))
{
var recolher = c.gameObject.GetComponent < MyCollectable > ();
MyCollectableData dados = novas MyCollectableData ();
data.ID = collect.ID;
data.size = collect.size;
este .myCollection.Add (dados);
Destroy (c.gameObject);
}
Se (c.tag.Equals ( "DropOffZone" ))
{
Se ( este .myCollection.Count> 2)
{
Vector3 centro = c.transform.position;
int index = 1;
foreach ( var d neste .myCollection)
{
Vector3 pos = CirclePath (centro, 1.0f, index);
Índice ++;
Quaternion rot = Quaternion .FromToRotation ( Vector3 .forward,
Centro - pos);
GameObject tmp = GameObject .Instantiate ( GameObject .Cre-
atePrimitive ( PrimitiveType .Cube),
pos, rot) como GameObject ;
tmp.transform.localScale = new Vector3 (d.size, d.size,
d.size);
tmp.GetComponent < Renderer > () Material =. presente .CubeMaterial;
}
}
}
}

página 102
Unity 3D - Jogo de Programação Intro
88
// Função para colocar a posição calcule do próximo item de torno
// Um caminho circular.
Vector3 CirclePath ( Vector3 center, flutuador raio, int id)
{
flutuador ang = 90 * id; //Random.value * 360;
Vector3 pos;
pos.x = center.x + raio * Mathf .Sin (ang * Mathf .Deg2Rad);
pos.z = center.z + raio * Mathf .Cos (ang * Mathf .Deg2Rad);
pos.y = center.y + 1;
voltar pos;
}
}
Código Bloco 21 - PlayerInput.cs Ver. 3
No OnTriggerEnter () função, nós adicionamos uma nova condição
para o DropOffZone plataforma. Se estamos na plataforma, o código
verifica para ver se temos recolhido todos os itens colecionáveis. Uma vez o
condição for verdadeira, então começamos o processo de descarregamento / re-criação
os GameObjects na ordem de cobrança em um caminho circular em torno do
centro da plataforma. A função CirclePath () é usada para calcular
a posição da próxima colecionável para descarga.
Figura 35 - Drop Off Zona em ação

página 103
Vahé Karamian
89
Note-se que no foreach circuito, calcula-se a posição do
objecto a ser colocado através do CirclePath () função, seguido pela
rotação do objecto. Uma vez que o cubo primitiva é instanciado usando o
dados de posição e rotação, usamos o tamanho valor armazenado nas MyCol-
lectableData objeto.
Ordenação e Matching
Nós completamos a implementação de busca e collect-
ing do objeto jogo e, portanto, de ter sido dada uma simples
exemplo dos dois mecânicos. O próximo passo é a concepção de correspondência e
encomenda. Manter as coisas simples para fins de demonstração, podemos
pedir ao jogador para clicar sobre o objeto do jogo do menor para o maior,
isso vai entrar em ressonância com o ato de ordenação sem torná-lo muito com-
plex. Podemos usar uma estrutura de dados Stack
13
para implementar este recurso.
A razão pela qual nós estamos usando uma pilha para a estrutura de dados, é porque
ele se encaixa o efeito.
Figura 36 - Representação visual de uma pilha
Nós só pode inserir a partir do topo, e antes de inserir a próxima
valor, podemos espreitar a pilha e ver se o valor superior atualmente no
pilha é maior do que ou menor do que o valor a ser inserido. Baseado em
o resultado então podemos decidir o que fazer a seguir. Isso fará com que mais
sentido quando olhamos para o código.
13
Uma pilha é uma estrutura de dados básica que pode ser logicamente pensado como estrutura
representam linear
tada por uma pilha física real ou pilha, uma estrutura onde a inserção e exclusão de itens leva
colocar em uma extremidade chamado topo da pilha.

página 104
Unity 3D - Jogo de Programação Intro
90
As primeiras coisas a fazer é criar uma classe pilha. O código a seguir
é uma lista de nossa classe:
usando UnityEngine;
usando System.Collections;
classe pública MyStack {
private int index;
private ArrayList pilha;
pública MyStack ()
{
este .STACK = new ArrayList ();
index = -1;
}
int pública COUNT
{
obter { return este .stack.Count; }
}
public void push ( objeto de dados)
{
este .stack.Add (dados);
este .index ++;
}
objeto público pop ()
{
objeto o = este .STACK [índice];
este .stack.RemoveAt (index);
este .index--;
devolver o;
}
public void clear ()
{
este .stack.Clear ();
este .index = -1;
}
objeto pública espiada ()
{
devolver este .STACK [ este .index];
}
}
Código Bloco 22 - Estrutura de dados Stack

página 105
Vahé Karamian
91
Como você pode ver, a implementação de uma estrutura de dados Stack é
bastante simples e direto.
Agora podemos ir em frente e realmente implementar a lógica do jogo de
lidar com a correspondência e encomendas. Aqui está a lista para PlayerInput.cs
com as novas atualizações:
usando UnityEngine;
utilizando System.Collections.Generic;
classe pública PlayerInput : MonoBehaviour {
pública Lista < MyCollectableData > myCollection = nova Lista < MyCollecta-
bleData > ();
pública de materiais CubeMaterial;
pública MyStack pilha = new MyStack ();
bool privada MATCH = false ;
anular Awake ()
{
este .match = false ;
// Certifique-se que comece a limpo
este .myCollection.Clear ();
}
// Use isso para inicialização
vazio Iniciar () {
}
// Update é chamado uma vez por quadro
anular Update ()
{
se (! este .match)
{
// Código para o movimento do jogador (CP) para a frente
se ( Input .GetKey ( KeyCode .UpArrow))
{
este .transform.Translate ( Vector3 .forward * Tempo .deltaTime * 10);
}
// Código para o movimento do jogador (CP) para trás
se ( Input .GetKey ( KeyCode .DownArrow))
{
este .transform.Translate ( Vector3 .Contra * Tempo .deltaTime * 10);
}
// Código para o movimento do jogador (CP) esquerda
se ( Input .GetKey ( KeyCode .LeftArrow))
{
este (.transform.Rotate Vector3 .Até, -5);
}

página 106
Unity 3D - Jogo de Programação Intro
92
// Código para o movimento do jogador (CP) à direita
se ( Input .GetKey ( KeyCode .RightArrow))
{
este (.transform.Rotate Vector3 .Até, 5);
}
}
Se ( este .match)
{
#region RATO DE ENTRADA
se ( Input .mousePosition! = nulo && entrada .GetMouseButtonUp (0))
{
//Debug.Log("START JOGO >>> ");
RaycastHit selectedCollectable;
// Capturar a posição do mouse e lança um raio para ver o objeto
nós batemos
Ray ray = Câmara .main.ScreenPointToRay ( Input .mousePosition);
se ( Física .Raycast (ray, fora selectedCollectable, 200))
{
//Debug.Log("TAG="+selectedCollectable.transform.tag);
se (selectedCollectable.transform.tag.Equals ( "MyCollect-
capazes " ))
{
var recolher = selectedCollectable.transform.gameOb-
ject.GetComponent < MyCollectable > ();
MyCollectableData dados = novas MyCollectableData ();
data.ID = collect.ID;
data.size = collect.size;
MyCollectableData sd = NULL ;
// Pilha de seleção
Se (stack.COUNT> 0)
{
sd = ( MyCollectableData ) stack.peek ();
Se (sd.size <data.size)
{
stack.push (dados);
}
outro
{
Debug log ( "Desculpe Try Again ...!" );
stack.clear ();
}
}
outro
{
stack.push (dados);
}
}

página 107
Vahé Karamian
93
}
}
Se (stack.COUNT> = 3)
{
para ( int i = 0; i <= stack.COUNT + 1; i ++)
{
MyCollectableData d = ( MyCollectableData ) stack.pop ();
Debug log ( cadeia .format ( "Pop: {0}" , d.size));
}
Debug log ( "GRANDE TRABALHO !!! Objectivo Concluído!" );
este .match = false ;
}
#endregion
}
}
// Essa função manipula a colisão de aceleradores como um gatilho
vazio OnTriggerEnter ( Collider c)
{
Se (c.tag.Equals ( "MyCollectable" ))
{
var recolher = c.gameObject.GetComponent < MyCollectable > ();
MyCollectableData dados = novas MyCollectableData ();
data.ID = collect.ID;
data.size = collect.size;
este .myCollection.Add (dados);
Destroy (c.gameObject);
}
Se (c.tag.Equals ( "DropOffZone" ))
{
Se ( este .myCollection.Count> 2)
{
Vector3 centro = c.transform.position;
int index = 1;
foreach ( var d neste .myCollection)
{
Vector3 pos = CirclePath (centro, 1.0f, index);
Índice ++;
Quaternion rot = Quaternion .FromToRotation ( Vector3 .forward,
Centro - pos);
GameObject tmp = GameObject .CreatePrimitive ( Primitive-
Tipo .Cube);
tmp.transform.position = pos;
tmp.transform.rotation = podridão;
tmp.transform.tag = "MyCollectable" ;

page 108
Unity 3D - Jogo de Programação Intro
94
tmp.transform.localScale = new Vector3 (d.size, d.size,
d.size);
tmp.GetComponent < Renderer > () Material =. presente .CubeMaterial;
// Anexar componente coleccionável, aplicam-se os dados
tmp.gameObject.AddComponent < MyCollectable > ();
tmp.gameObject.GetComponent < MyCollectable .> () ID = d.ID;
tmp.gameObject.GetComponent < MyCollectable > () size = d.size.;
}
// Tudo foi processado, começar combinando
este .match = verdadeiro ;
}
}
}
// Função para colocar a posição calcule do próximo item de torno
// Um caminho circular.
Vector3 CirclePath ( Vector3 center, flutuador raio, int id)
{
flutuador ang = 90 * id; //Random.value * 360;
Vector3 pos;
pos.x = center.x + raio * Mathf .Sin (ang * Mathf .Deg2Rad);
pos.z = center.z + raio * Mathf .Cos (ang * Mathf .Deg2Rad);
pos.y = center.y + 1;
voltar pos;
}
}
Código Bloco 23 - PlayerInput.cs Ver. 4
Você pode notar algumas mudanças no código como eu listados n Código
Bloco 23 - PlayerInput.cs Ver. 4. Primeiro aviso de que na DropOffZone
detecção de colisão, estamos fazendo várias tarefas novas e importantes.
1. Nós percorrer nossa lista de colecionáveis.
2. Para cada colecção que está sendo processado, calculamos o po-
sição e rotação com a ajuda de CirclePath () função.
3. Uma vez que a posição, a rotação ea escala foram aplicadas,
que começar a construir os próximos propriedades, ou seja, Tag .
4. Uma vez que este é um GameObject recém-criado que precisa represen-
ressentir-se da colecção original, precisamos também adicionar o
MyCollectable componentes a ele.
5. Depois de anexar o componente, é preciso definir o va- dados
UEs que em seguida vai ser utilizados numa fase posterior.
6. Finalmente, definir um valor bandeira this.MATCH para true.
página 109
Vahé Karamian
95
A próxima grande mudança está no Update () função. Precisamos de uma maneira de
detectar se tivermos descarregado com sucesso nossos objetos colecionáveis para o
DropOffZone . Isso é feito por um booleano nomes bandeira JOGO .
Se o sinalizador é definido como verdadeiro, o programa vai para a segunda fase do
o jogo, a correspondência e encomendas. O objetivo aqui é para que o usuário
marque as caixas de colecionáveis descarregadas na ordem do menor para o
O maior.
Usamos Camera.main.ScreenToRay () função para converter o
coordena mouse de um espaço 2D para um espaço 3D Ray objeto. o Ray
objeto é então usado pelo motor de física para lançar um raio usando o
Raycase () função. Esta função retorna informações sobre o primeiro
objetar que o raio colide com. Este é armazenado na selectedCollectable
variável. Se estamos a bater com sucesso o objeto jogo desejado, então nós
começar a receber os dados usando o getComponent () função para acessar o
MyCollectable , e armazená-lo em um novo MyCollectableData objeto.
Quando temos toda a informação que está procurando, nós utilizamos
Pilha a estrutura de dados para iniciar a inserção nossos pontos de dados para ele. Obvi-
ously há alguns controlos e verificações que precisam ser feitas
antes de determinar se a colecção seleccionada vai ser empurrado
para a pilha, ou se vamos ter que começar o processo de seleção
denovo. Se você seguiu as instruções, até agora, você
deve ter tudo funcionando corretamente. Nós não implementar qualquer
interface do usuário neste momento. A razão principal é que estamos trabalhando no
lógica de código e nós estamos usando a janela do console para a saída dos resultados
para o gabarito.
Figura 37 - Console janela mostrando Pilha Ouput após a ordem de sucesso

página 110
Unity 3D - Jogo de Programação Intro
96
Neste ponto, nós completamos os objetivos que estabelecemos para
-nos para o nível 1. Vamos começar a pensar sobre o Nível 2.
Desenvolvimento de Nível 2
No nível 2, vamos implementar a mecânica de tempo , arriscando ,
misturando e progredindo . Nós podemos criar um nível que irá ser composta
por várias salas.
Figura 38 - apenas um conceito para o Nível 2
A ideia básica subjacente nível 2 será para o jogador deve ser capaz de
completar os objetivos com base em alguns critérios. Por exemplo, o jogador
terá de ser capaz de visitar todos os três quartos dentro do nível para completar
o principal objetivo do nível. No entanto, ele / ela não pode diretamente o acesso

página 111
Vahé Karamian
97
os quartos. Eles primeiro tem que interagir com um gerador aleatório que será
ditar a sala que eles precisam para atender.
Os três quartos vão ser identificados por suas cores exclusivas:
Vermelho, Verde e Azul. Quando o jogador interage com o dispositivo de selecção aleatória,
o randomizer irá exibir uma cor específica, quando a cor tem sido
selecionado, em seguida, o usuário terá que encontrar o quarto em uma determinada quantidade de
Tempo. Cada quarto terá uma porta de correr que se abre somente se o con-
condições sejam atendidas.
Figura 39 - Nível 2 design
Para fazer com que o nosso novo trabalho de nível, precisamos implementar algumas novas
Unid. O primeiro seria um modelo 3D que representa o nosso quarto. eu tenho
SketchUp usado para modelar o meu quarto, pois é um programa muito fácil para não-
designer para pick-up e trabalhar. O modelo é apresentado na Figura
40, é um quarto muito simples, com as seguintes dimensões Largura e
Comprimento de 4 metros, por uma altura de 3 metros. A abertura para o quarto
é de 2 metros de largura. As dimensões são importantes quando você está projetando

página 112
Unity 3D - Jogo de Programação Intro
98
seus modelos 3D, porque eles irão refletir em Unity 3D baseado na unidade
de medição
14
.
Figura 40 - Modelo 3D quarto
Observe, que eu não tenha aplicado quaisquer texturas para o modelo. eu mantive
coisas muito simples, como o propósito deste exemplo não é a modelagem 3D
ing mas a programação. Uma vez que importar o modelo em Unity, você
precisa ter certeza de que o Gerar Colliders opção for marcada na
modelo. Isto é importante para a detecção de colisão.
Figura 41 - Modelo 3D na cena Unity
14
Unity 3D usa o sistema métrico, por isso é melhor para fazer seus modelos 3D na métrica
sistema. Isso vai ajudar a importação e dimensionamento de seus modelos dentro da unidade muito
mais fácil.

página 113
Vahé Karamian
99
Figura 42 - Hierarquia de quarto
No modo de design, você
pode ir em frente e adicionar um
nova luz do ponto como um
criança com o modelo, cen-
naipes-lo na sala. Cada
sala terá um
Ponto de Luz com um
cor única de vermelho,
verde ou azul.
Você vai precisar adicionar
outra GameObject , um
cubo que irá representar
a porta de correr.
Você vai precisar para jogar
com o colisor de
torná-lo um pouco maior
do que a porta real.
Vamos ser também a adição de dois novos scripts para lidar com o ran-
domization e selecção da sala, e o deslizamento da porta para
a sala. Os dois scripts são chamados RoomSelection.cs e Sliding-
Door.cs . O RoomSelection script está anexado ao GameObject
representando o randomizer na cena.
Aqui está a lista para RoomSelection.cs :
usando UnityEngine;
usando System.Collections;
classe pública RoomSelection : MonoBehaviour
{
pública GameObject playerCharacter = NULL ;
// Use isso para inicialização
anular Iniciar ()
{
// Se o characte jogador não está definido em tempo de design
// Atribui-lo durante o tempo de execução antes do jogo começar
Se ( esse .playerCharacter == nulo )

page 114
Unity 3D - Jogo de Programação Intro
100
{
este .playerCharacter = GameObject .FindGameObjectWithTag ( "Player" )
como GameObject ;
}
}
// Update é chamado uma vez por quadro
anular Update ()
{
este .transform.Rotate ( novo Vector3 (1, 1, 1), 1.0f);
// Distância de seleção entre este objeto e o personagem do jogador
flutuador distância = Vector3 .distance ( este .transform.position, este .play-
erCharacter.transform.position);
Se (distância <2.0F)
{
#region RATO DE ENTRADA
se ( Input .mousePosition! = nulo && entrada .GetMouseButtonUp (0))
{
int color = Aleatório .Range (0, 3);
interruptor (cor)
{
caso 0:
{
este .transform.GetComponent < Renderer > (). material.color
= Cor .blue;
este .playerCharacter.GetComponent < PlayerIn-
colocar .> () ROOM_SELECTION = 0;
break;
}
case 1:
{
este .transform.GetComponent < Renderer > (). material.color
= Cor .Red;
este .playerCharacter.GetComponent < PlayerIn-
colocar .> () ROOM_SELECTION = 1;
break;
}
Caso 2:
{
este .transform.GetComponent < Renderer > (). material.color
= Cor .Green;
este .playerCharacter.GetComponent < PlayerIn-
colocar .> () ROOM_SELECTION = 2;
break;
}
}
}
#endregion
}
}
}
Código Bloco 24 - Sala de Seleção Listagem de código

página 115
Vahé Karamian
101
Este script basicamente transforma o GameObject que ele está ligado a em
a selecção aleatória. No nosso exemplo, ela está ligada a um cubo. Ele irá girar
o cubo em todos os três eixos. Ele também verificado para ver se o personagem do jogador
está dentro de uma determinada distância de si mesmo. O limite é definido como <2.0m.
Se a condição for satisfeita, então o jogador está autorizado a clicar no cubo. Cada
vez que o usuário clica no GameObject, um novo número aleatório é ge-
ciado entre 0 e 3.
 0: representa o quarto azul.
 1: representa o quarto vermelho.
 2: representa o quarto verde.
A instrução switch é usado para mudar a cor do material do
GameObject à respectiva cor para pista visual. Em seguida, ele acessa um
nova variável que foi definida na PlayerInput.cs script chamado
ROOM_SELECTION .
O próximo script que vamos olhar é SlidingDoor.cs :
usando UnityEngine;
usando System.Collections;
classe pública SlidingDoor : MonoBehaviour
{
int pública ROOM_NUMBER;
pública Transform doorTransform;
public float raiseHeight = 3F;
public float velocidade = 3F;
privada Vector3 _closedPosition;
// Use isso para inicialização
anular Iniciar ()
{
_closedPosition = transform.position;
}
vazio OnCollisionEnter ( Collision c)
{
se (c.transform.tag.Equals ( "Player" ))
{
se (! este .IsDoorOpen && (c.transform.GetComponent < PlayerIn-
colocar > (). ROOM_SELECTION == este .ROOM_NUMBER))
{
StopCoroutine ( "MoveDoor" );
Vector3 endpos = _closedPosition + nova Vector3 (0f, raiseHeight,
0f);

página 116
Unity 3D - Jogo de Programação Intro
102
StartCoroutine ( "MoveDoor" , endpos);
}
}
}
bool privada IsDoorOpen = false ;
IEnumerator MoveDoor ( Vector3 endPos)
{
flutuar t = 0f;
Vector3 startPos = doorTransform.position;
enquanto (t <1F)
{
t + = Tempo .deltaTime * velocidade;
doorTransform.position = Vector3 .Slerp (startPos, endPos, t);
deu return null ;
}
este .IsDoorOpen = verdadeiro ;
}
}
Código Bloco 25 - Porta de Correr Listagem de código
Este código é responsável pela abertura da porta com base em dois
condições:
1. O objeto jogo que colide com ele é o caracter do Jogador
ter.
2. O personagem do jogador ROOM_SELECTION é idêntico ao
o ROOM_NUMBER .
Isso é tratado pelo OnCollisionEnter () função. Nós estamos usando
esta função, porque nós queremos realmente o que representa GameObject
a porta ser sólida, ou seja, o jogador não pode passar através dele. em outra
palavras, o IsTrigger recurso no Component Collider é falso!
Observe que também estamos usando um co-rotina que realmente faz o
transformação na porta. Co-rotinas não são os mesmos como multi-
Threading. Atualizações normais co-rotina são executados após o Update () função
retornos à. A co-rotina é uma função que pode suspender a sua execução
( Rendimento ) até que os dados de instrução Rendimento acabamentos. Aqui está uma lista:
 rendimento , a co-rotina vai continuar depois de tudo Update () função
ções foram chamados no próximo quadro.
página 117
Vahé Karamian
103
 WaitForSeconds rendimento , continuar após um tempo especificado
atraso, afinal Update () funções foram chamados para o
quadro.
 rendimento WaitForFixedUpdate , continuar depois de tudo
FixedUpdate () foi chamado em todos os scripts.
 rendimento WWW , continuar após um download WWW tem com-
taram.
 StartCoroutine rendimento , as cadeias da co-rotina, e vontade
esperar para a co-rotina MyFunc para completar em primeiro lugar.
Neste ponto, nós estabelecemos a nossa estrutura principal para o nível 2.
Agora precisamos implementar os detalhes da mecânica do jogo. O primeiro
dos quais será um temporizador. O temporizador será definido quando o jogador clica
no dispositivo de selecção aleatória. Aqui estão os passos:
1. O temporizador será definido quando o jogador seleciona o randomizer
eo gerador aleatório seleciona uma sala / cor.
2. Contagem regressiva do temporizador começará imediatamente após a
seleção.
3. Se o jogador não é capaz de encontrar a sala durante o dado
tempo, o jogo vai ser longo.
4. Se o fizerem encontrar o quarto, o temporizador será reposto, e eles
terá de encontrar a próxima sala, indo de volta para o ran-
domizer.
Isto pode ser conseguido muito facilmente pela adição de algumas variáveis de
manter o controle do tempo no RoomSelection.cs scrip e também atualizar
o PlayerInput.cs roteiro com seu próprio conjunto de variáveis para determinar se
o jogador não conseguiu passar o nível, bem como o SlidingDoor.cs roteiro
para repor o temporizador quando o jogador encontra com êxito o quarto seleccionado
no prazo determinado.
usando UnityEngine;
usando System.Collections;
classe pública RoomSelection : MonoBehaviour
{
pública GameObject playerCharacter = NULL ;
// Use isso para inicialização
anular Iniciar ()

página 118
Unity 3D - Jogo de Programação Intro
104
{
// Se o characte jogador não está definido em tempo de design
// Atribui-lo durante o tempo de execução antes do jogo começar
Se ( esse .playerCharacter == nulo )
{
este .playerCharacter = GameObject .FindGameObjectWithTag ( "Player" )
como GameObject ;
}
}
// MYtime será usada para dar a quantidade de tempo em segundos
// Para o jogador para encontrar o quarto !!!
public float Mytime = 33.0f;
private float endTime = 0.0f;
// Update é chamado uma vez por quadro
anular Update ()
{
este .transform.Rotate ( novo Vector3 (1, 1, 1), 1.0f);
Se ( esse .endTime> Tempo .time)
{
Debug log ( "Temporizador iniciado !!!" + Mathf .CeilToInt ( este .endTime -
Tempo .time) .ToString ());
}
else if ( esta .endTime == 0.0f)
{
; // Não fazer nada
}
outro
{
Debug log ( "Time Ended !!!" );
este .playerCharacter.GetComponent < PlayerInput .> () game_over = verdadeiro ;
}
// Distância de seleção entre este objeto e o personagem do jogador
flutuador distância = Vector3 .distance ( este .transform.position, este .play-
erCharacter.transform.position);
Se (distância <2.0F)
{
#region RATO DE ENTRADA
se ( Input .mousePosition! = nulo && entrada .GetMouseButtonUp (0))
{
int color = Aleatório .Range (0, 3);
interruptor (cor)
{
caso 0:
{
este .transform.GetComponent < Renderer > (). material.color
= Cor .blue;
este .playerCharacter.GetComponent < PlayerIn-
colocar .> () ROOM_SELECTION = 0;
break;
}
case 1:

página 119
Vahé Karamian
105
{
este .transform.GetComponent < Renderer > (). material.color
= Cor .Red;
este .playerCharacter.GetComponent < PlayerIn-
colocar .> () ROOM_SELECTION = 1;
break;
}
Caso 2:
{
este .transform.GetComponent < Renderer > (). material.color
= Cor .Green;
este .playerCharacter.GetComponent < PlayerIn-
colocar .> () ROOM_SELECTION = 2;
break;
}
}
// Inicia temporizador
este .endTime = este .myTime + Tempo .time;
}
#endregion
}
}
public void ResetTimer ()
{
este .endTime = 0.0f;
}
}
Código Bloco 26 - RoomSelection script de atualização para incluir Temporizador
Observe que nós introduzimos duas variáveis no script, endTime e
MyTime . A variável MYtime é usado como a quantidade de tempo em segundos
o jogador tem de executar uma tarefas específicas. A variável endTime está definido
como uma combinação do tempo de execução do jogo, feita a partir de time.time
15
adicionada com o Mytime valor. Esta é definida, quando o usuário seleciona o ran-
domizer.
No Update () função, há um bloco condicional verificando para
ver se a variável endTime é maior do que time.time . Se essa condição é
satisfeitas, então ainda estamos dentro do prazo e que o jogador pode fazer o que ele
ou ela agrada no nível. Uma vez que a condição já não é válida, então é
usamos o PlayerCharacter objeto para extrair o PlayerInput objeto
e definir o game_over variável para true. Isto indica que o jogador
15
Este é o tempo em segundos desde o início do jogo.

página 120
Unity 3D - Jogo de Programação Intro
106
não foi capaz de completar sua tarefa corretamente. O que se segue é uma snip-
estimação do modificações / modificação feita ao PlayerInput.cs script:
usando UnityEngine;
utilizando System.Collections.Generic;
classe pública PlayerInput : MonoBehaviour {
pública Lista < MyCollectableData > myCollection = nova Lista < MyCollecta-
bleData > ();
pública de materiais CubeMaterial;
pública MyStack pilha = new MyStack ();
bool privada MATCH = false ;
#region variáveis para o nível 2
int pública ROOM_SELECTION;
bool pública game_over;
#endregion
anular Awake ()
{
este .ROOM_SELECTION = -1;
este .GAME_OVER = false ;
este .match = false ;
// Certifique-se que comece a limpo
este .myCollection.Clear ();
}
// Use isso para inicialização
vazio Iniciar () {
}
private float VELOCIDADE = 2.0F;
// Update é chamado uma vez por quadro
anular Update ()
{
se (! este .GAME_OVER)
{
se (! este .match)
{
...
}
Se ( este .match)
{
#region RATO DE ENTRADA
se ( Input .mousePosition! = nulo && entrada .GetMouseButtonUp (0))
{

página 121
Vahé Karamian
107
//Debug.Log("START JOGO >>> ");
RaycastHit selectedCollectable;
...
Se (stack.COUNT> = 3)
{
para ( int i = 0; i <= stack.COUNT + 1; i ++)
{
MyCollectableData d = ( MyCollectableData ) stack.pop ();
Debug log ( cadeia .format ( "Pop: {0}" , d.size));
}
Debug log ( "GRANDE TRABALHO !!! Objectivo Concluído!" );
este .match = false ;
}
#endregion
}
}
}
// Essa função manipula a colisão de aceleradores como um gatilho
vazio OnTriggerEnter ( Collider c)
{
Se (c.tag.Equals ( "MyCollectable" ))
{
...
}
}
// Função para colocar a posição calcule do próximo item de torno
// Um caminho circular.
Vector3 CirclePath ( Vector3 center, flutuador raio, int id)
{
flutuador ang = 90 * id; //Random.value * 360;
Vector3 pos;
pos.x = center.x + raio * Mathf .Sin (ang * Mathf .Deg2Rad);
pos.z = center.z + raio * Mathf .Cos (ang * Mathf .Deg2Rad);
pos.y = center.y + 1;
voltar pos;
}
}
Código Bloco 27 - PlayerInput.cs Atualização para incluir Temporizador Estado
Eu não fornecer toda a listagem do script como já temos
feito nas seções anteriores do livro. As atualizações de chave / modifi-
cátions que fizemos para o script foi negrito enfrentou. Duas variáveis,
ROOM_SELECTION e game_over . É claro que eles são usados
para. ROOM_SELECTION é usado para guardar quais o quarto das necessidades de jogador
de encontrar, e game_over determina se o jogador foi atingido e
portanto, perdeu o jogo.

página 122
Unity 3D - Jogo de Programação Intro
108
O próximo script que deve dar uma olhada é o SlidingDoor.cs
script. Este script é realmente usado para repor o temporizador se o jogador encontra
a resposta correta e entra nele. Como listando o código anterior, eu vou
só fazem listagem parcial do código para demonstrar as modificações.
usando UnityEngine;
usando System.Collections;
classe pública SlidingDoor : MonoBehaviour
{
int pública ROOM_NUMBER;
pública Transform doorTransform;
public float raiseHeight = 3F;
public float velocidade = 3F;
privada Vector3 _closedPosition;
pública GameObject roomSelection;
// Use isso para inicialização
anular Iniciar ()
{
Se ( esse .roomSelection == nulo )
{
este .roomSelection = GameObject .Find ( "RoomSelection" ) como GameOb-
jecto ;
}
_closedPosition = transform.position;
}
vazio OnCollisionEnter ( Collision c)
{
se (c.transform.tag.Equals ( "Player" ))
{
...
// Reiniciar o temporizador uma vez que o jogador está no quarto
este .roomSelection.GetComponent < RoomSelection > () ResetTimer ().;
Debug log ( "O temporizador foi reposto!" );
}
}
}
bool privada IsDoorOpen = false ;
IEnumerator MoveDoor ( Vector3 endPos)
{
...
}
}
Código Bloco 28 - atualização SlidingDoor.cs Script para a função Temporizador

página 123
Vahé Karamian
109
Há duas novas tarefas que estão sendo executadas no atualizada
roteiro, o primeiro é na Iniciar () função. Nós identificar e localizar o
GameObject com o nome ou ID do RoomSelection , e armazenar uma rência
rência à GameObject para usá-lo em um momento posterior. A segunda adição
neste script é o chamado do ResetTimer () função através da
RoomSelection GameObject RoomSelection objeto no OnColli-
sionEnter () função.
Neste ponto temos implementado os fundamentos, mas precisamos
para manter alguma forma pontuação para o jogador. Em outras palavras, precisamos de uma
maneira
para identificar quais quartos o jogador tenha visitado, e quando todos os quartos
foram visitados pelo jogador, que teria completado o nível.
Nós podemos utilizar nossa estrutura de dados Pilha de superar este obstáculo. Nós
pode empurrar cada quarto para a pilha quando o jogador os visita e
quando todos os três quartos foram visitadas, em seguida, o jogador ganha o nível.
Este cenário e atualiza dados seria tratado pela Sliding-
Door.cs script eo PlayerInput.cs script. O SlidingDoor classe irá
chamar o método definido no PlayerInput classe para empurrar os dados dos quartos
na pilha.
O segmento de código que precisa ser mudado em SlidingDoor.cs é
listado abaixo:
vazio OnCollisionEnter ( Collision c)
{
se (c.transform.tag.Equals ( "Player" ))
{
se (! este .IsDoorOpen && (c.transform.GetComponent < PlayerIn-
colocar > (). ROOM_SELECTION == este .ROOM_NUMBER))
{
...
// Reiniciar o temporizador uma vez que o jogador está no quarto
este .roomSelection.GetComponent < RoomSelection > () ResetTimer ().;
// Enviar os dados dos quartos para a pilha
c.gameObject.GetComponent < PlayerInput > () RoomVisited (. presente );
Debug log ( "O temporizador foi reposto!" );
}
}
}
Código Bloco 29 - Quarto Visitou além de roteiro SlidingDorr.cs

página 124
Unity 3D - Jogo de Programação Intro
110
As mudanças que precisamos fazer no PlayerInput.cs roteiro estão listados
abaixo:
public void RoomVisited ( SlidingDoor quarto)
{
se (quarto! = NULL )
{
este .stack.push (quarto);
cadeia msg = cadeia .format ( "Room # {0} inserido, a contagem de pilha = {1}" ,
room.ROOM_NUMBER, este .stack.COUNT);
Debug log (msg);
Se ( este .stack.COUNT> = 3)
{
Debug log ( "VOCÊ GANHA !!!" );
este .GAME_OVER = verdadeiro ;
}
}
}
Código Block 30 - Adição de PlayerInput.cs script para lidar com salas visitadas
Portanto, agora temos visto alguns tipos diferentes de mecânica de jogo im-
plementations. Embora os exemplos fornecidos são muito simplista, na
finalidade, eles fazem demonstrar os principais conceitos e ideias da indicação
mecânica viduais.
Desenvolvimento de Nível 3
No nível 3, nós estamos indo para ilustrar a progredir, capturando / con-
quering e avançando mecânica de jogo. Nós também provavelmente
combinar algumas das outras mecânicas de jogo que temos visto até agora em
combinação para criar um nível que é um pouco mais sofisticado e in-
vidos.
Um dos meus gêneros jogo favorito é o Real Time Strategy. Dois dos meus
favoritos foram Age of Empires I, II, III, e Command and Conquer .
Uma das principais razões que eu amo jogos RTS é o fato de que você realmente
tem que pensar e usar um monte de logística para planejar sua estratégia e ser
capaz de derrotar o adversário. Eu sempre desenhar uma linha entre o jogo de
Xadrez e RTS, a diferença é que em um jogo de xadrez os jogadores
se revezam para fazer os seus movimentos, para que eles tenham tempo para pensar no futuro
alguns
passos. Em um RTS, seu adversário pode atacar a qualquer momento e de
qualquer direção e, com armas e recursos superiores !!!
página 125
Vahé Karamian
111
Em uma porca shell, cada um desses jogos, o jogador é obrigado a recolher
recursos, construir um exército, construir a sua base e as estruturas necessárias, pro-
Congresso através das diferentes fases de modernização das suas estruturas e
unidades, e, ao mesmo tempo que mantém a sua base. Em cima dessas ac-
ções, existe um elemento de tempo para a recolha e a criação de
recursos e unidades. Como você pode dizer por agora, o design do jogo e me-
cânica são bastante envolvidos e precisam ser planejadas muito bem.
Não temos o tempo nem os recursos para realizar tal tarefa
para o nível 3. Portanto, vamos fazer uma versão simplificada de um
RTS tipo de jogo. Para realizar nossos objetivos, podemos desenhar um esboço de
as tarefas que o usuário precisará preencher no nível 3.
Aqui está um breve resumo:
1. O jogador irá começar com uma quantidade definida de recursos quando
o jogo começa.
2. O jogador terá que construir uma instalação de recolha.
3. O jogador terá de criar uma unidade de coletor.
4. O jogador terá de identificar a localização de recursos para
ser recolhidos.
5. O jogador terá de atribuir o coletor para o recurso
a recolher.
6. Enquanto a unidade (s) colector estão coletando, o jogador irá
precisa para explorar o terreno para identificar o inimigo e matá-lo.
7. O jogador terá de evitar ser morto pelo inimigo
e ou outros objetos prejudiciais ao jogador.
Para manter as coisas simples, tanto o jogador como o inimigo vai começar
com a mesma quantidade de recursos. Neste caso particular, haverá
dois tipos de recursos, um deles seria mineração de ouro, ea
outro seria balas. No entanto, o problema aqui é que, para que o
player / inimigo acumular balas, eles terão de continuamente col-
ouro lect.
A recolha do ouro também irá basear-se num tempo específico.
Isto irá forçar o jogador a ser mais cauteloso sobre como utilizar os recursos

página 126
Unity 3D - Jogo de Programação Intro
112
balas, muitos tiros sem sucesso irá colocar o jogador em risco de ser
mortos pelo inimigo.
Para que nós para fazer isso, seria preciso criar algum
novos scripts. Precisaríamos de um roteiro para representar a unidade de armazenamento, nós
seria necessário um roteiro para representar a unidade de coletor, o que nos obrigaria
um script para representar a unidade de recurso. Nós também precisamos criar dois simples
prefabs para representar a nossa Unidade de Armazenamento e Unidade Collector .
Figura 43 - Projeto de amostra de unidades de armazenamento e colecionador
Não vou entrar em detalhes de como criar o armazenamento e Col-
lector Unidades, como deveriam ser muito elementar para você até agora.
Da mesma forma, o jogador personagem e objeto do jogo do recurso. A chave é a
conexão entre os GameObjects e sua interação através do
scripts.
Vamos começar a olhar para a unidade de armazenamento em primeiro lugar. A função de um
armazenamento
unidade de idade é armazenar recursos para os fins do jogo. Poderia ser
usada para armazenar qualquer tipo de recurso, no entanto, geralmente, não são diferentes

página 127
Vahé Karamian
113
tipos de unidades de armazenamento de diferentes tipos de recursos. No nosso caso, nós
são manter as coisas muito simples, portanto, a unidade de armazenamento será armazenamento
ing apenas um tipo de recurso, uma vez que só temos um tipo de recurso
para armazenar, para começar!
Em segundo lugar, a unidade de armazenamento será automaticamente criar o primeiro Col-
Unidade lector uma vez que tenha sido colocado dentro do mundo 3D. Portanto, o
Unidade de armazenamento é responsável por manter o controle da Unidade de coletor bem
como ter certeza que a Unidade de coletor sabe que a Unidade de Armazenamento ele pertence
para! Finalmente, a Unidade de Armazenamento também precisará ter uma referência para o
personagem do jogador para que ele possa atualizar as estatísticas sobre o jogador.
O código que nos ajuda a alcançar esses resultados é listado abaixo:
usando UnityEngine;
usando System.Collections;
classe pública MyStorage : MonoBehaviour
{
pública GameObject myCollector;
privada GameObject collectorObj;
privada GameObject playerCharacter;
// variáveis para temporizador
public float Mytime = 3.0f;
private float endTime = 0.0f;
// Use isso para inicialização
anular Iniciar ()
{
Vetor3 POS = novo vetor3 ( este .transform.position.x + 1, 2,
este .transform.position.z + 1);
este .collectorObj = GameObject .Instantiate ( este .myCollector, pos,
este .transform.rotation) como GameObject ;
este .collectorObj.GetComponent < MyCollector > (). MyStorage = este .gameOb-
jecto;
este .playerCharacter = GameObject .FindGameObjectWithTag ( "Player" ) como
GameObject ;
}
// Update é chamado uma vez por quadro
anular Update ()
{
Se ( esse .endTime> Tempo .time)
{
// Vamos colocar algum código aqui para visualmente carregamento de exibição
}

página 128
Unity 3D - Jogo de Programação Intro
114
else if ( esta .endTime == 0.0f)
{
; // Não fazer nada
}
outro
{
este .endTime = 0.0f;
este .collectorObj.GetComponent < MyCollector .> () GOTO_RESOURCE = verdadeiro ;
// Adiciona bala personagem do jogador
este .playerCharacter.GetComponent < PlayerInput > () NUM_BULLETS + = 1.;
}
}
// Essa função manipula a colisão de aceleradores como um gatilho
vazio OnCollisionEnter ( Collision c)
{
Se (c.transform.tag.Equals ( "CollectorUnit" ))
{
c.transform.GetComponent < MyCollector .> () GOTO_STORAGE = false ;
// Inicia temporizador
este .endTime = este .myTime + Tempo .time;
}
}
}
Código Bloco 31 - MyStorage.cs versão inicial
Quando você lê o código, você vai notar que nesse Iniciar () função
ção que instanciar um CollectorUnit objeto e atribuir o StorageUnit
objeto como uma referência para que ele sabe para onde voltar depois ele tem
recolheu os recursos. A próxima coisa que fazer é ter uma referência para o
personagem do jogador.
O Update () função definida no MyStorage classe só é utilizada
quando a Unidade de coletor retorna de volta para ele. É desencadeada pelos OnCol-
lissionEnter () função onde o timer para descarregar os recursos chegar
conjunto. O temporizador é então verificado no Update () função para o descarregamento
ing e reencaminhamento da Unidade de coletor de volta para a localização de recursos.
Isso nos faz dar uma olhada no próximo item de interesse, o Col-
Unidade lector. A Unidade Collector neste cenário é apenas preocupado com
saber onde o recurso está localizado para que ele possa ir e recolher o
recursos, e que unidade de armazenamento a que pertence, para que ele pode seguramente

page 129
Vahé Karamian
115
voltar e descarregar os recursos. Ele também precisa saber quanto re-
fontes que tenha recolhido, esta variável está definida, mas não é usado neste
ponto. Além disso, existem dois sinalizadores críticos que definem o estado do col-
lector, é qualquer um que vai para a localização de recursos para o carregamento, ou é
ir para a unidade de armazenamento para a descarga.
A listagem para os MyCollector.cs está abaixo:
usando UnityEngine;
usando System.Collections;
classe pública MyCollector : MonoBehaviour
{
pública GameObject myResource;
públicas GameObject MyStorage;
bool pública GOTO_RESOURCE;
bool pública GOTO_STORAGE;
int pública UNINTS_COLLECTED;
// Use isso para inicialização
anular Iniciar ()
{
este .myResource = GameObject .FindGameObjectWithTag ( "ResourcePlayer" )
como GameObject ;
este .GOTO_RESOURCE = verdadeiro ;
este .GOTO_STORAGE = false ;
este .UNINTS_COLLECTED = 0;
}
// Update é chamado uma vez por quadro
anular Update ()
{
Se ( este .GOTO_RESOURCE)
{
// Goto a localização dos recursos para a coleta
Vector3 refillHeading = este .myResource.transform.position -
este .transform.position;
refillHeading.Normalize ();
// Usar a função Quaternion Slerp para fazer transição suave ...
este .transform.rotation =
Quaternion .Slerp (transform.rotation,
Quaternion .LookRotation (refillHeading), 10 * Tempo .deltaTime);
este .transform.Translate ( Vector3 .forward * Tempo .deltaTime);
}
Se ( este .GOTO_STORAGE)

página 130
Unity 3D - Jogo de Programação Intro
116
{
Vector3 refillHeading = este .myStorage.transform.position -
este .transform.position;
refillHeading.Normalize ();
// Usar a função Quaternion Slerp para fazer transição suave ...
este .transform.rotation =
Quaternion .Slerp (transform.rotation,
Quaternion .LookRotation (refillHeading), 10 *
Tempo .deltaTime);
este .transform.Translate ( Vector3 .forward * Tempo .deltaTime);
}
}
}
Código Bloco 32 - MyCollector.cs versão 1
Observando o código, você vai notar que a Unidade Collector encontra
onde o recurso para o jogador é, ele armazena e que, na sua memória. Desde
que acaba de ser inicializada pela unidade de armazenamento, o seu estado inicial seria
para ir e recolher recursos. Isto é definido na Iniciar () função.
O Update () função é apenas responsável por certificar-se de que a col-
lector está correctamente orientada, quer a localização de recursos, ou para o armazenamento
unidade. Muito simples e muito para a frente. A chave aqui é notar
que o estado do colector é alterada por forças externas!
A próxima peça do quebra-cabeça para completar o ciclo é o recurso.
Como foi concebido, o objeto de recurso é fixo e não pode ser movida
ou realocados. Também não criar qualquer coisa a partir de dentro, embora isto
pode ser algo que você pode querer fazer em um momento posterior. Assim, as principais tarefas
do objeto de recurso para saber quando o coletor chegou para col-
lect, e como alterar o estado do colector quando o tempo tem
vêm para retornar à base!
Aqui está uma lista para MyResource.cs script:
usando UnityEngine;
usando System.Collections;
classe pública MyResource : MonoBehaviour
{
pública GameObject collectorUnit;
// variáveis para temporizador

page 131
Vahé Karamian
117
public float Mytime = 3.0f;
private float endTime = 0.0f;
// Use isso para inicialização
anular Iniciar ()
{
}
// Update é chamado uma vez por quadro
anular Update ()
{
Se ( esse .endTime> Tempo .time)
{
// Vamos colocar algum código aqui para visualmente carregamento de exibição
}
else if ( esta .endTime == 0.0f)
{
; // Não fazer nada
}
outro
{
este .endTime = 0.0f;
este .collectorUnit.GetComponent < MyCollector .> () GOTO_STORAGE = verdadeiro ;
}
}
// Essa função manipula a colisão de aceleradores como um gatilho
vazio OnTriggerEnter ( Collider c)
{
Se (c.tag.Equals ( "CollectorUnit" ))
{
c.GetComponent < MyCollector .> () GOTO_RESOURCE = false ;
este .collectorUnit = c.gameObject;
// Inicia temporizador
este .endTime = este .myTime + Tempo .time;
}
}
}
Código Bloco 33 - MyResource.cs versão 1
O código que eu tenho mostrado até agora é muito simples e direta para-
enfermaria. Mas o conceito é muito poderoso se você começar a construir em cima dela
e criar sistemas maiores. Mais uma vez, uma das chaves desse livro é
demonstrar-lhe algumas noções básicas ideias e para aqueles que segurá-lo, eles podem
construir cenários e ambiente muito mais interessantes e complexas ou
simulações.

página 132
Unity 3D - Jogo de Programação Intro
118
Agora é hora de construir os componentes para o adversário. Vamos começar
descrevendo os itens que seria necessário para definir adequadamente a op- simples
Ponent para fins de demonstração.
Aqui está um breve resumo:
1. O inimigo vai começar com uma quantidade definida de recursos quando
o jogo começa.
2. O inimigo vai precisar para construir uma instalação de recolha.
3. O inimigo terá de criar uma unidade de coletor.
4. O inimigo terá de identificar a localização de recursos
a recolher.
5. O inimigo vai precisar atribuir o coletor para o recurso
a recolher.
6. Enquanto a unidade (s) colector estão coletando, o inimigo
precisa para explorar o terreno para identificar o jogador e matá-lo.
7. O inimigo terá de evitar ser morto pelo jogador
e ou outros objetos prejudiciais ao inimigo.
Praticamente é exactamente a mesma que a do jogador. Mas isso é
vale a pena mencionar novamente para nos dar uma ideia concreta. Você pode querer
usar os mesmos scripts para lidar com a lógica do jogador e do inimigo
lógica, mas como o tempo passa e seu código se torna mais complexa você
vai ver que esta estratégia não é sustentável. Na verdade, ele pode tornar-se
tedioso para manter e expandir a longo prazo. Portanto, seria
ser melhor para criar classes separadas para lidar com a lógica e as unidades do jogador
da do inimigo.
Assim como o jogador que seria necessário para criar três scripts para Han-
dle Unidade do inimigo Armazenamento, Unidade Collector, e da Unidade de Recursos. Estes
scripts são vai ser exatamente idêntico ao roteiro do jogador, com o
ressalva de que eles vão ser abordados objetos do inimigo.
A principal novidade para nossos scripts vai ser, o script que
irá conduzir nosso inimigo. Vamos chamar-lhe MyEnemy.cs . Será respon-
sível dar ao inimigo alguma inteligência, embora não muito, apenas para o
causa da demonstração deste nível. O objectivo do script

página 133
Vahé Karamian
119
seria permitir que o inimigo para nos arredores do terreno e ser capaz de
colocar a sua unidade de armazenamento para a coleta de recursos, e também ser capaz de defender
sua base e atacar o jogador, se necessário.
O script irá começar por colocar uma unidade de armazenamento em um lo- aleatório
cação com base no movimento do inimigo e um intervalo de tempo. Uma vez
A unidade de armazenamento é colocado, a Unidade de Armazenamento vai começar a automatizar
a sua
mecanismo de unidade de coletor e isso vai continuar até que o jogo acabou. Dentro
Entretanto, a lógica para a enemycharacter é entrar em modo de olheiro
até que tenha suficientes munições / recursos de ser capaz de atacar o
jogador. Durante este tempo, ele irá percorrer um conjunto de ponto especificado
no mundo até que esteja pronto para atacar. Quando ele está pronto para atacar, ele
irá localizar a posição do jogador e vá direto para o jogador
para matar.
Aqui está a lista inicial de MyEnemy.cs script:
usando UnityEngine;
usando System.Collections;
classe pública MyEnemy : MonoBehaviour
{
públicas GameObject MyBase;
públicas GameObject MyStorage;
privada GameObject myStorageObj;
pública GameObject MyEnemy;
public int NUM_BULLETS;
// variáveis para temporizador
public float Mytime = 5.0f;
private float endTime = 0.0f;
bool pública ATAQUE;
bool pública SCOUT;
pública Transform [] scoutPoints;
private int nextPointIndex;
// Use isso para inicialização
anular Iniciar ()
{
este .NUM_BULLETS = 1;
este .ATTACK = verdadeiro ;

página 134
Unity 3D - Jogo de Programação Intro
120
este .myEnemy = GameObject .FindGameObjectWithTag ( "Player" ) como GameOb-
jecto ;
// Inicia temporizador
este .endTime = este .myTime + Tempo .time;
este .nextPointIndex = 0;
}
// Update é chamado uma vez por quadro
anular Update ()
{
Se ( esse .myStorageObj == nulo )
{
Se ( esse .endTime < Tempo .time)
{
// Soltar o armazenamento
Vetor3 POS = novo vetor3 ( este .transform.position.x + 1, 2,
este .transform.position.z + 1);
este .myStorageObj = GameObject .Instantiate ( este .myStorage, pos,
este .myStorage.transform.rotation) como GameObject ;
este .endTime = 0.0f;
}
}
Se ( este .NUM_BULLETS> 1)
{
este .ATTACK = verdadeiro ;
}
outro
{
este .ATTACK = false ;
}
// Procurar o jogador para atacar
Se ( este .ATTACK)
{
Vector3 refillHeading = este .myEnemy.transform.position -
este .transform.position;
refillHeading.Normalize ();
// Usar a função Quaternion Slerp para fazer transição suave ...
este .transform.rotation =
Quaternion .Slerp (transform.rotation,
Quaternion .LookRotation (refillHeading), 10 *
Tempo .deltaTime);
este .transform.Translate ( Vector3 .forward * Tempo .deltaTime);
}
outro
{
Se ( este .scoutPoints.Length> 0)
{

página 135
Vahé Karamian
121
Vector3 refillHeading = esta .scoutPoints [nextPointIndex] .posi-
ção - este .transform.position;
refillHeading.Normalize ();
// Usar a função Quaternion Slerp para fazer transição suave ...
este .transform.rotation =
Quaternion .Slerp (transform.rotation,
Quaternion .LookRotation (refillHeading), 10 *
Tempo .deltaTime);
este .transform.Translate ( Vector3 .forward * Tempo .deltaTime);
Se ( Vector3 .distance ( este .transform.position, este .scout-
Pontos [nextPointIndex] .position) <0.25f)
{
este .nextPointIndex + = 1;
Se ( esse .nextPointIndex> = este .scoutPoints.Length)
{
este .nextPointIndex = 0;
}
}
}
}
}
}
Código Bloco 34 - MyEnemy.cs versão 1
Colocar os pedaços juntos e executar o programa, você vê como
o meio ambiente vem à vida. Os gráficos que usamos e 3D
modelos que usamos são muito primitivo, mas esta livros não é para 3D
Modelagem, é para a programação. Então, usamos espaço reservado primitivo que
pode muito facilmente ser substituídos quando chegarmos melhores modelos!
O único aspecto que ainda não implementaram, é a capacidade
atacar. Este é o caso tanto para o jogador eo inimigo. Nós podemos
começar por primeira implementação recurso ataque do jogador e, em seguida, nós podemos
implementar o recurso ataque do inimigo.
Para implementar o recurso de ataque seria preciso ajustar alguns
Unid. Em primeiro lugar, seria necessário ter uma representação física de como
e onde a iniciação ataque vai ocorrer. A próxima tarefa é iden-
tificar o quão poderoso o ataque real será. Finalmente, precisamos
determinar o que o intervalo para o ataque é.
A última condição é mais para o personagem do jogador inimigo, em vez
do que o jogador efectivo. O jogador pode atacar a qualquer momento e em qualquer lugar que ele

página 136
Unity 3D - Jogo de Programação Intro
122
ou ela deseja, desde que haja recursos disponíveis! O mesmo pio
cípio aplica-se ao inimigo, mas, seria sem sentido para projetar um inimigo
para atacar por qualquer razão, como seria o mesmo para o jogador para atacar
sem rumo e perder seus recursos, sem qualquer efeito real.
Aqui está a nova lista para o PlayerInput.cs script:
usando UnityEngine;
utilizando System.Collections.Generic;
classe pública PlayerInput : MonoBehaviour {
pública Lista < MyCollectableData > myCollection = nova Lista < MyCollecta-
bleData > ();
pública de materiais CubeMaterial;
pública MyStack pilha = new MyStack ();
bool privada MATCH = false ;
#region variáveis para o nível 2
int pública ROOM_SELECTION;
bool pública game_over;
#endregion
#region variáveis para o nível 3
pública GameObject myStorageUnit;
pública GameObject myBullet;
pública GameObject myGun;
public int NUM_BULLETS;
pública GameObject MyEnemy;
#endregion
anular Awake ()
{
este .stack.clear ();
este .ROOM_SELECTION = -1;
este .GAME_OVER = false ;
este .match = false ;
este .NUM_BULLETS = 1;
// Certifique-se que comece a limpo
este .myCollection.Clear ();
}
// Use isso para inicialização
vazio Iniciar () {

página 137
Vahé Karamian
123
Se ( esse .myEnemy == nulo )
{
este .myEnemy = GameObject .FindGameObjectWithTag ( "Inimigo" ) como GameOb-
jecto ;
}
}
private float VELOCIDADE = 2.0F;
// Update é chamado uma vez por quadro
anular Update ()
{
se (! este .GAME_OVER)
{
se (! este .match)
{
// Código para o movimento do jogador (CP) para a frente
se ( Input .GetKey ( KeyCode .UpArrow))
{
este .transform.Translate ( Vector3 .forward * Tempo .deltaTime *
este .SPEED);
}
// Código para o movimento do jogador (CP) para trás
se ( Input .GetKey ( KeyCode .DownArrow))
{
este .transform.Translate ( Vector3 .Contra * Tempo .deltaTime *
este .SPEED);
}
// Código para o movimento do jogador (CP) esquerda
se ( Input .GetKey ( KeyCode .LeftArrow))
{
este (.transform.Rotate Vector3 .Até, -5);
}
// Código para o movimento do jogador (CP) à direita
se ( Input .GetKey ( KeyCode .RightArrow))
{
este (.transform.Rotate Vector3 .Até, 5);
}
// Ir em frente e colocar a nossa estrutura de armazenamento na posição
onde o jogador é a
se ( Input .GetKeyUp ( KeyCode .space))
{
Vetor3 POS = novo vetor3 ( este .transform.position.x + 1, 2,
este .transform.position.z + 1);
GameObject storageObj = GameObject .Instantiate ( este .myStor-
ageUnit, pos, este .transform.rotation) como GameObject ;
storageObj.name = cadeia .format ( "StorageUnit {0}" , Tempo .time);
}
// fogo
se ( Input .GetKeyUp ( KeyCode .F))
{
Se ( este .NUM_BULLETS> 0)
{
GameObject bala = GameObject .Instantiate ( este .myBullet,

página 138
Unity 3D - Jogo de Programação Intro
124
este .myGun.transform.position, este .myGun.transform.ro-
ção) como GameObject ;
bullet.GetComponent < corpo rígido > (). velocidade = trans-
form.TransformDirection ( novo Vector3 (0, 0, 10.0f));
GameObject .Destroy (bala, 3.0f);
este .NUM_BULLETS--;
}
}
}
Se ( este .match)
{
#region RATO DE ENTRADA
se ( Input .mousePosition! = nulo && entrada .GetMouseButtonUp (0))
{
RaycastHit selectedCollectable;
// Capturar a posição do mouse e lança um raio para ver o que ob-
JECT nós batemos
Ray ray = Câmara .main.ScreenPointToRay ( Input .mousePosition);
se ( Física .Raycast (ray, fora selectedCollectable, 200))
{
se (selectedCollectable.transform.tag.Equals ( "MyCollect-
capazes " ))
{
var recolher = selectedCollectable.transform.gameOb-
ject.GetComponent < MyCollectable > ();
MyCollectableData dados = novas MyCollectableData ();
data.ID = collect.ID;
data.size = collect.size;
MyCollectableData sd = NULL ;
// Pilha de seleção
Se (stack.COUNT> 0)
{
sd = ( MyCollectableData ) stack.peek ();
Se (sd.size <data.size)
{
stack.push (dados);
}
outro
{
Debug log ( "Desculpe Try Again ...!" );
stack.clear ();
}
}
outro

página 139
Vahé Karamian
125
{
stack.push (dados);
}
}
}
}
Se (stack.COUNT> = 3)
{
para ( int i = 0; i <= stack.COUNT + 1; i ++)
{
MyCollectableData d = ( MyCollectableData ) stack.pop ();
Debug log ( cadeia .format ( "Pop: {0}" , d.size));
}
Debug log ( "GRANDE TRABALHO !!! Objectivo Concluído!" );
este .match = false ;
}
#endregion
}
}
}
// Essa função manipula a colisão de aceleradores como um gatilho
vazio OnTriggerEnter ( Collider c)
{
Se (c.tag.Equals ( "MyCollectable" ))
{
var recolher = c.gameObject.GetComponent < MyCollectable > ();
MyCollectableData dados = novas MyCollectableData ();
data.ID = collect.ID;
data.size = collect.size;
este .myCollection.Add (dados);
Destroy (c.gameObject);
}
Se (c.tag.Equals ( "DropOffZone" ))
{
Se ( este .myCollection.Count> 2)
{
Vector3 centro = c.transform.position;
int index = 1;
foreach ( var d neste .myCollection)
{
Vector3 pos = CirclePath (centro, 1.0f, index);
Índice ++;
Quaternion rot = Quaternion .FromToRotation ( Vector3 .forward,
Centro - pos);
GameObject tmp = GameObject .CreatePrimitive ( Primitive-
Tipo .Cube);

página 140
Unity 3D - Jogo de Programação Intro
126
tmp.transform.position = pos;
tmp.transform.rotation = podridão;
tmp.transform.tag = "MyCollectable" ;
tmp.transform.localScale = new Vector3 (d.size, d.size,
d.size);
tmp.GetComponent < Renderer > () Material =. presente .CubeMaterial;
// Anexar componente coleccionável, aplicam-se os dados
tmp.gameObject.AddComponent < MyCollectable > ();
tmp.gameObject.GetComponent < MyCollectable .> () ID = d.ID;
tmp.gameObject.GetComponent < MyCollectable > () size = d.size.;
}
// Tudo foi processado, começar combinando
este .match = verdadeiro ;
}
}
}
// Função para colocar a posição calcule do próximo item de torno
// Um caminho circular.
Vector3 CirclePath ( Vector3 center, flutuador raio, int id)
{
flutuador ang = 90 * id; //Random.value * 360;
Vector3 pos;
pos.x = center.x + raio * Mathf .Sin (ang * Mathf .Deg2Rad);
pos.z = center.z + raio * Mathf .Cos (ang * Mathf .Deg2Rad);
pos.y = center.y + 1;
voltar pos;
}
public void RoomVisited ( SlidingDoor quarto)
{
se (quarto! = NULL )
{
este .stack.push (quarto);
cadeia msg = cadeia .format ( "Room # {0} inserido, a contagem de pilha = {1}" ,
room.ROOM_NUMBER, este .stack.COUNT);
Debug log (msg);
Se ( este .stack.COUNT> = 3)
{
Debug log ( "VOCÊ GANHA !!!" );
este .GAME_OVER = verdadeiro ;
}
}
}
}
Código Bloco 35 - PlayerInput.cs com função ataque inimigo

página 141
Vahé Karamian
127
Olhando para o código que usamos a tecla 'F' na
teclado para começar a disparar as balas no inimigo.
Isto é feito através da verificação e certificando-se de que há balas no
o inventário. Uma vez que a bala é inicializado, ele é dada uma velocidade que
vai usar o motor de física para a sua trajetória. Finalmente, auto destruir
o objeto do jogo depois de um certo período de tempo, que passa a ser 3 se-
gundos.
Agora podemos dar uma olhada no script inimigo e estudar a estrutura
do código. Aqui está a lista para MyEnemy.cs com o recurso de ataque
implementadas:
usando UnityEngine;
usando System.Collections;
classe pública MyEnemy : MonoBehaviour
{
públicas GameObject MyBase;
públicas GameObject MyStorage;
privada GameObject myStorageObj;
pública GameObject MyEnemy;
pública GameObject myBullet;
pública GameObject myGun;
public int NUM_BULLETS;
// variáveis para temporizador
public float Mytime = 5.0f;
private float endTime = 0.0f;
bool pública ATAQUE;
bool pública SCOUT;
pública Transform [] scoutPoints;
private int nextPointIndex;
// Use isso para inicialização
anular Iniciar ()
{
este .NUM_BULLETS = 1;
este .ATTACK = verdadeiro ;
este .myEnemy = GameObject .FindGameObjectWithTag ( "Player" ) como GameOb-
jecto ;
// Inicia temporizador

página 142
Unity 3D - Jogo de Programação Intro
128
este .endTime = este .myTime + Tempo .time;
este .nextPointIndex = 0;
}
private float VELOCIDADE = 2.0F;
// Update é chamado uma vez por quadro
anular Update ()
{
Se ( esse .myStorageObj == nulo )
{
Se ( esse .endTime < Tempo .time)
{
// Soltar o armazenamento
Vetor3 POS = novo vetor3 ( este .transform.position.x + 1, 2,
este .transform.position.z + 1);
este .myStorageObj = GameObject .Instantiate ( este .myStorage, pos,
este .myStorage.transform.rotation) como GameObject ;
este .endTime = 0.0f;
}
}
Se ( este .NUM_BULLETS> 1)
{
este .ATTACK = verdadeiro ;
}
outro
{
este .ATTACK = false ;
}
// Procurar o jogador para atacar
Se ( este .ATTACK)
{
Vector3 refillHeading = este .myEnemy.transform.position -
este .transform.position;
refillHeading.Normalize ();
// Usar a função Quaternion Slerp para fazer transição suave ...
este .transform.rotation =
Quaternion .Slerp (transform.rotation,
Quaternion .LookRotation (refillHeading), 10 *
Tempo .deltaTime);
este .transform.Translate ( Vector3 .forward * Tempo .deltaTime *
este .SPEED);
Se ( Vector3 .distance ( este .myEnemy.transform.position, este .trans-
form.position) <5.0f)
{
Se ( este .NUM_BULLETS> 0)
{
Se ( esse .endTime < Tempo .time)

página 143
Vahé Karamian
129
{
GameObject bala = GameObject .Instantiate ( este .myBullet,
este .myGun.transform.position, este .myGun.transform.ro-
ção) como GameObject ;
bullet.GetComponent < corpo rígido > (). velocidade = trans-
form.TransformDirection ( novo Vector3 (0, 0, 10.0f));
GameObject .Destroy (bala, 3.0f);
// Inventário diminuição
este .NUM_BULLETS--;
// Definir o temporizador antes da próxima tacada
este .endTime = este .myTime + Tempo .time;
}
}
}
}
outro
{
Se ( este .scoutPoints.Length> 0)
{
Vector3 refillHeading = esta .scoutPoints [nextPointIndex] .posi-
ção - este .transform.position;
refillHeading.Normalize ();
// Usar a função Quaternion Slerp para fazer transição suave ...
este .transform.rotation =
Quaternion .Slerp (transform.rotation,
Quaternion .LookRotation (refillHeading), 10 *
Tempo .deltaTime);
este .transform.Translate ( Vector3 .forward * Tempo .deltaTime);
Se ( Vector3 .distance ( este .transform.position, este .scout-
Pontos [nextPointIndex] .position) <0.25f)
{
este .nextPointIndex + = 1;
Se ( esse .nextPointIndex> = este .scoutPoints.Length)
{
este .nextPointIndex = 0;
}
}
}
}
}
}
Código Bloco 36 - MyEnemy.cs com função de Ataque
Se você observar a modificação para o recurso de ataque é semelhante à forma como
temos implementado para o jogador, mas há uma grande diferença, nós
integraram um temporizador na lógica para que o computador não dispara

página 144
Unity 3D - Jogo de Programação Intro
130
continuamente. O temporizador irá permitir que o jogador a fazer um movimento e também
para o inimigo em si não para drenar todos os seus recursos em um curto espaço de
Tempo.
A lógica temos implementado não é muito sofisticado e pode
ser melhorado um pouco. Nesse ponto, eu quero que você tome a oportunidade
e veja como você pode melhorar a lógica um passo adiante. eu vou te dar
uma dica, se você jogar o nível e prestar atenção aos detalhes que você vai notar
que o inimigo vai atirar se o jogador está dentro de dois metros dele, mesmo
embora o inimigo não está voltada para o jogador. Este é um inconveniente que a
lógica atual não leva em consideração, portanto, uma melhoria
seria para se certificar de que o inimigo está sempre de frente para o jogador antes de
incêndios. Isso é algo que pode ser facilmente implementado e eu faria
que você faça essa parte em seu próprio país.

página 145
Vahé Karamian
131
Capítulo 5 - Criando a interface do usuário
User Interface (UI) é um aspecto muito importante de qualquer soft-
sistema ware. Afinal, esta é a forma como os usuários estão indo para ser capaz de
interagir com seus aplicativos, jogos e ambientes. Neste tulo
ter, vamos dar uma olhada na nova arquitetura UI disponível com
Unidade 5. Se você tiver feito qualquer desenvolvimento em versões antigas do Unity,
você vai apreciar o novo reforço, que são feitas no novo re-
locação de Unity 5.
Design de interface de usuário e desenvolvimento é uma arte por si só. Assim como
qualquer outra coisa, leva anos de prática e experiência na área de re-
aliado a ajustar seus projetos de interface do usuário. Não há ciência na concepção de uma interface
de usuário
per-se, no entanto, bons designers de interface do usuário tocar em outras ciências humanas e
ciências da arte para trazer algo único.
Figura 44 - Interface de usuário Amostra 1
Uma vez que cada UI vai ser exclusivo para o ambiente que você está
projetando para, será muito importante para o designer UI Compreensão
suportar o sistema dentro e por fora. Eu não estou falando sobre a técnica
detalhes de como as coisas podem funcionar internamente, mas, você deve estar ciente
de todas as especificações para as entradas e as saídas do sistema.

página 146
Unity 3D - Jogo de Programação Intro
132
Isto levará a uma melhor tomada de decisão quando você está projetando o
layout de sua interface do usuário e as características e funções disponíveis em um determinado
Tempo.
Figura 45 - Interface de usuário Amostra 2
Interfaces de usuário vêm em muitas formas e formas. Como mencionado BE
tona, ele realmente se resume a que tipo de informação que você deseja
compartilhar com o jogador, e que tipo de funcionalidade, se for o caso, você teria
gostaria de fornecer para o jogador.
Os princípios de design de interface na unidade 5
Se você tem experiência com a criação de interfaces de usuário com o anterior
versões de Unidade, você sabe que ele foi extremamente entediante e limitado.
Com a introdução da Unidade 5, o motor de UI de base tem sido
melhorou dez vezes.
os Canvas
Um pouco de fundo e diversão. O que é um Canvas?
"Canvas é um tecido-plain extremamente durável usado para MAK
ing velas, tendas, toldos, mochilas e outros itens para os quais
resistência é necessária. Ele também é popularmente usado por artistas como uma pintura
superfície, normalmente esticado através de uma moldura de madeira ".

página 147
Vahé Karamian
133
Na ciência da computação e visualização, a tela é um recipiente que
detém vários elementos de desenho (linhas, formas, texto, quadros que contêm
outros elementos, etc.). Ela leva o seu nome a partir da tela usado no Visual
artes. Às vezes é chamado um grafo de cena, porque organiza a lógica
representação de uma interface de usuário ou cena gráfica. alguns aplica-
tações também definem a representação espacial e permitir que o usuário
interagir com os elementos por meio de uma interface de utilizador gráfica.
Em Unity 3D, a tela é a área que todos os elementos de interface do usuário deve ser
dentro. É um GameObject com um componente de tela a ela ligada, e
todos os elementos de interface do usuário deve ser filhos de tal Canvas.
Ordem de desenho e Modos de Desenho:
elementos da interface na tela são desenhados na mesma ordem em que aparecem
na hierarquia. O primeiro filho é desenhada em primeiro lugar, o segundo filho seguinte,
e etc ... Se dois elementos de interface do usuário se sobrepõem, o que mais tarde irá aparecer no
topo
do um anterior.
Modos de Desenho:
Há três modos de renderização disponíveis para a lona:
 Espaço Tela - Overlay: Este modo de renderização coloca elemento UI
mentos na tela processado no topo da cena. Se o
tela é redimensionada ou resolução de mudanças, os Canvas vai au-
maticamente alterar o tamanho para coincidir com ele.
 Espaço Screen - Câmara: semelhante à tela Space - Over-
leigos, mas neste modo de renderização, a lona é colocado um determinado
distância na frente de uma câmera especificada. Os elementos de interface do usuário
são prestados pela Câmara, o que indica que o Cam-
configurações era irá ter um efeito sobre a aparência da IU
elementos.
 Space World: Neste modo de renderização, os Canvas irá se comportar
como qualquer outro objeto na cena. O tamanho da tela pode
ser ajustado manualmente usando seu Rect Transform, e os elementos de interface do usuário

página 148
Unity 3D - Jogo de Programação Intro
134
retribuirá na frente ou atrás de outros objetos na cena
com base no posicionamento 3D. Isto é útil para interfaces de usuário que são
destina-se a ser uma parte do mundo. Isto também é conhecido como um
"Interface diegético".
Esquema Básico
Cada elemento da interface do usuário é representada como um retângulo para fins de layout.
Esse retângulo pode ser manipulado na Scene View usando o Rect
Ferramenta na barra de ferramentas. A ferramenta Rect é usada tanto para recursos 2D do Unity
e para IU, e na verdade pode ser usado até mesmo para objetos em 3D também.
Figura 46 - Rect da barra de ferramentas Ferramenta Botões
A ferramenta Rect pode ser usado para mover, redimensionar e girar elementos de interface do
usuário.
Depois de ter seleccionado um elemento de interface do usuário, você pode movê-lo clicando an-
ywhere dentro do retângulo e arrastando. Você pode redimensioná-la clicando
nas bordas ou cantos e arrastando.
O elemento pode ser girado passando o cursor um pouco longe
a partir dos cantos até que o cursor do mouse se parece com um símbolo de rotação.
Em seguida, você pode clicar e arrastar em qualquer direção para girar.
Assim como as outras ferramentas, a ferramenta Rect usa o modo de giro atual
e espaço, situado na barra de ferramentas. Ao trabalhar com UI é geralmente uma boa
idéia para manter os estabelecidos para Pivot e Local.
Rect Transformação:
A Rect Transform é um novo componente transformar que é usado para
todos os elementos de interface do usuário, em vez de regular Transform componente.
Rect transformações têm posição, rotação e escala apenas como regulares
Transforma, mas também tem uma largura e uma altura, utilizado para especificar o di-
mensões do retângulo.

página 149
Vahé Karamian
135
Figura 47 - Rect Transform Component
Pivô:
Rotações, tamanho, e modificações escala ocorrer em torno do pivô assim
a posição do pivô afecta o resultado de uma rotação, redimensionamento, ou
escalonamento. Quando o botão da barra de ferramentas Pivot está no modo de pivô, o pivô
de um Rect Transform pode ser movido na Scene View.
Figura 48 - Pivot interface
Âncoras e Presets Âncora:
Rect transformações incluem um conceito de layout chamado âncoras. âncoras
são mostrados como quatro pequenas alças triangulares na Scene View e an-
informações Chor também é mostrado no Inspector. Se o pai de um Rect
Transformar é também um Rect transformar, a criança Rect Transform pode ser

página 150
Unity 3D - Jogo de Programação Intro
136
ancorado à matriz Ret Transformada de várias maneiras. Por exemplo,
a criança pode ser ancorada ao centro da matriz, ou a um dos
cantos.
Figura 49 - Anchor UI Elements
A ancoragem também permite que a criança para esticar juntamente com o
largura ou a altura do pai. Cada canto do retângulo tem um fixo
offset para sua âncora correspondente, ou seja, o canto superior esquerdo da rectan-
gle tem um deslocamento fixo para o início âncora esquerda, etc. Desta forma, o diferente
cantos do rectângulo pode ser ancorado a diferentes pontos na matriz
retângulo.
No Inspector, o botão Anchor predefinidos podem ser encontrados no up-
per canto esquerdo do Rect Transform componente. Ao clicar no botão
traz no menu suspenso Âncora Presets. A partir daqui você pode rapidamente
selecionar a partir de algumas das opções de ancoragem mais comuns. Você pode an-
chor o elemento UI para os lados ou no meio do pai, ou estiramento
em conjunto com o tamanho de pai. A ancoragem horizontal e vertical é
independente.

página 151
Vahé Karamian
137
Figura 50 - Pré-selecionar Anchor Component
Os Anchor Presets botões mostra a predefinição actualmente seleccionada
opção se houver um. Se as âncoras de ambos a horizontal ou vertical
eixo estão definidos para diferentes posições do que qualquer uma das predefinições, o costume
opções é mostrado.
Unidade componentes de interface do utilizador 5
Existem dois tipos de componentes de interface do usuário na unidade. Há Visual
Componentes e componentes interativos . Vamos começar por olhar para
o Visual Components primeiro, e depois os Componentes Interactive.
Componentes Visuais:
Estes são os UIElements que são usados para displayinformation volta
para o utilizador. Vou dar-lhe apenas a visão geral e se você cavar
mais profunda para eles em seu próprio país.
 texto: a componente de texto, que é também conhecido como um rótulo,
tem uma área de texto para introduzir o texto que será exibido.
É possível definir a fonte, estilo da fonte, tamanho da fonte e se

página 152
Unity 3D - Jogo de Programação Intro
138
ou não o texto tem capacidade de texto rico. Há opções para
definir o alinhamento do texto, as definições para horizontal e ver-
estouro ticos que controlar o que acontece se o texto é
maior do que a largura ou altura do rectângulo, e uma melhor
opção de ajuste que faça o texto redimensionar para se ajustar ao disponíveis
espaço.
 Image: Uma imagem tem um Rect Transform componente e um
componente de imagem. Um sprite pode ser aplicada à imagem
componente sob o campo Target Graphic, e sua cor
pode ser definido no campo Cor. Um material também pode ser aplicado
ao componente de imagem. Os define campo Tipo de Imagem
como o sprite aplicada aparecerá, as opções são:
o simples
o em fatias
o Azulejo
o Filled
As imagens podem ser importadas como sprites UI selecionando Sprite (
2D / UI) a partir das definições do 'tipo de textura ". Sprites têm ex-
configurações tra importação em comparação com os antigos sprites GUI, o
maior diferença é a adição do editor de sprites. o
editor de sprites fornece a opção de 9-cortar a imagem, este
divide a imagem em 9 áreas de modo que se o sprite é redimensionada
os cantos não são esticados ou distorcidos.
 Imagem Raw: O componente de imagem leva um sprite, mas Raw
Imagem tem uma textura (sem fronteiras etc). Imagem crus devem
só pode ser usado se for necessário outro modo Imagem será adequado
na maioria dos casos.
 Mask: A máscara não é um controle UI visível, mas sim uma maneira
para modificar a aparência dos elementos filho de um controle. o
restringe máscara (ou seja, "máscaras") A criança elementos para a forma
do pai. Assim, se a criança é maior do que o pai então

página 153
Vahé Karamian
139
apenas a parte da criança que se encaixa dentro do pai será
visível.
 Efeitos: componentes visuais também podem ter várias simples
efeitos aplicados, como uma sombra simples ou esquema.
Componentes interativos:
Cada UI precisa ter algum tipo de um elemento intratável a ele.
Esse é o usuário precisa ser capaz de selecionar alguma coisa. Estes são elemento UI
mentos que o utilizador pode interagir com, como um:
 Botão: O botão é projetado para iniciar uma ação quando
o usuário clica e libera-lo. Se o mouse é movido para fora da
controle de botão antes do clique é liberado, a ação faz
não ter lugar. O botão tem um único evento chamado On
Clique que responde quando o usuário conclui um clique.
 Alternar: O controle de alternância permite que o usuário alternar uma
opção ligado ou desligado. Você também pode combinar vários alterna em
um grupo de alternância nos casos em que apenas um de um conjunto de opções
deve ser ao mesmo tempo. A alternância tem um único evento chamado
Em valor alterado que responde quando as alterações do usuário
o valor atual. O novo valor é passado para o evento
função como um parâmetro booleano.
 Grupo de alternância: O Grupo de alternância está configurado, arrastando o
Grupo de alternância objeto para a propriedade Grupo de cada um dos
Alterna no grupo. Alternar Grupos são úteis em qualquer lugar
o usuário deve fazer uma escolha entre um conjunto mutuamente exclusivos
de opções. Exemplos comuns incluem jogador de seleção
tipos de caracteres, configurações de velocidade (lento, médio, rápido, etc),
cores predefinidas e dias da semana. Você pode ter mais de
Um grupo de alternância objeto na cena de cada vez, para que você possa
criar vários grupos separados, se necessário.
 deslizante: O valor de um deslizante é determinada pela posição
da pega ao longo do seu comprimento. O valor aumenta a partir da

página 154
Unity 3D - Jogo de Programação Intro
140
Min Valor até o valor máximo em proporção com o dis-
tância a alça é arrastado. O comportamento padrão é para o
deslizante para aumentar a partir da esquerda para a direita, mas também é possível
reverter esse comportamento usando a propriedade Direction.
Você também pode definir o controle deslizante para aumentar verticalmente selecionáveis
ing baixo para cima ou de cima para baixo para o Direction
propriedade. O controle deslizante tem um único evento chamado sobre o valor
Mudou isso responde como o usuário arrasta a alça. o
valor numérico corrente do cursor é passado para a função
como um parâmetro flutuante.
 Barra de rolagem: O valor de uma barra de rolagem é determinada pela
posição da pega ao longo do seu comprimento com o valor sendo
relatado como uma fracção entre as extremidades extremas. Para a prova-
plo, o padrão da esquerda para a direita bar tem um valor de 0.0 na esquerda
fim, 1,0 na extremidade direita e 0,5 indica o ponto no meio do caminho.
A barra de rolagem pode ser orientada verticalmente, escolhendo Top de
Baixo ou de baixo para cima para o jogador a propriedade Direction.
Uma diferença significativa entre a barra de rolagem eo sim-
controle de Ilar Slider é que o cabo da barra de rolagem pode mudar
em tamanho para representar a distância de deslocamento disponível; quando
a visão pode rolar apenas um pouco mais, a alça vai encher-se
a maior parte do bar e onlyallow uma ligeira mudança qualquer direção.
A barra de rolagem tem um único evento chamado On valor alterado
que responde como o usuário arrasta a alça. O atual
valor é passado para a função mesmo como um parâmetro flutuante.
 suspensa: a lista suspensa
16
pode ser usado para permitir que o usuário
escolher uma única opção de uma lista de opções. O controle
mostra a opção atualmente escolhido. Uma vez clicado, abre-se
a lista de opções para uma nova opção pode ser escolhida. sobre
a escolha de uma nova opção, a lista de fechada novamente, eo con-
controle mostra a nova opção selecionada. A lista também está fechado
16
Olhe para a documentação on-line para todas as opções e configurações disponíveis.

página 155
Vahé Karamian
141
Se o usuário clica no controle propriamente dito, ou em qualquer outro lugar in-
lado a lona.
 O campo de entrada: Um campo de entrada é uma maneira de tornar o texto de uma
Controle de texto editável. Como os outros controles de interação,
não é um elemento de interface do usuário visível em si mesmo e deve ser combinada
com um ou mais elementos de interface visual, a fim de ser visível.
O script Campo de entrada pode ser adicionado a qualquer texto existente
objeto de controle a partir do menu (Componente> UI> Input
Campo). Tendo feito isso, você também deve arrastar o objeto para
propriedade de texto do campo de entrada para permitir a edição.
O texto de propriedade do controle de texto em si vai mudar à medida
os tipos de usuários e o valor pode ser recuperado a partir de um roteiro
após a edição. Note-se que Rich Text intencionalmente não é apoiar
portado para controles de texto editável; o campo será aplicada qualquer
marcação Rich Text instantaneamente quando digitado, mas a marcação es-
cialmente "desaparece" e não há nenhuma maneira para subsequente
alterar ou remover o styling.
 Scroll Rect: Um Scroll Rect pode ser usado quando o conteúdo que
toma-se uma grande quantidade de espaço necessário para ser exibida numa pequena área.
O Scroll Rect fornece a funcionalidade para se deslocar ao longo deste
conteúdo. Normalmente, um Scroll Rect é combinado com uma máscara em
Para criar uma exibição de rolagem, onde apenas o con- rolagem
tenda dentro do Scroll Rect é visível. Ele pode também adicionalmente
ser combinada com uma ou duas barras de deslocamento que pode ser
arrastado para rolar horizontalmente ou verticalmente.
Criação de interface primeiro usuário
Agora que você tem uma compreensão da tela e as dife-
Os elementos da interface do utilizador ent disponíveis para você, nós podemos ir em frente e obter
mãos em prática através da criação de nossa primeira UI.
Usaremos os níveis que desenvolvemos no capítulo anterior
para demonstrar os conceitos e também dar uma visão geral do sistema de UI
na Unidade 5. Nós criamos níveis de árvore para a demonstração da

página 156
Unity 3D - Jogo de Programação Intro
142
mecânica de jogo conceitos. Vamos em frente e incluí-los aqui, e também
os objectivos para cada um. Isto é importante, porque você precisa de Compreensão
ficar os objectivos do nível para ser capaz de projetar seu UI para apoiar
seu ambiente de jogo.
Se você se lembrar estes eram os níveis que discutimos:
 Nível 1: pesquisa; coleta; correspondência e classificação.
 Nível 2: Chancing; mistura e temporização
 Nível 3: progredindo; evasão; capturando e conquistar
Para projetar a interface do usuário para o nível 1, que seria necessário para exibir algumas infor-
mações para o usuário sobre o estado do jogo. No anterior
capítulo usamos debug.log () como uma forma de testar e depurar a nossa lógica. Em um
forma a dar-nos uma atualização sobre o estado do ambiente. Isso, entretanto,
não é visível para o jogador e que seria necessário para criar algo que
será mais atraente para eles.
Nível 1 - UI design
Para começar a criar o nosso UI, precisamos introduzir uma tela de jogo, Obser-
JECT em nossa cena. A maneira mais fácil de fazer isso é clicando com o botão direito na
Janela Hierarquia e do menu de contexto , selecione ( UI-> Canvas ).
Isto irá colocar um jogo de objeto em tela em sua cena. Queremos definir
o modo de renderização de tela Space - Overlay
17
Se este não é o conjunto de valores
já.
Existem dois principais informações que precisa para se comunicar com o
jogador: (1) quantos colecionáveis itens existem na cena, (2) como
muitos itens o jogador tenha coletado. Podemos combinar dois elementos de interface do usuário
para exibir esta informação para o jogador:
 Painel
 Texto
17
Este modo de renderização coloca elementos de interface do usuário na tela prestados no topo da
cena.

página 157
Vahé Karamian
143
Para adicionar um elemento de interface do usuário do painel, você deve clicar com o botão direito
na Hierarquia
Janela sobre o Jogo lona objeto, e selecione ( Painel UI-> ). Isso vai
adicionar um elemento Panel como um filho para o jogo lona objeto. Por padrão,
o Painel irá preencher toda a tela.
Figura 51 - Canvas com painel Anexado
Observe como a Janela de jogo mudou com a tela sobre-
leigos do jogo lona objeto. Queremos ter certeza de que o Painel
elemento UI não ocupam todo o espaço. Selecionando a interface do usuário do painel
elemento, podemos usar a janela Inspetor para ajustar as propriedades.
A primeira coisa que gostaria de fazer é mudar as âncoras do
Painel. Podemos usar a configuração predefinida para ancorar o controle para a
canto superior esquerdo da tela. Quando você fazer a mudança, observe que
o Rect Transform atualizados seus valores posX / Posy e largura / altura.
Nós estaremos ajustando esses valores para a nossa ligação. Eu tenho feito em frente e
atualizados meus valores para o seguinte:
 Pos X: 50
 Pos Y: -25
 Largura: 100
 Altura: 50

página 158
Unity 3D - Jogo de Programação Intro
144
A largura ea altura, definir a largura real ea altura
o painel em pixels, e os valores de posição são deslocamento relativo a
o ponto de ancoragem.
Vamos em frente e adicionar a elementos de interface do usuário texto, para fazer isso, você vai
clique novamente com o botão direito na janela de hierarquia no elemento Panel, e
select ( UI-> Texto ). Esta acção irá criar um elemento de texto e torná-lo um
filho do Painel. Note também que na janela Inspetor, bydefault,
o elemento de texto está ancorada no centro, com a largura padrão e
altura.
Existem algumas propriedades que eu tenho
mudou no elemento de texto.
No Rect Transform , eu atualizei
Largura e Altura para ser 80 e
40, respectivamente.
No texto componente Script, tenho
mudou o alinhamento a ser horizontalmente
tally centrado e verticalmente também
centrado.
Por último, tenho verificado o melhor ajuste
caixa de verificação para auto-corrigir o texto no
área fornecida.
Observe, que você também pode alterar o
fonte e o tamanho da fonte, bem como a
cor do texto, ou até mesmo aplicar Mate-
rial a ser utilizado para o processamento.
Temos agora compôs uma interface simples que pode ser usado para dar alguma
feedback para o jogador. Quanto ao design de interface está em causa, estamos
feito neste ponto. Mas, é preciso ser capaz de atualizar o elemento de texto
página 159
Vahé Karamian
145
de alguma forma, de dentro do nosso jogo! A fim de sermos capazes de alcançar
isso, seria preciso fazer alguma codificação menor.
Figura 52 - Painel de UI e texto Elemento
Precisamos ser capazes de referenciar o UIElement texto de nosso código,
e uma vez que temos uma referência, podemos atualizar o texto de propriedade do
Texto elemento de interface do usuário.
Desde o PlayerInput.cs roteiro é responsável por manter o controle do
estatuto para o jogo, vamos criar uma nova variável pública do tipo Texto
que será usada para se referir ao elemento de interface de texto.
Gostaríamos de atualizar a classe adicionando as duas variáveis seguintes:
públicas texto lblCollectables;
private int colecionáveis = 0;
E gostaríamos de mudar a nossa Iniciar () função de ser algo como o
Segue:
anular Iniciar ()
{
Se ( esse .myEnemy == nulo )
{
este .myEnemy = GameObject .FindGameObjectWithTag ( "Inimigo" ) como GameOb-
jecto ;
}

página 160
Unity 3D - Jogo de Programação Intro
146
Se ( esse .lblCollectables! = NULL )
{
GameObject [] colecionáveis = GameObject .FindGameObjectsWithTag ( "MyCol-
lectable " );
este .Colecionáveis = collectables.Length;
este .lblCollectables.text = cadeia .format ( "{0} / {1}" , este .myCollec-
tion.Count, este .Colecionáveis);
}
}
Finalmente, seria preciso atualizar as informações durante o jogo
tempo, por conseguinte, que irá também incluir o seguinte segmento no Up-
date () função.
Se ( esse .lblCollectables! = NULL )
{
este .lblCollectables.text = cadeia .format ( "{0} / {1}" , este .myCollec-
tion.Count, este .Colecionáveis);
}
A interface resultante seria algo como isto:
Figura 53 - Collectables UI Implementado
Então nós criamos um aspecto do nosso UI, mas temos mais trabalho
façam. Uma vez que recolher todas as nossas coleções, temos de encontrar o drop
Zona e ser capaz de igualar os colecionáveis com base em seu tamanho. Nós
página 161
Vahé Karamian
147
seria necessário para implementar uma interface que pode identificar corretamente este
processo para o jogador de uma forma agradável.
Uma vez que, estamos usando uma estrutura de dados Stack para manter a ordem de
seleção realizada pelo jogador, podemos criar a nossa UI para esta tarefa em
de forma semelhante. Além disso, gostaríamos de displaythis UIportion específica
uma vez que o usuário tenha coletado todos os itens colecionáveis e está no drop
Zona . Por isso, quando que desencadeia, vamos também apresentar o específica UI
para correspondência. Para que isso funcione corretamente, seria preciso criar um novo
Objeto de lona. Lembre-se, que podemos ter objeto Canvas múltipla
a cena, e cada tela pode ser usada para uma finalidade diferente dentro
a cena e ativada ou desativada, conforme necessário.
Para criar uma segunda tela, você vai clicar com o botão direito na Hierarquia
Janela e, no menu de contexto, selecione ( UI-> Canvas ). Você poderia
quiser adicionar um novo elemento do painel e também objetos de elemento de três botões
ao Painel. O processo é o mesmo para adicionar qualquer elemento de interface do usuário, por isso
estamos
Não indo para listar que qualquer mais.
Figura 54 - UI adicional para Matching

página 162
Unity 3D - Jogo de Programação Intro
148
Uma vez que você projetou a interface do usuário na Scene View, precisaríamos
para criar o código para acessar e controlá-lo. No mínimo, precisamos
ser capaz de ativar e desativar o objeto da lona com base em alguns critérios.
Também precisamos atualizar a legenda dos elementos de botão com base no
seleção do usuário na Gota-Zone .
pública Canvas canvasMatching;
pública Texto lblStackTop;
pública Texto lblStackMiddle;
pública Texto lblStackBottom;
Código Bloco 37 - Nível 1 Variáveis de lona Jogo
Nós podemos facilmente configurar algumas variáveis para fazer referência a interface necessária
ob-
JECT como mostrado i n Código Bloco 37. Mas olhe para o código temos
escrito anteriormente, não estamos realmente lidando com isso corretamente. Para fazer o
processo ea interface do usuário um pouco mais intuitivo, que provavelmente deve adicionar dois
mais botões na interface do usuário, dando ao jogador a capacidade quer redefinir o
jogo inteiro, ou no caso de correspondência, ser capaz de experimentar o desafio
mais uma vez. Levando isso dois nova adição em consideração, o nosso UI será
atualizados para se parecer com o seguinte:
Figura 55 - Elementos de interface do usuário adicionais para Nível 1
Desde então, temos melhorado a nossa UI, precisamos rever nossa lógica para
o matchmaking e também atualizá-lo corretamente para refletir as novas alterações.
A primeira tarefa que devemos fazer é criar as funções botão de gatilho, em

página 163
Vahé Karamian
149
menos o espaço reservado. Nós iria introduzir duas novas funções para lidar com
os eventos CLICK durante os botões recém-criados: butRestartClick ()
e butTryAgainClick () .
public void butRestartClick ()
{
Aplicação .LoadLevel ( "CH6_LEVEL_1" );
}
public void butTryAgainClick ()
{
// Manipular o evento tente novamente
}
Código Bloco 38 - Botão dispara para o Nível 1
As funções listadas acima irá lidar com o OnClick evento para cada
botão respectivamente. Nós ainda precisamos de ligar essas funções com as On-
Clique evento. A fim de fazer isso, você precisará selecionar o desejado
botão a partir da janela de hierarquia , e da janela Inspector ,
você precisará adicionar um novo evento na OnClick () propriedade.
Figura 56 - Botão OnClick evento
Assim, desde o Inspector Win-
dow , você irá para o botão
Componente Script e adicione um
manipulador de eventos clicando no
(+) Botão. Isto irá criar um
slot de soltar vazio para você.
Você vai precisar de arrastar e soltar
o GameObject que o Evento
Handler está conectado, em nossa
caso é o GameObject CP.
Uma vez que é colocado no
slot vazio, você vai usar o
lista suspensa para selecionar o
Script-> Função (), que irá
manipular o evento OnClick.
Isto acontece por ser PlayerInput.butRestartClick () para o nosso código.
É isso! Você acabou de criar seu manipulador de eventos primeiro botão. No

página 164
Unity 3D - Jogo de Programação Intro
150
altura desta escrita, a função Unidade de evento só pode receber um tro
eter, daí, se houver uma necessidade de passar vários parâmetros, uma maneira
contornar essa limitação, é criar múltiplas funções e múltipla
manipulador de eventos e anexá-las apenas como nós fizemos. Neste ponto cada vez
o botão é clicado em tempo de execução, que são re-carregar todo o nível.
Aqui estão os trechos de código para as adições e também de modificação
que tenham sido aplicadas à PlayerInput.cs script:
public void butRestartClick ()
{
Aplicação .LoadLevel ( "CH6_LEVEL_1" );
}
public void butTryAgainClick ()
{
// Manipular o evento tente novamente
este .stack.clear ();
este .lblStackBottom.text = "0" ;
este .lblStackMiddle.text = "0" ;
este .lblStackTop.text = "0" ;
}
As duas funções que lidam com o botão OnClick evento para o
Botão reiniciar eo botão Try Again estão listados acima. A Awake ()
função foi removida, eo Start () função foi modificada
para chamar uma nova função para repor todas as variáveis chamadas RESETgame () . Aqui
é a listagem:
private void RESETgame ()
{
este .stack.clear ();
este .ROOM_SELECTION = -1;
este .GAME_OVER = false ;
este .match = false ;
este .NUM_BULLETS = 1;
// Certifique-se que comece a limpo
este .myCollection.Clear ();
}
// Use isso para inicialização
vazio Iniciar () {

página 165
Vahé Karamian
151
este .ResetGame ();
Se ( esse .myEnemy == nulo )
{
este .myEnemy = GameObject .FindGameObjectWithTag ( "Inimigo" ) como GameOb-
jecto ;
}
#region código para elementos de interface do usuário - Nível 1
Se ( esse .lblCollectables! = NULL )
{
GameObject [] colecionáveis = GameObject .FindGameObjectsWithTag ( "meu-
Colecionáveis " );
este .Colecionáveis = collectables.Length;
este .lblCollectables.text = cadeia .format ( "{0} / {1}" , este .myCollec-
tion.Count, este .Colecionáveis);
}
Se ( esse .canvasMatching! = NULL )
{
este .canvasMatching.enabled = false ;
Se ( esse .lblStackTop! = NULL )
{
este .lblStackTop.text = "0" ;
}
Se ( esse .lblStackMiddle! = NULL )
{
este .lblStackMiddle.text = "0" ;
}
Se ( esse .lblStackBottom! = NULL )
{
este .lblStackBottom.text = "0" ;
}
este .butTryAgain.gameObject.SetActive ( false );
}
#endregion
}
Basicamente, o RESETgame () função é fazer o que a Awake ()
função usada para fazer, no entanto, uma vez que temos a capacidade de re-iniciar o
jogo durante o jogo, e o recurso de reinício basicamente carrega o nível
mais uma vez, estamos usando o Start () função para chamar a RESETgame () função
ção para redefinir todas as variáveis no nível.
O Update () função também foi modificado para acomodar o
as novas alterações que fizemos através da interface do usuário. Você vai notar que agora,
quando o jogador escolhe três itens correspondentes, se eles não são ordenados
corretamente, um botão, é apresentado para dar-lhes a oportunidade de experimentar novamente.

página 166
Unity 3D - Jogo de Programação Intro
152
Aqui está a lista para a nova lógica de lidar com a entrada do mouse na
) Update ( função:
Se ( este .match)
{
#region RATO DE ENTRADA
se ( Input .mousePosition! = nulo && entrada .GetMouseButtonUp (0))
{
//Debug.Log("START JOGO >>> ");
RaycastHit selectedCollectable;
// Capturar a posição do mouse e lança um raio para ver o que ob-
JECT nós batemos
Ray ray = Câmara .main.ScreenPointToRay ( Input .mousePosition);
se ( Física .Raycast (ray, fora selectedCollectable, 200))
{
//Debug.Log("TAG="+selectedCollectable.transform.tag);
se (selectedCollectable.transform.tag.Equals ( "MyCollect-
capazes " ))
{
//Debug.Log("YOU Clicado ME >>> ");
var recolher = selectedCollectable.transform.gameOb-
ject.GetComponent < MyCollectable > ();
MyCollectableData dados = novas MyCollectableData ();
data.ID = collect.ID;
data.size = collect.size;
MyCollectableData sd = NULL ;
Se ( este .stack.COUNT <3)
este .stack.push (dados);
Debug log ( "PILHA COUNT =" +
stack.COUNT.ToString ());
interruptor (stack.COUNT)
{
case 1:
este .lblStackBottom.text data.size.ToString = ();
break;
Caso 2:
este .lblStackMiddle.text =
data.size.ToString ();
break;
Caso 3:
este .lblStackTop.text data.size.ToString = ();
break;
}
}
}

página 167
Vahé Karamian
153
}
Se (stack.COUNT> = 3)
{
bool WIN = false ;
ArrayList tmp = new ArrayList ();
para ( int i = 0; i <= stack.COUNT + 1; i ++)
{
MyCollectableData d = ( MyCollectableData ) stack.pop ();
Debug log ( cadeia .format ( "Pop: {0}" , d.size));
tmp.Add (d);
}
se (((( MyCollectableData ) tmp [0]). de tamanho> (( MyCollecta-
bleData ) tmp [1]). size) && ((( MyCollectableData ) tmp [1]). size>
(( MyCollectableData ) tmp [2]). Size))
{
Debug log ( "GRANDE TRABALHO !!! Objectivo Concluído!" );
este .match = false ;
}
outro
{
este .butTryAgain.gameObject.SetActive ( verdadeiro );
}
}
#endregion
}
Nós completamos nosso projeto UI inicial para o Nível 1. Agora vamos
dar uma olhada em como implementar a interface do usuário para o nível 2.
Nível 2 - UI design
Para o Nível 2, o jogador teve que selecionar um gerador aleatório que
indicam que quarto ele ou ela tinha que visitar. Após a seleção foi feita,
o jogador foi dado um conjunto específico de tempo para ser capaz de visitar a sala.
Após a visita, o temporizador seria de descanso, eo quarto seria marcado
como visitado.
O nosso IU deve ser concebido de forma a capturar o estado do
ambiente a qualquer momento. Então, precisamos de uma maneira para exibir o
timer. Também seria bom para exibir o objetivo para o jogador; aquele
é que quarto ele ou ela tem que visitar. E, finalmente, deve haver uma maneira
para indicar se o jogador ganhou o jogo ou não, e como sempre uma maneira
para eles para repetir o jogo, como um reinício.

página 168
Unity 3D - Jogo de Programação Intro
154
Uma vez que existem algumas semelhanças entre a interface do usuário para o Nível 2 e
a interface do usuário para o Nível 1, podemos facilitar a vida copiando o Canvas
Gamebjects temos definido no Nível 1 e colá-los no Nível 2.
Obviamente, vamos fazer algum mudou, mas no geral ele vai nos dar uma
boa base para começar.
Figura 57 - Nível 2 Nível Concept
Vamos começar por implementar a interface do usuário do temporizador em primeiro lugar.
Queremos basi-
camente criar um novo elemento de painel com um elemento de texto associado e
ancorá-la para o canto superior direito da tela. Se bem se lembram, o script
que manipula o temporizador está ligado ao RoomSelection GameObject
eo próprio script é chamado RoomSelection.cs . Para exibir o timer,
teremos de criar uma referência para o rótulo e, basicamente, certifique-se
que ele está exibindo o valor adequado durante o ciclo de atualização.
Quando isso acontece, podemos também estabeleceu o objectivo de o jogador no
mesmo script. Seria preciso criar uma nova variável para fazer referência ao
Texto objectivo e, basicamente, atualizar o conteúdo com base no leitor de
selecção durante o jogo. Aqui está a lista de códigos para o novo script:
usando UnityEngine;
usando UnityEngine.UI;
usando System.Collections;
classe pública RoomSelection : MonoBehaviour

página 169
Vahé Karamian
155
{
pública GameObject playerCharacter = NULL ;
#region Variáveis UI
pública Texto lblTimer;
pública Texto lblObjective;
#endregion
// Use isso para inicialização
anular Iniciar ()
{
Se ( esse .lblTimer! = NULL )
{
este .lblTimer.text = "0" ;
}
Se ( esse .lblObjective! = NULL )
{
este .lblObjective.text = cadeia .format ( "Select Randomizer!" );
}
// Se o characte jogador não está definido em tempo de design
// Atribui-lo durante o tempo de execução antes do jogo começar
Se ( esse .playerCharacter == nulo )
{
este .playerCharacter = GameObject .FindGameObjectWithTag ( "Player" )
como GameObject ;
}
}
// MYtime será usada para dar a quantidade de tempo em segundos
// Para o jogador para encontrar o quarto !!!
public float Mytime = 33.0f;
private float endTime = 0.0f;
// Update é chamado uma vez por quadro
anular Update ()
{
este .transform.Rotate ( novo Vector3 (1, 1, 1), 1.0f);
Se ( esse .endTime> Tempo .time)
{
este .lblTimer.text = Mathf .CeilToInt ( este .endTime -
Tempo .time) .ToString ();
Debug log ( "Temporizador iniciado !!!" + Mathf .CeilToInt ( este .endTime -
Tempo .time) .ToString ());
}
else if ( esta .endTime == 0.0f)
{
este .lblTimer.text = "0" ;
; // Não fazer nada
}
outro
{
Debug log ( "Time Ended !!!" );

página 170
Unity 3D - Jogo de Programação Intro
156
este .playerCharacter.GetComponent < PlayerInput .> () game_over = verdadeiro ;
}
// Distância de seleção entre este objeto e o personagem do jogador
flutuador distância = Vector3 .distance ( este .transform.position, este .play-
erCharacter.transform.position);
Se (distância <2.0F)
{
#region RATO DE ENTRADA
se ( Input .mousePosition! = nulo && entrada .GetMouseButtonUp (0))
{
int color = Aleatório .Range (0, 3);
interruptor (cor)
{
caso 0:
{
este .transform.GetComponent < Renderer > (). material.color
= Cor .blue;
este .playerCharacter.GetComponent < PlayerIn-
colocar .> () ROOM_SELECTION = 0;
este .lblObjective.text = cadeia .format ( "Find Azul
Room " );
break;
}
case 1:
{
este .transform.GetComponent < Renderer > (). material.color
= Cor .Red;
este .playerCharacter.GetComponent < PlayerIn-
colocar .> () ROOM_SELECTION = 1;
este .lblObjective.text = cadeia .format ( "Find Red
Room " );
break;
}
Caso 2:
{
este .transform.GetComponent < Renderer > (). material.color
= Cor .Green;
este .playerCharacter.GetComponent < PlayerIn-
colocar .> () ROOM_SELECTION = 2;
este .lblObjective.text = cadeia .format ( "Find Verde
Room " );
break;
}
}
// Inicia temporizador
este .endTime = este .myTime + Tempo .time;
}
#endregion
}
}
public void ResetTimer ()

página 171
Vahé Karamian
157
{
este .endTime = 0.0f;
este .lblObjective.text = cadeia .format ( "Select Randomizer" );
}
}
Código Bloco 39 - Nível 2 Timer e código UI Objectivo
Quando você executa a cena agora, você verá uma tela semelhante à
Segue:
O próximo elemento UI queremos implementar é quando o jogador vis
seu quarto que é suposto encontrar. Uma vez que temos três quartos,
pode reutilizar o nosso Painel de Jogo existente de Nível 1. Nós apenas teria
para escrever um novo pedaço de código para atualizar o subtítulo de acordo com o ob-
jectivos para o Nível 2.
Para conseguir isso, vamos ter que atualizar vários arquivos de script.
Se bem se lembram, temos três scripts que são especificamente relacionados com
Nível 2: RoomSelection.cs , SlidingDoor.cs e PlayerInput.cs .
Se você olhar para os scripts, as principais atualizações estão realmente acontecendo
na RoomSelection.cs script eo PlayerInput.cs script. Sliding-
Door.cs está provocando uma função no PlayerInput.cs roteiro para indicar
o quarto foi visitada.

página 172
Unity 3D - Jogo de Programação Intro
158
No OnCollisionEnter () função dentro da SlidingDoor.cs
script, se estiverem reunidas as condições adequadas, o RoomVisited () função é
instou a PlayerInput.cs script. Então seria preciso atualizar essa
Scrip para refletir as informações corretas no Painel de Estado Objectivo
exibição.
Aqui está a lista para a revista RoomVisited () função no
PlayerInput.cs roteiros:
public void RoomVisited ( SlidingDoor quarto)
{
se (quarto! = NULL )
{
este .stack.push (quarto);
cadeia msg = cadeia .format ( "Room # {0} inserido, a contagem de pilha = {1}" ,
room.ROOM_NUMBER, este .stack.COUNT);
Debug log (msg);
#region usado para o elemento de interface do usuário
interruptor (room.ROOM_NUMBER)
{
caso 0:
{
este .lblStackTop.text = "Blue" ;
quebrar ;
}
Caso 1:
{
este .lblStackBottom.text = "Red" ;
quebrar ;
}
Caso 2:
{
este .lblStackMiddle.text = "Green" ;
quebrar ;
}
}
#endregion
Se ( este .stack.COUNT> = 3)
{
Debug log ( "VOCÊ GANHA !!!" );
este .lblObjective.text = "Você ganhou !!!" ;
este .GAME_OVER = verdadeiro ;
este .butTryAgain.gameObject.SetActive ( verdadeiro );
}
}

página 173
Vahé Karamian
159
}
Código Block 40 - função Revista RoomVisited () para o Nível 2
Repare que nós adicionamos uma instrução switch para determinar qual sala
foi visitado e atualizar o botão de legendas no painel de conformidade.
Uma vez que essa função também determina se o jogador tiver completado o nível
com sucesso, temos também incluiu uma linha para permitir que o Try Again mas-
tonelada que vai ser utilizado para repetir o jogo.
Agora nós também precisamos fazer algumas alterações nos RoomSelection.cs
script. Aqui está o trecho para as atualizações que tínhamos de fazer para que script:
Se ( esse .endTime> Tempo .time)
{
este .lblTimer.text = Mathf .CeilToInt ( este .endTime -
Tempo .time) .ToString ();
Debug log ( "Temporizador iniciado !!!" + Mathf .CeilToInt ( este .endTime -
Tempo .time) .ToString ());
}
else if ( esta .endTime == 0.0f)
{
este .lblTimer.text = "0" ;
; // Não fazer nada
}
outro
{
Debug log ( "Time Ended !!!" );

página 174
Unity 3D - Jogo de Programação Intro
160
este .playerCharacter.GetComponent < PlayerInput .> () game_over = verdadeiro ;
este .lblObjective.text = "VOCÊ PERDER !!!" ;
este .lblTimer.text = "0" ;
este .playerCharacter.GetComponent < PlayerInput > (). butT-
ryAgain.gameObject.SetActive ( verdadeiro );
}
Temos agora concluída a implementação da interface do usuário para Nível 1 e
Nível 2 . Vamos dar uma olhada na implementação UI de Nível 3 .
Nível 3 - UI design
Para o nível 3, que seria necessário para criar um tipo totalmente diferente de um
UI. No nível 3, o nosso objectivo é criar uma instalação de armazenamento que será
recolher e armazenar recursos para nós. O objectivo do nível é para o
jogador para matar o adversário e para o adversário para matar o jogador. Quem-
sempre faz isso primeiro é o vencedor.
Figura 58 - Nível 3 Concept UI
Nossa UI terão de ser concebidos de forma a dar-nos informações
sobre o estado dos nossos recursos, a nossa saúde e também a próxima col-
recurso lectable. Seria bom também ter um displayrelevant wayto
página 175
Vahé Karamian
161
mensagens para o jogador. Por exemplo, certificando-se que eles sabem que precisam
para criar uma instalação de armazenamento para recolher recursos.
Nós também gostaríamos de mostrar a saúde do nosso adversário, mas não
necessariamente os seus recursos. Mesmo que isso é bem possível fazer
se optar por incluí-lo no projeto.
O código de atualização principal para a saúde, o inventário e as mensagens serão
estar ocorrendo no PlayerInput.cs arquivo script. Aqui está um trecho de código
do código comprovativos necessários para a configuração inicial dos rótulos em cima
inicialização do nível:
// Variáveis para o nível 3 UI
pública Texto lblHealth;
públicas texto lblResources;
públicas texto lblMessages;
#endregion
...
private void ResetLevel3UI ()
{
Se ( esse .lblHealth! = NULL )
este .lblHealth.text = cadeia .format ( "{0} / 100" , este .Saúde);
se ( este .lblResources! = NULL )
este .lblResources.text = este .NUM_BULLETS.ToString ();
se ( este .lblMessages! = NULL )
este .lblMessages.text = "Use o espaço-CHAVE a cair Storage Facility
para começar a recolher recursos ". ;
}
Uma vez que largar a instalação de armazenamento, podemos usar o Painel de Mensagem
para exibir o status do coletor de recursos. A fim de executar este
tarefa, seria preciso executar várias etapas-chave.
Seria preciso atualizar o painel de mensagem cada vez que um
deste ações acontecem:
1. instalações de armazenamento é ignorado
2. Unidade Collector está viajando para a área de Recursos
3. Unidade Collector está viajando para instalações de armazenamento
4. Unidade Collector está a carregar recursos.
5. Unidade Collector está descarregando recursos.

página 176
Unity 3D - Jogo de Programação Intro
162
Os scripts que irão lidar com as atualizações de interface do usuário são: MyStorage.cs , meu-
Collector.cs , MyResource.cs e, claro, PlayerInput.cs scripts. o
seguinte listagem de código irá exibir o script completo para MyStorage.cs , meu-
Collector.cs e MyResource.cs roteiros:
usando UnityEngine;
usando System.Collections;
classe pública MyStorage : MonoBehaviour
{
pública GameObject myCollector;
privada GameObject collectorObj;
privada GameObject playerCharacter;
// variáveis para temporizador
public float Mytime = 3.0f;
private float endTime = 0.0f;
// Use isso para inicialização
anular Iniciar ()
{
Vetor3 POS = novo vetor3 ( este .transform.position.x + 1, 2,
este .transform.position.z + 1);
este .collectorObj = GameObject .Instantiate ( este .myCollector, pos,
este .transform.rotation) como GameObject ;
este .collectorObj.GetComponent < MyCollector > (). MyStorage = este .gameOb-
jecto;
este .playerCharacter = GameObject .FindGameObjectWithTag ( "Player" ) como
GameObject ;
este .playerCharacter.GetComponent < PlayerInput > (). = lblMessages.text
"Storage Facility Criado!" ;
}
// Update é chamado uma vez por quadro
anular Update ()
{
Se ( esse .endTime> Tempo .time)
{
cadeia msg = cordas .format ( "Descarregar Recursos: {0}" ,
Mathf .CeilToInt ( este .endTime - Tempo .time));
este .collectorObj.GetComponent < MyCollector > () UpdateMessage (msg).;
}
else if ( esta .endTime == 0.0f)
{
; // Não fazer nada
}
outro
{
este .endTime = 0.0f;

página 177
Vahé Karamian
163
este .collectorObj.GetComponent < MyCollector .> () GOTO_RESOURCE = verdadeiro ;
int collectedResources = este .collectorObj.GetComponent < MyCollec-
tor > () UNINTS_COLLECTED.;
// Adiciona bala personagem do jogador
este .playerCharacter.GetComponent < PlayerInput > (). = + NUM_BULLETS
collectedResources;
este .playerCharacter.GetComponent < PlayerInput > () UpdateResources ().;
}
}
// Essa função manipula a colisão de aceleradores como um gatilho
vazio OnCollisionEnter ( Collision c)
{
Se (c.transform.tag.Equals ( "CollectorUnit" ))
{
c.transform.GetComponent < MyCollector .> () GOTO_STORAGE = false ;
// Inicia temporizador
este .endTime = este .myTime + Tempo .time;
cadeia msg = cordas .format ( "Descarregar Recursos: {0}" ,
Mathf .CeilToInt ( este .endTime - Tempo .time));
c.transform.GetComponent < MyCollector > () UpdateMessage (msg).;
}
}
}
Código Bloco 41 - Listagem MyStorage.cs para UI design
usando UnityEngine;
usando UnityEngine.UI;
usando System.Collections;
classe pública MyCollector : MonoBehaviour
{
pública GameObject myResource;
públicas GameObject MyStorage;
bool pública GOTO_RESOURCE;
bool pública GOTO_STORAGE;
int pública UNINTS_COLLECTED;
privada GameObject playerCharacter;
// Use isso para inicialização
anular Iniciar ()
{
este .myResource = GameObject .FindGameObjectWithTag ( "ResourcePlayer" )
como GameObject ;
este .GOTO_RESOURCE = verdadeiro ;
este .GOTO_STORAGE = false ;

página 178
Unity 3D - Jogo de Programação Intro
164
este .UNINTS_COLLECTED = 0;
este .playerCharacter = GameObject .FindGameObjectWithTag ( "Player" ) como
GameObject ;
}
// Update é chamado uma vez por quadro
anular Update ()
{
Se ( este .GOTO_RESOURCE)
{
// Goto a localização dos recursos para a coleta
Vector3 refillHeading = este .myResource.transform.position -
este .transform.position;
refillHeading.Normalize ();
// Usar a função Quaternion Slerp para fazer transição suave ...
este .transform.rotation =
Quaternion .Slerp (transform.rotation,
Quaternion .LookRotation (refillHeading), 10 *
Tempo .deltaTime);
este .transform.Translate ( Vector3 .forward * Tempo .deltaTime);
int distance = Mathf .CeilToInt ( Vector3 .distance ( este .transform.po-
sição, este .myResource.transform.position));
este .playerCharacter.GetComponent < PlayerInput > (). = lblMessages.text
cadeia .format ( "Distância para o recurso {0}" , a distância);
}
Se ( este .GOTO_STORAGE)
{
Vector3 refillHeading = este .myStorage.transform.position -
este .transform.position;
refillHeading.Normalize ();
// Usar a função Quaternion Slerp para fazer transição suave ...
este .transform.rotation =
Quaternion .Slerp (transform.rotation,
Quaternion .LookRotation (refillHeading), 10 *
Tempo .deltaTime);
este .transform.Translate ( Vector3 .forward * Tempo .deltaTime);
int distance = Mathf .CeilToInt ( Vector3 .distance ( este .transform.po-
sição, este .myResource.transform.position));
este .playerCharacter.GetComponent < PlayerInput > (). = lblMessages.text
cadeia .format ( "Distância para armazenamento {0}" , a distância);
}
}
public void UpdateMessage ( string de mensagem)

página 179
Vahé Karamian
165
{
este .playerCharacter.GetComponent < PlayerInput > (). = lblMessages.text
mensagem;
}
}
Código Bloco 42 - Listagem MyCollector.cs para UI design
usando UnityEngine;
usando System.Collections;
classe pública MyResource : MonoBehaviour
{
pública GameObject collectorUnit;
// variáveis para temporizador
public float Mytime = 3.0f;
private float endTime = 0.0f;
// Use isso para inicialização
anular Iniciar ()
{
}
// Update é chamado uma vez por quadro
anular Update ()
{
Se ( esse .endTime> Tempo .time)
{
cadeia msg = cadeia .format ( "cobrança dos recursos: {0}" ,
Mathf .CeilToInt ( este .endTime - Tempo .time));
este .collectorUnit.GetComponent < MyCollector > () UpdateMessage (msg).;
}
else if ( esta .endTime == 0.0f)
{
; // Não fazer nada
}
outro
{
este .endTime = 0.0f;
este .collectorUnit.GetComponent < MyCollector .> () GOTO_STORAGE = verdadeiro ;
este .collectorUnit.GetComponent < MyCollector > (). = UNINTS_COLLECTED
1;
}
}
// Essa função manipula a colisão de aceleradores como um gatilho
vazio OnTriggerEnter ( Collider c)
{
Se (c.tag.Equals ( "CollectorUnit" ))
{
c.GetComponent < MyCollector .> () GOTO_RESOURCE = false ;
este .collectorUnit = c.gameObject;
// Inicia temporizador
este .endTime = este .myTime + Tempo .time;

página 180
Unity 3D - Jogo de Programação Intro
166
cadeia msg = cadeia .format ( "cobrança dos recursos: {0}" ,
Mathf .CeilToInt ( este .endTime - Tempo .time));
este .collectorUnit.GetComponent < MyCollector > () UpdateMessage (msg).;
}
}
}
Código Bloco 43 - Listagem MyResource.cs para UI design
Seria preciso atualizar o rótulo de recursos e o Selo de Saúde
cada vez que uma destas ações acontecem:
1. Recurso é carregada nas instalações de armazenamento.
2. O jogador é atingido pelo inimigo.
Se você tem prestado atenção e testar o tempo de código
discuti-lo no livro, você deve ter notado que há alguns
pequenos bugs no Nível 3. Em primeiro lugar, nós nunca implementou uma maneira de capturar
A saúde do jogador ou o inimigo. Segundo, quando os recursos
foram recolhidos e levados de volta para a instalação de armazenamento, você pode ter
notado que os incrementos dos recursos não foi realizada cor-
tamente após a primeira coleção. Isto é porque nós nunca repor o
variável na Unidade de coletor de volta a 0 após a descarga.
Outra questão aqui é que nós não implementaram uma maneira de parar
o jogo! Precisamos ter certeza de que quando o jogador ou o inimigo
morre, paramos todos os objetos em movimento dentro do jogo e exibir o bom
mensagem. As seguintes listagens colocar tudo junto para fazer Nível
3 concluir tanto do UIside do desenvolvimento e também o jogo
lado a mecânica do desenvolvimento.
Lista completa para MyStorage.cs :
usando UnityEngine;
usando System.Collections;
classe pública MyStorage : MonoBehaviour
{
pública GameObject myCollector;
privada GameObject collectorObj;
privada GameObject playerCharacter;

página 181
Vahé Karamian
167
// variáveis para temporizador
public float Mytime = 3.0f;
private float endTime = 0.0f;
// Use isso para inicialização
anular Iniciar ()
{
Vetor3 POS = novo vetor3 ( este .transform.position.x + 1, 2,
este .transform.position.z + 1);
este .collectorObj = GameObject .Instantiate ( este .myCollector, pos,
este .transform.rotation) como GameObject ;
este .collectorObj.GetComponent < MyCollector > (). MyStorage = este .gameOb-
jecto;
este .playerCharacter = GameObject .FindGameObjectWithTag ( "Player" ) como
GameObject ;
este .playerCharacter.GetComponent < PlayerInput > (). = lblMessages.text
"Storage Facility Criado!" ;
}
// Update é chamado uma vez por quadro
anular Update ()
{
se (! este .playerCharacter.GetComponent < PlayerInput > (). game_over)
{
Se ( esse .endTime> Tempo .time)
{
cadeia msg = cordas .format ( "Descarregar Recursos: {0}" ,
Mathf .CeilToInt ( este .endTime - Tempo .time));
este .collectorObj.GetComponent < MyCollector > (). UpdateMes-
sage (msg);
}
else if ( esta .endTime == 0.0f)
{
; // Não fazer nada
}
outro
{
este .endTime = 0.0f;
este .collectorObj.GetComponent < MyCollector > (). = GOTO_RESOURCE
verdade ;
int collectedResources = este .collectorObj.GetComponent < MyCol-
lector .> () UNINTS_COLLECTED;
este .collectorObj.GetComponent < MyCollector > (). = UNINTS_COLLECTED
0;
// Adiciona bala personagem do jogador
este .playerCharacter.GetComponent < PlayerInput > (). = + NUM_BULLETS
collectedResources;
este .playerCharacter.GetComponent < PlayerInput > (). Up-
dateResources ();
}
}

página 182
Unity 3D - Jogo de Programação Intro
168
}
// Essa função manipula a colisão de aceleradores como um gatilho
vazio OnCollisionEnter ( Collision c)
{
Se (c.transform.tag.Equals ( "CollectorUnit" ))
{
c.transform.GetComponent < MyCollector .> () GOTO_STORAGE = false ;
// Inicia temporizador
este .endTime = este .myTime + Tempo .time;
cadeia msg = cordas .format ( "Descarregar Recursos: {0}" ,
Mathf .CeilToInt ( este .endTime - Tempo .time));
c.transform.GetComponent < MyCollector > () UpdateMessage (msg).;
}
}
}
A listagem completa para MyCollector.cs :
usando UnityEngine;
usando UnityEngine.UI;
usando System.Collections;
classe pública MyCollector : MonoBehaviour
{
pública GameObject myResource;
públicas GameObject MyStorage;
bool pública GOTO_RESOURCE;
bool pública GOTO_STORAGE;
int pública UNINTS_COLLECTED;
privada GameObject playerCharacter;
// Use isso para inicialização
anular Iniciar ()
{
este .myResource = GameObject .FindGameObjectWithTag ( "ResourcePlayer" )
como GameObject ;
este .GOTO_RESOURCE = verdadeiro ;
este .GOTO_STORAGE = false ;
este .UNINTS_COLLECTED = 0;
este .playerCharacter = GameObject .FindGameObjectWithTag ( "Player" ) como
GameObject ;
}

página 183
Vahé Karamian
169
// Update é chamado uma vez por quadro
anular Update ()
{
se (! este .playerCharacter.GetComponent < PlayerInput > (). game_over)
{
Se ( este .GOTO_RESOURCE)
{
// Goto a localização dos recursos para a coleta
Vector3 refillHeading = este .myResource.transform.position -
este .transform.position;
refillHeading.Normalize ();
// Usar a função Quaternion Slerp para fazer transição suave ...
este .transform.rotation =
Quaternion .Slerp (transform.rotation,
Quaternion .LookRotation (refillHeading), 10 *
Tempo .deltaTime);
este .transform.Translate ( Vector3 .forward * Tempo .deltaTime);
int distance = Mathf .CeilToInt ( Vector3 .distance ( este .trans-
form.position, este .myResource.transform.position));
este .playerCharacter.GetComponent < PlayerInput > (). lblMes-
sages.text = cadeia .format ( "Distância para o recurso {0}" , a distância);
}
Se ( este .GOTO_STORAGE)
{
Vector3 refillHeading = este .myStorage.transform.position -
este .transform.position;
refillHeading.Normalize ();
// Usar a função Quaternion Slerp para fazer transição suave ...
este .transform.rotation =
Quaternion .Slerp (transform.rotation,
Quaternion .LookRotation (refillHeading), 10 *
Tempo .deltaTime);
este .transform.Translate ( Vector3 .forward * Tempo .deltaTime);
int distance = Mathf .CeilToInt ( Vector3 .distance ( este .trans-
form.position, este .myResource.transform.position));
este .playerCharacter.GetComponent < PlayerInput > (). lblMes-
sages.text = cadeia .format ( "Distância para armazenamento {0}" , a distância);
}
}
}
public void UpdateMessage ( string de mensagem)
{
este .playerCharacter.GetComponent < PlayerInput > (). = lblMessages.text
mensagem;
}
}

página 184
Unity 3D - Jogo de Programação Intro
170
Lista completa de MyResource.cs :
usando UnityEngine;
usando System.Collections;
classe pública MyResource : MonoBehaviour
{
pública GameObject collectorUnit;
// variáveis para temporizador
public float Mytime = 3.0f;
private float endTime = 0.0f;
// Use isso para inicialização
anular Iniciar ()
{
}
// Update é chamado uma vez por quadro
anular Update ()
{
Se ( esse .endTime> Tempo .time)
{
cadeia msg = cadeia .format ( "cobrança dos recursos: {0}" ,
Mathf .CeilToInt ( este .endTime - Tempo .time));
este .collectorUnit.GetComponent < MyCollector > () UpdateMessage (msg).;
}
else if ( esta .endTime == 0.0f)
{
; // Não fazer nada
}
outro
{
este .endTime = 0.0f;
este .collectorUnit.GetComponent < MyCollector .> () GOTO_STORAGE = verdadeiro ;
este .collectorUnit.GetComponent < MyCollector > (). = UNINTS_COLLECTED
1;
}
}
// Essa função manipula a colisão de aceleradores como um gatilho
vazio OnTriggerEnter ( Collider c)
{
Se (c.tag.Equals ( "CollectorUnit" ))
{
c.GetComponent < MyCollector .> () GOTO_RESOURCE = false ;
este .collectorUnit = c.gameObject;
// Inicia temporizador
este .endTime = este .myTime + Tempo .time;
cadeia msg = cadeia .format ( "cobrança dos recursos: {0}" ,
Mathf .CeilToInt ( este .endTime - Tempo .time));
este .collectorUnit.GetComponent < MyCollector > () UpdateMessage (msg).;

página 185
Vahé Karamian
171
}
}
}
Para os scripts inimigas, MyStorageEnemy.cs , MyCollec-
torEnemy.cs e MyResourceEnemy.cs são todos semelhantes ao jogador do
roteiros, apenas as referências têm de ser atualizado para apontar para o inimigo
roteiros e ou pré-fabricados.
No entanto, aqui é o MyEnemy.cs script que é único:
usando UnityEngine;
usando UnityEngine.UI;
usando System.Collections;
classe pública MyEnemy : MonoBehaviour
{
públicas GameObject MyBase;
públicas GameObject MyStorage;
privada GameObject myStorageObj;
pública GameObject MyEnemy;
pública GameObject myBullet;
pública GameObject myGun;
public int NUM_BULLETS;
// variáveis para temporizador
public float Mytime = 5.0f;
private float endTime = 0.0f;
bool pública ATAQUE;
bool pública SCOUT;
pública Transform [] scoutPoints;
private int nextPointIndex;
bool pública game_over;
int privada de saúde;
pública Texto lblHealth;
// Use isso para inicialização
anular Iniciar ()
{
este .NUM_BULLETS = 1;
este .ATTACK = verdadeiro ;

página 186
Unity 3D - Jogo de Programação Intro
172
este .myEnemy = GameObject .FindGameObjectWithTag ( "Player" ) como GameOb-
jecto ;
// Inicia temporizador
este .endTime = este .myTime + Tempo .time;
este .nextPointIndex = 0;
este .GAME_OVER = false ;
este .Saúde = 100;
Se ( esse .lblHealth! = NULL )
este .lblHealth.text = cadeia .format ( "{0} / 100" , este .Saúde);
}
private float VELOCIDADE = 2.0F;
// Update é chamado uma vez por quadro
anular Update ()
{
se (! este .GAME_OVER)
{
Se ( esse .myStorageObj == nulo )
{
Se ( esse .endTime < Tempo .time)
{
// Soltar o armazenamento
Vetor3 POS = novo vetor3 ( este .transform.position.x + 1, 2,
este .transform.position.z + 1);
este .myStorageObj = GameObject .Instantiate ( este .myStorage,
pos, este .myStorage.transform.rotation) como GameObject ;
este .endTime = 0.0f;
}
}
Se ( este .NUM_BULLETS> 1)
{
este .ATTACK = verdadeiro ;
}
outro
{
este .ATTACK = false ;
}
// Procurar o jogador para atacar
Se ( este .ATTACK)
{
Vector3 refillHeading = este .myEnemy.transform.position -
este .transform.position;
refillHeading.Normalize ();
// Usar a função Quaternion Slerp para fazer transição suave ...
este .transform.rotation =
Quaternion .Slerp (transform.rotation,

página 187
Vahé Karamian
173
Quaternion .LookRotation (refillHeading), 10 *
Tempo .deltaTime);
este .transform.Translate ( Vector3 .forward * Tempo .deltaTime *
este .SPEED);
Se ( Vector3 .distance ( este .myEnemy.transform.position,
este .transform.position) <5.0f)
{
Se ( este .NUM_BULLETS> 0)
{
Se ( esse .endTime < Tempo .time)
{
GameObject bala = GameObject .Instantiate ( este .myBul-
deixei,
este .myGun.transform.position, este .myGun.trans-
form.rotation) como GameObject ;
bullet.GetComponent < corpo rígido > (). velocidade = trans-
form.TransformDirection ( novo Vector3 (0, 0, 10.0f));
GameObject .Destroy (bala, 3.0f);
// Inventário diminuição
este .NUM_BULLETS--;
// Definir o temporizador antes da próxima tacada
este .endTime = este .myTime + Tempo .time;
}
}
}
}
outro
{
Se ( este .scoutPoints.Length> 0)
{
Vector3 refillHeading = esta .scoutPoints [nextPointIndex] .po-
sição - este .transform.position;
refillHeading.Normalize ();
// Usar a função Quaternion Slerp para fazer uma transição suave
...
este .transform.rotation =
Quaternion .Slerp (transform.rotation,
Quaternion .LookRotation (refillHeading),
10 * Tempo .deltaTime);
este .transform.Translate ( Vector3 .forward * Tempo .deltaTime);
Se ( Vector3 .distance ( este .transform.position, este .scout-
Pontos [nextPointIndex] .position) <0.25f)
{
este .nextPointIndex + = 1;
Se ( esse .nextPointIndex> = este .scoutPoints.Length)
{

página 188
Unity 3D - Jogo de Programação Intro
174
este .nextPointIndex = 0;
}
}
}
}
}
}
vazio OnCollisionEnter ( Collision c)
{
se (c.transform.tag.Equals ( "bullet" ))
{
Destroy (c.gameObject);
este .Saúde - = 25;
este .lblHealth.text = cadeia .format ( "{0} / 100" , este .Saúde);
Se ( este .Saúde <= 0)
{
este .GAME_OVER = verdadeiro ;
este .myEnemy.GetComponent < PlayerInput > (). = game_over
este .GAME_OVER;
}
}
}
}
Vimos agora a implementação de algumas mecânicas de jogo
temos discutido no capítulo Mecânica de jogo e neste capítulo
vimos como criar elementos de interface de usuário relacionados que vai
apoiar a mecânica do jogo.
Enquanto você estava estudando este capítulo e passando por cima da UI de-
sinais, você pode ter pensado para si mesmo sobre a simplicidade deles.
Isso é intencional como este livro é voltado para programadores de jogos /
desenvolvedores. Há mais ênfase na codificação e scripting e
menos sobre os gráficos. Dito isto, para aqueles que são mais criativos,
você pode ter o que você aprendeu neste livro e aplicar sua própria
toque criativo.
Há algumas pequenas melhorias que podemos fazer melhorar o nosso usuário
design de interface mais. Isso é abordado na próxima seção.

página 189
Vahé Karamian
175
Melhorar a interface do usuário
Nesta seção, terá de nível 3 e fazer algumas adições ao
o design da interface do usuário. O layout principal não será a mudança, mas o que eu faria
quer demonstrar é a facilidade de como usar texturas para melhorar a
olhar e sentir dos elementos de interface do usuário.
Figura 59 - Outra amostra UI
Agora que você está familiarizado com os conceitos básicos de design de interface do usuário ea
interface do usuário
Arquitetura em Unity, que pode levá-lo um pouco mais. De um modo geral,
quando você está projetando e desenvolvendo o seu jogo, você vai ter um
equipe de pessoas dedicadas apenas para a criação de conteúdo e modelos gráficos
para os fins do projecto. Você estará trabalhando com eles entregar
mão para incorporar o seu design elegante para o ambiente do jogo.
A maior parte da UI terá altamente polido 2D textura gráfica que
pode ser usado para fornecer temas visualmente atraente para o jogador. eu quero
para mostrar-lhe como é fácil de incorporar essas texturas na nova interface
Arquitetura em Unity 5.

página 190
Unity 3D - Jogo de Programação Intro
176
Considere nosso design de interface do usuário para o nível 3:
O layout da interface do usuário é muito bom para os fins deste demonstrado
stração. O que pode melhorar é o aspecto visual da interface do usuário. Um dos
grandes mudanças que podemos aplicar é uma textura para o elemento Panel UI. No
momento estamos usando todas as texturas padrão que vêm com o Unity
e eles trabalham muito bem para prototipagem, o que nós fizemos. Agora, vamos aplicar
algumas texturas mais interessante.
Para esta parte para funcionar corretamente, você terá que realmente tem um bom
compreensão de como as dimensões de sua interface do usuário e texturas. Isso vai ajudar na
tornando texturas mais finas. No nosso caso, temos três painéis gostaríamos
para aplicar uma textura para:
 Painel de Status - (333px X 50 pixels)
 Painel de Mensagens - (444px X 50 pixels)
 Painel de Saúde Enemy - (135px X 50 pixels)
As dimensões de cada painel é listado ao lado do item. Nós vamos
usar essas dimensões para criar nossas texturas. Como você já sabe, o meu

página 191
Vahé Karamian
177
habilidades criativas não vão ser tão agradável como o seu. Tendo dito isto,
aqui estão as texturas eu vim acima com para cada Painel:
Figura 60 - Background Painel de Estado
Figura 61 - Mensagem Fundo do painel
Figura 62 - Fundo do painel Inimigo
Depois de criar sua textura desejada, será necessário importá-lo
em Unity. Você pode simplesmente usar o sistema de arquivos em seu Sys operacional
TEM copiar e colar os arquivos para a pasta de ativos dentro do seu
Pasta do projeto. Eu coloquei minhas texturas no seguinte diretório:
<Pasta do projeto> / Assets / Texturas / CH5 /
Depois de importar suas texturas, você vai precisar para realizar algumas
configurações nas texturas. Uma vez que estas vão ser as texturas da IU,
precisamos mudar o tipo de textura de textura de Sprite (2D e
UI) . Depois de selecionar o bom tipo de textura, você terá que clicar

página 192
Unity 3D - Jogo de Programação Intro
178
o Aplicar botão para que as alterações tenham efeito. Executar esta para todos
sua interface texturas.
NOTA: Você vai notar que há mais propriedades e opções
disponível. Vou deixar que você estudá-los em seu próprio país. Estas propriedades serão
vêm em handier em jogos baseados em 2D Sprite.
Agora é hora de aplicar a nossa primeira textura. Vá em frente e selecione
o estado do painel elemento UI da Janela Hierarquia no Nível 3 .
Dê uma olhada na janela Inspetor , e você vai notar que há
uma imagem Componentes e que é tem uma propriedade para definir a Imagem
Fonte . Arraste e solte a textura projetado para o Painel de Estado em
esta propriedade. Execute o mesmo para cada um o outro painel temos
definida na cena. Seu UI deve ficar parecido com o seguinte
agora:
Figura 63 - Painel de texturas aplicadas ao nível 3
Portanto, este parece mais agradável, em seguida, o padrão texturas lisas que tivemos ante-
amente. A próxima coisa que eu gostaria de fazer é fornecer alguns ícones para o
imagens que colocamos como espaço reservado. Se você lembrar, as nossas imagens têm uma
dimensão de 40x40 pixels. Nós tecnicamente precisa ícones, um será

página 193
Vahé Karamian
179
utilizado tanto para a saúde do jogador e saúde do inimigo, eo outro
será utilizado para o inventário do jogador.
O processo para aplicar os ícones vão ser semelhantes, primeiro você
Será necessário criar os ícones desejados, então você terá que importá-los
em seu projeto, em seguida, configurá-los para ser do tipo Sprite , e
Finalmente, você precisará selecionar o elemento de interface do usuário, neste caso, a Imagem
elemento de interface do usuário para a saúde do jogador e o elemento UI Imagem para a
A saúde do inimigo da Janela Hierarquia , e na Imagem Compo-
nente , aplicar a textura para a propriedade Image Source. O resultado é:
Figura 64 - Nível 3 UI Enhancement
Como você pode ver, mesmo um simples aumento na UI terá um
grande impacto sobre a aparência geral do jogo.
Uma última melhoria eu gostaria de ilustrar para a UI é a
capacidade de exibir informações no espaço do mundo . Algumas das infor-
mações que você pode querer considerar para uma exibição Space World seria
Elementos de UI para GameObjects específicos.

página 194
Unity 3D - Jogo de Programação Intro
180
Por exemplo, seria bom para mostrar uma barra de saúde no leitor
caracteres, o que inclui tanto o jogador e também o inimigo. Isto é
realmente muito facilmente realizável na nova arquitectura UI dentro da Unidade.
Vamos dar uma olhada em como podemos implementar esse recurso para o nosso jogador.
Obviamente, precisamos ter um novo conjunto de objeto Canvas. o recém-
objeto Canvas criado será anexado ao nosso personagem do jogador
GameObject, um filho do personagem do jogador (PC). É também terá a sua
Modo de renderização definida como Space World . A maneira mais simples para criar este novo
Canvas é botão direito do mouse no PC e selecione ( UI-> Canvas ). Uma vez o
tela é criado, você precisará modificar várias propriedades, o primeiro
é o modo de renderização , vá em frente e defini-lo como Space World . O próximo mo-
ification será no Rect Transform Component. Você quer fazer
Certifique-se a tela é relativo ao PC em todos os momentos, ea melhor maneira de fazer
por isso, ter certeza de que ele está posicionado corretamente.
Figura 65 - Propriedades de lona Space World
Em primeiro lugar, mudar as Pos X e Pos Y propriedades para o Rect Transform
a 0 e 0 , respectivamente. Isto irá certificar-se de que você está alinhado com o
Centro do PC. A próxima propriedade de mudar seria a largura e
a altura da tela. Isso vai depender do que você está GameObject
anexar a tela para e também a finalidade do seu espaço Can- Mundial
vas. Neste caso, gostaríamos de apresentar apenas uma barra de saúde, portanto,

página 195
Vahé Karamian
181
que não precisa de muito espaço. Também vamos dar uma olhada na Escala cor-
erty e usá-lo para escalar os Canvas sem perder qualidade.
Dê uma olhada na Figura 65 para ver as propriedades que estabeleci para a minha
projeto. O resultado é o seguinte captura de tela:
O resto é como antes, precisamos de uma maneira para criar uma barra de saúde. o
maneira mais fácil é para representar a barra de saúde é com três imagens.
Uma das imagens irá representar a fronteira, e os outros dois im-
as idades vão representar a saúde real.
Manter as coisas simples, aqui está como eu quero a minha barra de saúde para se parecer com:
página 196
Unity 3D - Jogo de Programação Intro
182
Figura 66 - Conceito UI para Bar Saúde
A hierarquia para o PC e lona são mostrados na seguinte
figura:
Figura 67 - World Espaço Canvas Hierarquia

página 197
Vahé Karamian
183
O próximo passo é criar o código para gerenciar a barra de saúde. Nós
seria necessário uma referência ao healthBarFG elemento UI Imagem. Nós
seria necessário modificar o script PlayerInput.cs para atualizar corretamente o
Bar saúde. Aqui está o código parcial listando lidar com a atualização de
o elemento Health Bar UI:
private void ResetLevel3UI ()
{
Se ( esse .lblHealth! = NULL )
este .lblHealth.text = cadeia .format ( "{0} / 100" , este .Saúde);
se ( este .lblResources! = NULL )
este .lblResources.text = este .NUM_BULLETS.ToString ();
se ( este .lblMessages! = NULL )
este .lblMessages.text = "Use o espaço-CHAVE a cair Storage Facility
para começar a recolher recursos ". ;
Se ( esse .imgHealthBar! = NULL )
{
este .imgHealthBar.fillAmount = ( este .Saúde / 100.0f);
}
}
Actualizado () OnCollisionEnter função:
vazio OnCollisionEnter ( Collision c)
{
se (c.transform.tag.Equals ( "bullet" ))
{
Destroy (c.gameObject);
este .Saúde - = 25;
este .lblHealth.text = cadeia .format ( "{0} / 100" , este .Saúde);
Se ( esse .imgHealthBar! = NULL )
{
este .imgHealthBar.fillAmount = ( este .Saúde / 100.0f);
}
Se ( este .Saúde <= 0)
{
este .GAME_OVER = verdadeiro ;
este .myEnemy.GetComponent < MyEnemy > () = game_over. este .GAME_OVER;
Se ( esse .imgHealthBar! = NULL )
{
este .imgHealthBar.fillAmount = 0.0f;
}
}
}
}

página 198
Unity 3D - Jogo de Programação Intro
184
Você já viu uma boa parte de como incorporar UI ele-
mentos dentro do seu ambiente de jogo. As ferramentas são básicos, mas a capacidade
para criar e melhorar sobre os blocos de construção são grandes. Com alguma cria-
tividade e imaginação você pode obter uma utilização mais sofisticada
interfaces.
Uma outra modificação que eu faria na barra de saúde é torná-lo
semitransparente. No momento em que está bloqueando o direito GameObjects
em frente à câmara principal, e isso é irritante. Para aplicar transparentes
rência para a barra de saúde simplesmente selecione o elemento de interface do usuário e da Cor
Picker reduzir o canal Alpha para todas as imagens para 100. Também é possível
aplicar a transparência antes de importar as imagens em Unity.
Como um desafio ver se você pode criar uma carga visual e descarregamento
elemento de UI para o coletor.

página 199
Vahé Karamian
185
Capítulo 6 - Criando Battleship
Contexto histórico
O jogo de Battleship é pensado para ter suas origens no Francês
jogo L'Attaque jogado durante a Primeira Guerra Mundial I. O jogo é dito ter
foi interpretado por oficiais russos antes da Primeira Guerra Mundial O primeiro comercialmente
versão oficial do jogo foi Salvo, publicado em 1931 nos Estados
Unidos pela empresa Starex. Outras versões do jogo foram impressos
na década de 1930 e 1940, incluindo combate do Strathmore Empresa:
O Jogo Battleship, de Milton Bradley bordos: A Game of Naval
Estratégia e Combate Guerra Naval de Maurice L. Freedman.
Figura disposição da amostra 68-Grid
Battleship foi um dos primeiros jogos a ser produzido como um com-
putador jogo, com uma versão a ser lançado para o Z80 Compucolor em
1979. Muitas edições do computador do jogo foram produzidos desde então.
Em Jogos Clubhouse para o Nintendo DS, Battleship é conhecido como Grade
Ataque. É jogado em uma grade 8 × 8, e inclui ligeiras variações, tais
medida que o jogo 4-jogador, vários tamanhos e formas de navios, bem como a op-
ção para tornar os navios tocam.

página 200
Unity 3D - Jogo de Programação Intro
186
game Play
O jogo é jogado em quatro redes, dois para cada jogador. as grades
são tipicamente quadrado - geralmente 10 × 10 - e os quadrados individuais no
grade são identificados pela letra e número. Em uma grade os arranjos jogador
navios e grava os tiros bythe oponente. Por outro grade do jogador
registra suas / seus próprios tiros.
Antes do jogo começar, cada jogador secretamente arranja seus navios em
sua rede primária. Cada navio ocupa um número de quadrados consecutivos
na grelha, dispostos horizontalmente ou verticalmente. O número de
quadrados para cada navio é determinada pelo tipo de navio. os navios
não podem se sobrepor (ou seja, apenas um navio pode ocupar qualquer quadrado dado na
grade). Os tipos e o número de navios permitidos são as mesmas para cada
jogador. Estas podem variar em função das regras.
Tipo de navio
Tamanho
Porta-aviões
5
Battleship
4
Submarino
3
Destruidor
3
Barco de patrulha
2
Depois que os navios foram posicionados, o jogo continua em uma série
de rodadas. Em cada rodada, cada jogador dá uma guinada para anunciar um alvo
quadrado na grade do adversário que está a ser alvo de tiros. A an- oponente
nounces se ou não o quadrado é ocupada por um navio, e se for um
"Miss", o jogador marca sua rede primária com um pino branco; se um "hit"
eles marcam isso por conta própria grade primária com um pino vermelho. o atacante
jogador observa o sucesso ou perder em seu próprio grid "tracking" com a AP-
cor propriate peg (vermelho para "hit", branco de "miss"), a fim de construir-se
uma imagem de frota do adversário.
O jogador que localiza com sucesso todos os navios do oponente primeiro
por bater cada quadrado que ocupam é o vencedor como todos os navios têm sido
destruído.

página 201
Vahé Karamian
187
Game Plan para a Implementação
Uma vez que temos um bom entendimento do jogo e do jogo
regras, podemos começar a pensar em como implementar nossa versão da
jogo de tabuleiro de batalha.
A primeira coisa que devemos nos concentrar em é criar o conselho sobre
que vamos jogar o nosso jogo. Representando a bordo digitalmente
na memória do computador vai ser simples com base nas regras que
temos. Há dois itens que precisa pensar sobre (1), representando
a placa visualmente (2) Manter o controle de dados de tabuleiro.
Vamos dar uma olhada e ver como nós estamos indo para representar nosso conselho
visualmente. Sabemos que o conselho vai ser de tamanho N x N. Neste
caso decidimos torná-lo uma placa de 10 x 10. O próximo passo é
determinar como nós estamos indo para representar cada unidade única no tabuleiro.
Para tornar mais fácil, podemos usar um cubo com o vec- escala seguinte
tor: <1,0.1,1> na <x, y, z> coordenadas. Isso nos dará uma unidade agradável
base para a placa.
Figura 69-Unidade Base Board

página 202
Unity 3D - Jogo de Programação Intro
188
A próxima coisa que eu gostaria de fazer, é dar a unidade de alguma textura
que se assemelham a um pensionista. Para fazer isso, precisamos criar um novo mate-
rial e aplicar uma textura que será semelhante a aparência desejada. Nas próximas
passo é identificar de alguma forma a unidade real pela sua localização na placa!
Para fazer isso, vamos criar um objeto UI e anexá-lo à unidade bordo
para exibir a localização da unidade na placa. A unidade de placa final
algo parecido com isto:
Figura 70-Board Unit com textura e Elementos UI Aplicada
Cada unidade de bordo será parecido com a Figura 70 . B1 representa o nome
e ID da placa e [00:00] representam a linha e coluna que vai
ser utilizado para identificar a unidade de placa. Uma última parte mais que precisamos para
completando a nossa versão inicial da unidade placa é um script que irá represen-
ressentir-se os dados internos para a própria unidade. Isto irá ser chamado
BoardUIVer1.cs e aqui é a listagem para ele:
usando UnityEngine;
usando UnityEngine.UI;
usando System.Collections;
classe pública BoardUIVer1 : MonoBehaviour {

página 203
Vahé Karamian
189
pública Texto lblBoardPosition;
int pública ROW;
int pública COL;
bool públicos ocupados;
// Use isso para inicialização
vazio Iniciar () {
este .OCCUPIED = false ;
}
// Update é chamado uma vez por quadro
vazio Update () {
}
}
Código Bloco 44-BoardUIVer1 definição de classe
Uma classe simples que irá armazenar os dados de linha e coluna para a unidade.
Uma referência para o rótulo de texto interface do usuário para a unidade para que possa ser
atualizado quando
foi instanciado e, finalmente, uma variável booleano que indica se
a unidade está ocupada ou não.
Os Passos para criar Unidade Board:
1. Criar um cubo primitivo
GameObject, nomeá-lo
BoardUnit.
2. Alterar a escala a ser
<1,0.1,1> na <x, y, z>
3. Criar um novo tipo de materiais
chamado BoardUnit
4. Atribuir a textura preferida
à propriedade Albedo sob
Mapas principais.
5. Atribuir o novo material ao
BoardUnit GameObject
6. Criar um novo script chamado cs
BoardUIVer1.cs
7. Digite o seu código de script e as-
assinar o script para BoardUnit
GameObject

página 204
Unity 3D - Jogo de Programação Intro
190
Uma vez que estamos satisfeitos com a nossa unidade de bordo, gostaríamos de criar
o conselho real que consiste em unidades de tabuleiro. Para uma placa com dimensão
sões de 10 x 10, seria preciso usar 100 unidades de tabuleiro!
Há duas maneiras de conseguir isso. (1) criar manualmente o
tabuleiro e colocando cem unidades em conjunto, ou (2) Criação de um proce-
dure que vai cuidar dele para você! Obviamente, a escolha seria
criar um procedimento para lidar com a criação de conselho para nós.
Podemos representar nosso conselho com uma matriz bidimensional. Lá
são duas coisas que precisam acontecer, seria necessário para criar a bordo
visualmente e também armazenar os dados por unidade de bordo. Podemos usar o nosso favorito
método loop, para ... laço , estrutura para percorrer as nossas linhas e col-
UMNS.
// Criar um quadro de 10x10 - Conselho 1
int linha = 1;
int col = 1;
para ( int i = 0; i <10; i ++)
{
para ( int j = 0; j <10; j ++)
{
// Instanciar pré-fabricada e colocá-lo corretamente em cena
GameObject tmp = GameObject .Instantiate ( este .BoardUnitPrefab,
nova Vector3 (i, 0, J),
este .BoardUnitPrefab.transform.rotation) como GameObject ;
BoardUIVer1 tmpUI = tmp.GetComponent < BoardUIVer1 > ();
cadeia name = cadeia .format ( "B1: [{00:00}, {01:00}]" , linha, col);
tmpUI.lblBoardPosition.text = nome;
tmpUI.COL = j;
tmpUI.ROW = i;
placa [i, j] = tmp;
tmp.name = nome;
col ++;
}
col = 1;
row ++;
}
Código Bloco 45 Criando o dinamicamente Board
Vamos dar uma olhada e ver o que está acontecendo i n Código Bloco 45 . Nós
ter dois loops um para as linhas do bordo e o segundo para a

página 205
Vahé Karamian
191
colunas na placa. Desde nosso conselho é de 10 x 10, cada um para loop será
iteração 10 vezes. Dentro do corpo do segundo ciclo, é onde a maioria da
a mágica acontece.
Nós primeira instancia nossa Unidade Conselho Prefab GameObject em um espe-
espe- posição definida pelo objeto Vector3 que representa a posição,
e para rotação, usamos a orientação de rotação padrão do Prefab. Aviso prévio
que o objecto Vector3 utiliza a (i, 0, J) para o posicionamento do bordo
unidade. Se bem se lembram, Unidade usa o sistema métrico e, por padrão o básico
unidade é de 1 metro.
Isto torna mais fácil, quando começamos na posição (0,0,0), e para cada linha
e coluna, incrementamos por 1U. Portanto, temos (0,0,0), (0,0,1), (0,0,2)
... (9,0,9). O resultado final parecido com o seguinte:
Figura 71-A Junta
Uma vez que estamos gerando nosso conselho dinamicamente em tempo de execução, estamos
vai contar com a UnitBoard Prefab que criou e salvou no pré
etapa rior. A criação bordo real vai ser feito por um script.
Passos para criar o Conselho:
1. Crie um novo arquivo de cs chamado BoardVer1.cs
2. Na função Start () implementado o código listado i n Código
Bloco 45 Criando o dinamicamente Board
3. Coloque o script recém-criado à GameObject Câmara.

página 206
Unity 3D - Jogo de Programação Intro
192
4. Agora você precisará atribuir o pré-fabricada BoardUnit ao
variável pública denominada
BoardUnitPrefab.
Quando você executar o jogo, você vai notar a placa que tem sido
gerada.
A Figura 72 mostra detalhes por Unidade Board
Se você olhar de perto, você vai notar que as informações para cada placa
unidade está sendo exibido corretamente. Há muitas razões que gostaríamos
para ver estas informações. Em primeiro lugar, é uma forma visual de pin-point cada placa
unidade, o que leva à razão mais importante, a depuração! Nós podemos
rapidamente depurar nossa lógica e identificar os valores que recebemos por trás da cena
com a representação visual real. Você vai ver o benefício como nós
progresso.
Como este é um jogo de tabuleiro, é preciso manter alguma forma o controle do
Estado da placa ao longo de sua vida, e também ser capaz de selecionar um parti-
localização ular na placa principal para a colocação de nossos GameObjects e
interagir com elas. Então, vamos ver como esta parcela seria feito.
Assumindo que vamos usar o nosso ponteiro do mouse para localizar e posição
nossas peças, e também enviar o comando de ataque, teremos de cap-
tura a posição do mouse e converter a posição do mouse para o nosso 3D

página 207
Vahé Karamian
193
espaço. Há duas características que nos permitam executar essas opera-
ções, um é o objeto de entrada real que vai nos fornecer a
posição do rato, e o seguinte é uma combinação de um objecto e utilizando Ray
o motor de física para realizar um Raycast para determinar se ter atingido um
objeto na cena ou não. O bloco de código a seguir irá ilustrar este
operação.
NOTA: O bloco de código é listagem parcial da atualização function ()
18
.
se ( Input .mousePosition! = NULL )
{
// Capturar a posição do mouse e lança um raio para ver o objeto que
acertar
Ray ray = Câmara .main.ScreenPointToRay ( Input .mousePosition);
se ( Física .Raycast (ray, fora tmpHitHighlight, 100))
{
BoardUIVer1 tmpUI = tmpHitHighlight.transform.GetCompo-
nente < BoardUIVer1 > ();
se (tmpHitHighlight.transform.tag.Equals ( "Conselho" ) &&
! TmpUI.OCCUPIED)
{
BoardUIVer1 boardData = bordo [tmpUI.ROW,
tmpUI.COL] .transform.GetComponent < BoardUIVer1 > ();
se (tmpHighlight! = NULL )
{
Se (boardData.OCCUPIED)
tmpHighlight.GetComponent < Renderer > (). material.color =
Cor .Red;
outro
tmpHighlight.GetComponent < Renderer > (). material.color =
Cor .white;
}
Se ( esse .tmpBlockHolder! = NULL )
{
Destroy ( este .tmpBlockHolder);
}
Se ( este .PLACE_BLOCK)
{
este .tmpBlockHolder = new GameObject ();
este .OK_TO_PLACE = verdadeiro ;
se (! este .vertical && (tmpUI.ROW <= 10- este .blockSize))
{
para ( int i = 0; i < esta .blockSize; i ++)
{
18
listagem completa da função serão fornecidos nas próximas seções.

página 208
Unity 3D - Jogo de Programação Intro
194
GameObject visuais = GameObject .Instantiate ( este .Cub-
ePrefab,
nova Vec-
TOR3 (tmpUI.ROW + i, este .CubePrefab.transform.position.y, tmpUI.COL),
este .Cub-
ePrefab.transform.rotation) como GameObject ;
GameObject bp = bordo [tmpUI.ROW + i, tmpUI.COL];
BoardUIVer1 bpUI = bp.GetComponent < BoardUIVer1 > ();
se (! bpUI.OCCUPIED)
{
visual.GetComponent < Renderer > (). material.color =
Colorir .gray; // ok para o lugar
//this.OK_TO_PLACE = true;
}
outro
{
visual.transform.localScale = new Vector3 (0.6f,
0.6f, 0.6f);
visual.GetComponent < Renderer > (). material.color =
Cor .yellow; // Não ok
este .OK_TO_PLACE = false ;
}
visual.transform.parent = este .tmpBlockHolder.trans-
Formato;
}
}
Se ( esse .vertical && (tmpUI.COL <= 10 - este .blockSize))
{
para ( int i = 0; i < esta .blockSize; i ++)
{
GameObject visuais = GameObject .Instantiate ( este .Cub-
ePrefab,
nova Vec-
TOR3 (tmpUI.ROW, este .CubePrefab.transform.position.y, tmpUI.COL + i),
este .Cub-
ePrefab.transform.rotation) como GameObject ;
GameObject bp = bordo [tmpUI.ROW, tmpUI.COL + i];
BoardUIVer1 bpUI = bp.GetComponent < BoardUIVer1 > ();
se (! bpUI.OCCUPIED)
{
visual.GetComponent < Renderer > (). material.color =
Colorir .gray; // ok para o lugar
//this.OK_TO_PLACE = true;
}
outro
{
visual.transform.localScale = new Vector3 (0.6f,
0.6f, 0.6f);
visual.GetComponent < Renderer > (). material.color =
Cor .yellow; // Não ok
este .OK_TO_PLACE = false ;

página 209
Vahé Karamian
195
}
visual.transform.parent = este .tmpBlockHolder.trans-
Formato;
}
}
}
tmpHitHighlight.transform.GetComponent < Renderer > (). mate-
rial.color = Cor .Blue;
tmpHighlight = tmpHitHighlight.transform.gameObject;
}
}
}
Código Bloco 46 Destaque Lines para Mouse Position e ray casting
Vamos discutir apenas a seção do código que lidar com o mouse
posição e fundição Ray. O primeiro caso de verificação declaração para ver se temos
a posição do mouse. Se o fizermos, converter essa posição do mouse a um Ray
objeto usando o construído em função fornecida pela classe Camera. Uma vez
temos um objeto ray, usamos a função Raycast do motor de física para
lançou um raio e um dos parâmetros para a função raycast é um fora
variável chamada tmpHitHighlight que irá retornar uma GameObject se
não bater em nada dentro da visão da câmera ativa.
Lembre-se, tmpHitHighlight é um GameObject que representa a nossa
unidade de bordo. A unidade de placa pré-fabricada tem um script anexado a ele chamada
BoardUIVer1.cs que é usado para atualizar o visual da unidade de bordo
, bem como armazenar o estado dessa unidade placa particular. Portanto base
em nosso projeto nós sabemos que, neste momento, o único objeto que pudermos
tecnicamente atingido através da raycast é a unidade de bordo. Então, o que nós somos
fazendo está ficando os componentes ligados à unidade de placa utilizando a
GetComponent <> () função e armazenamos o objeto retornado em um VaR
iable chamado tmpUI .
O próximo passo é detectar se estamos realmente atingindo uma placa
GameObject. Isto é detectada verificando a etiqueta na GameObject
nós apenas atingido pela raycast. A idéia aqui é que, se nós somos um tipo de placa
objeto e a unidade de placa atualmente estamos apontando para não estiver ocupado,
executamos o bloco lógico seguinte. Em primeiro lugar, obter os dados da placa do nosso
array bidimensional, fornecendo a linha e coluna do hit

página 210
Unity 3D - Jogo de Programação Intro
196
unidade de bordo, recuperar e armazenar o elemento de dados em uma variável do tipo
BoardUIVer1 chamado boardData .
As duas últimas linhas no bloco de código 46 mudar a cor do material do
a unidade de bordo que estão a apontar para de branco para azul como um indicador.
Reunindo tudo - Jogo Objectos
Seria preciso criar várias GameObjects que serão utilizados para
fazer o nosso jogo. Alguns dos GameObjects são visuais, e alguns são
funcional. Alguns são ambos! Aqui está uma lista:
prefabs:
BoardUnit
BoardUnitAttack
BoardUnitEnemy
BoardUnityPlayer
CubePrefab
CubeWreck
Objetos de cena:
_Música de fundo
Câmera principal
EventSystem
luz direcional
Lona
Scripts:
BoardUIVer1
BoardVer1
Vamos passar por cada um dos GameObjects e ver o que eles
será utilizado para. Começando com BoardUnit, o GameObject foi criado
como uma base para demonstrar vários conceitos e ideias na anterior
secção, e será a base para os outros componentes que serão
utilizado no jogo real.
BoardUnitPlayer, este GameObject é usado para representar o
O conselho do jogador. Tem a seguinte estrutura:
Figura 73 - Estrutura BoardUnitPlayer

página 211
Vahé Karamian
197
Note-se que o GameObject é composto por vários outros
GameObjects. Uma é uma lona que é usado para indicar a etiqueta
do BoardUnit. AttackPosition é um GameObject vazio usado inter-
nallyfor renderização de gráficos. CubeWreck é outro GameObject aninhada
que representa o aspecto visual de um hit na BoardUnit. Você verá
como esses itens estão sendo construídos e utilizados quando começar a olhar
o código-fonte.
BoardUnitEnemy é uma duplicata de BoardUnityPlayer, a estrutura
é exactamente o mesmo. A única diferença entre os dois é o Tag e
alguns outros elementos de configuração. Também vamos dar uma olhada neles
quando se discute o código-fonte.
CubeWreck é o pré-fabricada que representa a representação visual
de uma batida a uma unidade de placa que é ocupado por um navio. É a combinação
de duas primitivas cubo em ângulos específicos para nos dar alguma visual agradável
efeito.
Figura 74 - CubeWreck Prefab
Os Prefabs que acabamos de descrever não estão presentes na cena ao vivo du-
ing tempo de design. Eles vão ser instanciado durante o jogo. Agora
vamos dar uma olhada nas GameObjects que vão estar presentes no de-
assinar tempo na cena.
_BackgroundMusic É um GameObject vazio que é exclusivamente utilizado para
armazenar e gerenciar uma fonte de áudio. Basicamente, desempenha o fundo
música para o nível.
Câmera principal é a GameObject representando a câmera na
cena. Por padrão, quando você criar uma cena, um GameObject Câmara

página 212
Unity 3D - Jogo de Programação Intro
198
é criado para você. Há um monte de configuração e as propriedades de
a câmera, vamos olhar para alguns deles no exemplo dado.
Direcional Luz é a GameObject representando o elemento de iluminação
mento na cena. Como a câmera, por padrão, uma luz direcional
GameObject é criado sempre que você iniciar uma nova cena. Ele também tem uma grande
quantidade
de propriedades que podem ser configuradas para efeitos de iluminação, vamos dar uma
olhar para alguns deles durante nossos exemplos.
Lona e eventos do sistema, a lona GameObject é usado para o
Graphical User Interface (GUI) design. É a nova forma de conceber
e implementar a GUI para a Unidade. Ele tem características poderosas para
construção de interfaces atraentes. O sistema de eventos GameObject é re-
vel para os eventos gerados dentro do GUI.
BoardUIVer1 é o script c-sharp que é usado para lidar com o Conselho
Unidade de elementos de interface do usuário. É também responsável na gestão da
estado da determinada unidade de bordo. Isto é, se ele estiver ocupado, bater e etc ...
também gerencia os aspectos visuais da unidade de bordo com base no estado.
BoardVer1 é o principal roteiro para a lógica do jogo. Ele contém toda a
elementos de dados necessários e lógica para o jogo para funcionar corretamente. isto
cola tudo juntos. É responsável para a inicialização do
unidades de tabuleiro, é responsável por manter o controle da pontuação, e também é
responsável pelo processo de pensamento do adversário do computador para fazer
o próximo passo.

página 213
Vahé Karamian
199
Jogo Fluxo + Logic
O diagrama a seguir é uma representação visual do nível elevado
fluxo do jogo. Como uma boa regra de ouro, antes de iniciar qualquer projeto, é
uma boa idéia para esboçar e capturar alguma representação elevado nível de
como o programa irá fluir.
Figura 75 - Jogo de Fluxo de Alto Nível
Para resumir rapidamente o diagrama, quando o jogo começa, inicialmente,
o jogador é convidado a colocar seus / suas peças no tabuleiro designado
19
.
Quando o jogador tiver completado colocando as suas peças, em seguida, o computador
começará a colocar as suas peças. Uma vez que o jogador e o computador tem
colocado todas as peças necessárias, o jogo começa!
19
Note-se, que nós não ter capturado os detalhes da verificação da placa para a colocação adequada
das peças, nem nós capturar a mudança de orientação ao colocar as peças na
borda.

página 214
Unity 3D - Jogo de Programação Intro
200
Quando o jogo começa, o gerente jogo decide qual jogador do
transformá-la é, uma vez que é determinado, se é a vez do jogador, ele esperará
até que o jogador escolhe uma unidade de bordo, o gerente jogo vai lidar com a
detalhes de um sucesso e perder nos bastidores. Se for um sucesso, em seguida, alguns ac-
contagem é feita eo jogador recebe outra vez, se é uma falta, em seguida,
o computador AI seleciona uma unidade de bordo a bordo e o do jogador
mesmo processo contínuo até que o jogador ou as vitórias de computador
o jogo.
Vamos olhar para os internos da lógica mais de perto.
Figura 76 - Jogador Navio Placement Diagrama de Fluxo
Quebrar F igura 75, w e vai começar por tomar um olhar mais atento
o que acontece internamente para a lógica do programa quando o jogador é solicitado
para colocar suas / seus navios em sua placa. Figura 76, ilustra a lógica
fluir em mais detalhe.

página 215
Vahé Karamian
201
Como ilustrado, o jogador precisa primeiro selecionar uma peça para ser colocado
no quadro. Quando uma peça é selecionado, em seguida, ele / ela tem que selecionar onde
eles gostariam de colocar a peça no tabuleiro, e em que a orientação.
Existem apenas duas orientações disponíveis, horizontal e vertical.
Quando uma determinada unidade de bordo é selecionado, o computador verifica para ver se
não há espaço suficiente para a colocação da peça, também verificar para ver
Se todo o comprimento do navio seleccionado é claro para o posicionamento. Isso é,
se não há peças colocadas já colocado no caminho do recém
peça selecionada. Este processo continua repetindo até que todas as peças foram
colocado com sucesso em cima da prancha.
Em seguida, o computador é iniciado colocando suas peças.
Figura 77 - AI Navio Placement Diagrama de Fluxo
A AI passa por um processo semelhante quando se está a colocar a sua própria
tocando peças em cima da prancha. Ele começa por selecionar o próximo disponível
peça a ser colocado, em seguida, ele decide aleatoriamente o que não era orientação
para colocar a peça, ao lado decide as coordenadas no tabuleiro,
uma vez que é determinado, em seguida, começa a atravessar o processo de
verificar e verificar se a seleção é válida para a colocação ou não. E se

página 216
Unity 3D - Jogo de Programação Intro
202
ele é, então tudo é bom e os dados são gravados, se não, ele passa por
etapas para selecionar outra posição e orientação disponível.
Quando todos os jogadores colocaram suas peças, o jogo começar. o se-
diagrama mugido ilustra a versão detalhada da lógica de jogo.
Figura 78 - O Jogo Logic

página 217
Vahé Karamian
203
Figura 78 fornece uma visão mais detalhada de como o jogo interno
lógica é quando tanto o jogador como o AI colocou seus navios em
seus respectivos conselhos. Cada jogador tem a chance de selecionar uma unidade de bordo
quando é sua vez, se a unidade de placa seleccionada é ocupada pelo oposta
nentes peça, então temos um sucesso, várias operações acontecem por trás do
cena pelo gerente de jogo para contabilidade e também visual e de áudio
representação, Finalmente, o gerente jogo verifica se o jogador tem
acertar todas peças do oponente, e se assim for, o jogo acabou.
A AI começa com uma lógica similar eo programa executa a
mesmos passos para os critérios de sucesso ou perder, no entanto, há um retrocesso
20
algoritmo desenvolvido para a IA, se houver um acerto! Este é basicamente o
código que realmente dar o AI sua inteligência. Ela determina que a
melhor movimento seguinte é para o AI se o AI tem um hit. Entretanto, a
gerente de jogo também verifica para determinar se o AI atingiu todo o
peças do jogo, e se assim for, o jogo é encerrado com a AI ser o
vencedora.
Como você pode ver, mesmo para um simples jogo, há um monte de planejamento
fazer como designer e programador. Os diagramas são fornecidos para
torná-lo mais fácil de visualizar o fluxo do programa. Vamos olhar para o
aplicação em uma seção diferente.
Jogo User Interface
Como qualquer outra aplicação, um jogo também precisa fornecer uma gráfica
User Interface (GUI) para o usuário. A GUI do seu jogo é um meio de
como o usuário irá interagir com o seu jogo. De um modo geral, a GUI
de uma aplicação e ou um jogo é impulsionado pelas características e objetivos de
que a aplicação e ou jogo particular.
Normalmente, o GUI tem de exibir informações significativas para o
usuário final. As informações são dados relacionados com o meio ambiente. para in-
posição, no nosso jogo, precisamos de um meio para o jogador para selecionar as peças
que são necessários para ser colocado sobre a sua placa, também precisamos de um meio para
20
Retrocesso é um algoritmo geral para encontrar todos (ou alguns) soluções para alguns com-
problemas computacionais, problemas de satisfação nomeadamente constrangimento, que constrói
incrementalmente
candidatos para as soluções, e abandona cada candidato parcial C ( "Backtracks"), logo que
determina que C não pode possivelmente ser completada com uma solução válida.

página 218
Unity 3D - Jogo de Programação Intro
204
alterar a orientação da peça antes de colocá-los em cima da prancha,
e, finalmente, precisamos mostrar a pontuação para o jogador e também o AI
A GUI para o jogo não é muito complexo, mas independentemente disso, você ainda
precisa prestar atenção às exigências do seu projeto e concepção e
implementar uma interface gráfica que vai ser suficiente para a experiência geral.
Figura 79 - Jogo GUI Concept
Aqui está uma lista de entrada e de saída que precisam ser tratadas:
entradas:
 Escolha peças individuais.
 Alterar a orientação da peça (vertical / horizontal)
 Select localização a bordo do jogador para colocar a peça.
 Select localização a bordo do inimigo para ter um hit.
Saída:
 placa de exibição do jogador / inimigo (s)

página 219
Vahé Karamian
205
 peças de Displayplayer a ser colocada sobre a placa do leitor
antes do jogo começar.
 representar visualmente as peças de tabuleiro após jogador tem posição
nado-los em cima da prancha.
 contagens de exibição para tanto o jogador como o inimigo.
 representar visualmente um sucesso a bordo e do tanto do jogador
O conselho do inimigo.
 A música de fundo para o jogo.
 Sound FX quando há uma batida a bordo, quer do jogador
ou placa do inimigo.
Dada a nossa lista de entradas e saídas, podemos chegar a um esboço
representando o layout de como gostaríamos que a nossa GUI a ser projetado.
Estes processo geralmente vai levar algum tempo e esforço e isso será mais
provavelmente passar por algumas iterações antes de se estabelecer em um de- final,
placa.
Figura 80 - Jogo GUI Score exibição

página 220
Unity 3D - Jogo de Programação Intro
206
Olhando para a Figura 79 nós dar uma olhada no nosso layout GUI desejado. Como
indicada no diagrama, temos cinco botões que representam a seleção
ção das nossas peças para a colocação de placa na parte inferior da tela, nós
tem um botão para a mudança de orientação no canto superior esquerdo da
tela, e temos dois principais blocos grandes que representam as placas de jogos
que vamos usar para o nosso jogo.
Se você observar a Figura 79 , não displayany informações sobre
a pontuação no jogo. Este é capturado na Figura 80 . Aqui é como a interface do usuário
obras de lógica:
1. O jogador seleciona um determinado navio para ser colocado em sua / seu bordo.
2. Após a colocação bem sucedida, o selecione peça será re-
movido da UI.
3. Esse processo se repete até que todas as peças foram colocadas em
o tabuleiro de jogo.
4. Neste ponto, quando o jogo começa, todo o posicionamento de função
cionais botões são removidos ou escondidos da UI.
5. Em seguida, a UI pontuação é exibida para o usuário como indicado na
o esboço.
Este é outro conceito importante quando você está projetando uma GUI
para uma aplicação particular. Devido às restrições de tela imobiliário,
você terá de decidir a forma de gerir a informação que você quer
exibir para o usuário final. Não só você terá que pensar sobre o tamanho
localização e orientação dos elementos de interface do usuário, mas também em que momento você
deseja exibir informações específicas.
Em alguns casos, você pode ter que mostrar continuamente um conjunto de muito
dados importantes para o jogador, portanto, você vai precisar para projetar a interface do usuário em
um
maneira que seja confortável para o jogador para obter as informações que ele ou
ela precisa, mas, ao mesmo tempo que não interfere com o jogo.
Em outros pontos, você pode querer exibir informações (mais de-
caudas) em relação a determinados critérios sobre um gatilho pelo jogador. este
ação trará um painel e ou uma janela que exibirá dados em
mais detalhes.

página 221
Vahé Karamian
207
Capítulo 7 - Delving o Código
Se você seguir junto i n Capítulo 3 - objetos do jogo e Compo-
nentes e Capítulo 6 - Criando Battleship, você deve ter uma boa
compreensão dos conceitos e uma ideia clara do nosso objetivo do jogo.
Para fazer uma breve recapitulação, no Capítulo 3, que abrangeu o básico do jogo Obser-
jectos e Unidade IDE, o conceito-chave do capítulo era para você
começou na direção certa, e permitir-lhe saltar iniciar o seu próprio
estudo e desenvolvimento do IDE.
Capítulo 6 foi totalmente dedicada ao conceito e a idéia do
jogo chamado Batalha do navio. Nós cobrimos um monte de idéias importantes, AP-
abordagens em geral para desenvolvimento de software, e usamos Batalha Board
como um exemplo para demonstração. Neste capítulo, vamos mergulhar
no código por trás do jogo e ver como ele dirige tudo e
cola tudo juntos.
Script - BoardUIVer1.cs
Conselho UI Ver um script é usado para controlar as unidades de bordo individuais de
o conselho dado dentro do jogo. Se você se lembrar do nosso cussão anterior
sion sobre a abordagem que devemos ter para a concepção e
implementação do nosso tabuleiro de jogo, você vai lembrar que temos uma espe-
CIFIC pré-fabricada dedicado para a representação visual da nossa unidade de bordo.
Os detalhes da pré-fabricada são discutidos na seção seguinte, Putting
Tudo Junto - Jogo Objectos, no Capítulo 6 - Criação de batalha
navio.
O pré-fabricada por si só é bastante inútil. Para que sejamos capazes
para trazê-lo à vida e interagir com o pré-fabricada precisamos de algum tipo de
scripting. O roteiro é usada para interagir e modificar o estado de um determinado
GameObject. Neste caso particular, este passa a ser nossa Unidade Board.
Vamos dar uma olhada na lista de códigos, e passar por cima de cada seção e
quebrar a lógica e entender o que ele está tentando alcançar.

página 222
Unity 3D - Jogo de Programação Intro
208
usando UnityEngine;
usando UnityEngine.UI;
usando System.Collections;
classe pública BoardUIVer1 : MonoBehaviour {
pública GameObject AttackPrefab;
pública GameObject WreckPrefab;
pública GameObject AttackPosition;
pública GameObject CubePrefab;
flutuar timeLimit = 4.0f; // 10 segundos.
pública Texto lblBoardPosition;
int pública ROW;
int pública COL;
bool públicos ocupados;
// Usado para indicar se a unidade está ocupada
bool públicas atacado;
// Usado para indicar se a unidade for atacado
// Use isso para inicialização
vazio Iniciar () {
este .OCCUPIED = false ;
este .ATTACKED = false ;
}
privada GameObject tmp = NULL ;
privada GameObject tmp1 = NULL ;
privada GameObject TMP 2 = NULL ;
// Update é chamado uma vez por quadro
vazio Update () {
Se (transform.tag.Equals ( "boardAttack" ) && este .ATTACKED &&
este .OCCUPIED)
{
este .WreckPrefab.SetActive ( verdadeiro );
Se (timeLimit> 0)
{
// Diminuir timeLimit.
timeLimit - = Tempo .deltaTime;
Se ( esse .tmp == nulo )
tmp = GameObject .Instantiate ( este .AttackPrefab,
este .AttackPosition.trans-
form.position,
este .AttackPosition.trans-
form.rotation) como GameObject ;
// Destroy (tmp, 3.0f);
}
outro

página 223
Vahé Karamian
209
{
Destroy (tmp);
timeLimit = 4.0f;
}
}
se (transform.tag.Equals ( "board" ) && este .ATTACKED && este .OCCUPIED)
{
este .CubePrefab.SetActive ( false );
Se (timeLimit> 0)
{
// Diminuir timeLimit.
timeLimit - = Tempo .deltaTime;
Se ( esse .tmp2 == nulo )
TMP 2 = GameObject .Instantiate ( este .AttackPrefab,
nova Vector3 (transform.position.x, 1.0f, transform.position.z),
transform.rotation) como GameObject ;
}
outro
{
Destroy (TMP 2);
timeLimit = 4.0f;
}
}
}
public void PlaceEnableCubePrefab ()
{
este .CubePrefab.SetActive ( verdadeiro );
}
}
Código Bloco 47 - Listagem de BoardUIVer1.cs
Vamos começar por afirmar que BoardUIVer1 é definida como uma classe que é
herdando de MonoBehaviour
21
. Todos os C # roteiros de herdar padrão
de MonoBeviour. Por padrão cada script tem um Iniciar () e um Up-
date () função definida.
A função Start () será chamado pelo Unity antes jogabilidade BE
gins, ou seja, antes que a função Update () é chamado pela primeira vez, e ele
é o lugar ideal para fazer a sua inicialização.
21
MonoBehaviour é a classe base cada script deriva.

página 224
Unity 3D - Jogo de Programação Intro
210
A função Update () é o lugar para colocar o código que irá lidar com o
atualização de quadros para o GameObject. Este movimento pode incluir, desenca-
dear ações e responder a entrada do usuário. Basicamente qualquer coisa que
precisa ser tratado ao longo do tempo durante o jogo.
Vamos dar uma olhada na estrutura de classes, e decompô-lo para uma melhor
compreensão:
Nós temos uma classe chamada BoardUIVer1, ele contém o seguinte
propriedades / atributos:
 AttackPrefab , é do tipo GameObject e é uma referência para
o Prefab GameObject usado para exibir o FX especial
para um sucesso a bordo do jogador.
 WreckPrefab , é do tipo GameObject e é uma referência para
o Prefab GameObject usado para exibir visual
naufrágio de um hit na placa inimigo.
 AttackPosition , é do tipo GameObject e é uma referência para
a posição 3D para instanciar o AttackPrefab visualmente
na tela.
 timeLimit , é do tipo flutuador e é utilizado como um temporizador para manu-
dling quando criar uma nova instância do FX especial.
 lblBoardPosition , é do tipo de texto e é usado para exibir
a posição do Conselho de Unidade.
 ROW , é do tipo int e é usado para manter o número da linha
a placa de unidade.
 COL , é do tipo int e é utilizada para conter o número da coluna
do conselho de administração da unidade.
 OCCUPIED , é do tipo booleano e é usado para indicar se o
Board Unit específico é ocupado ou não.
 ATAQUE , é do tipo booleano e é usado para indicar se o
Board Unit específica é atacado ou não.
A classe também tem a seguinte três funções definidas:

página 225
Vahé Karamian
211
 Iniciar () , na função start () os dois variável OCUPADOS
e atacou são inicializados como false. Isto porque por
nenhum padrão das unidades de tabuleiro estão ocupadas ou atacado.
 Update () , a função Update () é um pouco mais complicado. isto
é usado para gerenciar o aspecto visual da unidade de tabuleiro baseado
sobre o estado.
 PlaceEnableCubePrefab () , esta função é utilizada para ativar
o pré-fabricada definido na unidade de bordo.
Vamos olhar para o Update () função com mais profundidade. Este é o lugar onde
a maioria da ação está acontecendo para esta classe particular. Há dois
principais condições que estamos verificando:
Se (transform.tag.Equals ( "boardAttack" ) && este .ATTACKED && este .OCCUPIED)
{
este .WreckPrefab.SetActive ( verdadeiro );
Se (timeLimit> 0)
{
// Diminuir timeLimit.
timeLimit - = Tempo .deltaTime;
Se ( esse .tmp == nulo )
tmp = GameObject .Instantiate ( este .AttackPrefab,
este .AttackPosition.transform.position,
este .AttackPosition.transform.rotation) como GameObject ;
}
outro
{
Destroy (tmp);
timeLimit = 4.0f;
}
}
// Este bloco de código aqui é usado para o jogador enemny espaço reservado ...
se (transform.tag.Equals ( "board" ) && este .ATTACKED && este .OCCUPIED)
{
este .CubePrefab.SetActive ( false );
Se (timeLimit> 0)
{
// Diminuir timeLimit.
timeLimit - = Tempo .deltaTime;
Se ( esse .tmp2 == nulo )
TMP 2 = GameObject .Instantiate ( este .AttackPrefab,
nova Vector3 (transform.position.x, 1.0f, transform.position.z),
transform.rotation) como GameObject ;
}
outro
{
Destroy (TMP 2);

página 226
Unity 3D - Jogo de Programação Intro
212
timeLimit = 4.0f;
}
}
Se você notar, tanto do se as condições de verificar se os mesmos critérios:
a unidade de bordo devem ser atacados e deve ser ocupado. estes critérios
são verificados através do this.ATTACKED e this.OCCUPIED devidamente,
gravatas. A principal diferença entre os dois blocos é feito através do
propriedade de marca associada à pré-fabricada bordo unidade.
Precisamos ser capazes de identificar de alguma forma cujo conselho estamos in-
teracting com, e isso é feito através da propriedade tag que é
associado ao pré-fabricada bordo unidade. Para bordo do jogador, a tag prop-
erty é definido como "boardAttack" e para a placa do inimigo, a tag
propriedade é definida como "board" . A propriedade tag é definido e as-
assinado no momento da concepção. Em outras palavras, uma vez que estamos utilizando um único
script para lidar com ambas as unidades de tabuleiro do jogador e placa do inimigo
unidades, é preciso distinguir de alguma forma entre os dois, e, portanto, nós
estão fazendo isso através da propriedade tag.
Desde que agora está fora do caminho, a estrutura real e lógica para
ambos se os blocos são semelhantes, se estiverem reunidas as condições, ativar / enable
o pré-fabricada usado para representar visualmente um sucesso. O próximo passo é verificar
uma variável temporizador, o temporizador está definido para redefinir a cada quatro (4) segundos,
nós
instanciar o pré-fabricada efeitos visuais definidos na posição de ataque transformar
associado ao pré-fabricada bordo unidade. Note-se que a cada quatro segundos
destruímos o GameObject efeitos visuais da cena.
Script - BoardVer1.cs
Este script é a principal força motriz por trás do jogo Batalha Board.
Ele é usado para controlar a lógica do jogo e fluxo de jogo do início ao fim.
É o script que traz tudo junto e atua como o BE cola
tre todas as diferentes peças. É um script complexo, por isso vou tentar
decompô-lo tanto quanto possível. Vamos dar uma olhada e listar todos os
variáveis internas que foram definidos na BoardVer1
22
classe.
22
O code-block está mostrando apenas as variáveis declaradas, listagem completa do código é pro-
DESDE mais tarde.

página 227
Vahé Karamian
213
. ...
. ...
pública Camera cameraEndGame;
pública AudioClip explosionPlayerBlast;
pública AudioClip explosionEnemyBlast;
privada AudioSource AudioSource;
pública GameObject BoardUnitPrefab;
pública GameObject BoardUnitAttackPrefab;
pública GameObject CubePrefab;
// Esta variável será utilizada para o capítulo 5 ... melhorias do código
pública GameObject IverHuitfeldt;
pública GameObject IverHuitfeldtAnchorPosition;
pública GameObject AdmiralSergeyGorshkov;
pública GameObject AdmiralSergeyGorshkovAnchorPosition;
pública GameObject MRVikhrIFQ;
pública GameObject MRVikhrIFQAnchorPosition;
pública GameObject Steregushchiy;
pública GameObject SteregushchiyAnchorPosition;
pública GameObject AdmiralKuznetsov;
pública GameObject AdmiralKuznetsovAnchorPosition;
// ------------------------------------------------ ----------------------
pública GameObject [,] boardPlayer = new GameObject [10,10];
pública GameObject [,] boardEnemy = new GameObject [10, 10];
// Usado para colocar navios inimigos (por tamanho)
private int [] navios = new int [5] {2,3,3,4,5};
private int maxNumberOfHits = 17;
private int playerHitCount = 0;
private int enemyHitCount = 0;
int pública blockSize = 3;
pública bool verticais = false ;
pública GameObject myWater;
#region REF BUTTON
pública Botão butAircraftCarrier;
pública Botão butBattleship;
pública Botão butSubmarine;
pública Botão butDestroyer;
pública Botão butPatrolBoat;
pública Botão butUIReset;
pública Botão butExit;

página 228
Unity 3D - Jogo de Programação Intro
214
pública Botão butHorizontal;
pública Botão butVertical;
pública Canvas canvasScoreBoard;
pública Texto lblPlayerScore;
pública Texto lblAIScore;
pública Imagem imgYouWin;
pública Imagem imgYouLose;
#endregion
...
. ...
Código Bloco 48 - Variáveis BoardVer1
Aqui estão as variáveis responsáveis para o principal jogo.
 cameraEndGame , é do tipo Camera, e é usado para exibir
a cena final do jogo.
 explosionPlayerBlast , é do tipo AudioClip, e é usado para
reproduzir o som FX, quando o jogador é atingido.
 explosionEnemyBlast , é do tipo AudioClip, e é usado para
reproduzir o som FX quando o inimigo é atingido.
 AudioSource , é do tipo AudioSource, é utilizado para a
a reprodução do áudio em nível.
 BoardUnitPrefab , é do tipo GameObject, é o refe-
rência à pré-fabricada usada para manter bordo unidade do jogador.
 BoardUnitAttackPrefab , é do tipo GameObject, que é a
referência ao pré-fabricada usada para manter bordo unidade do inimigo.
 CubePrefab , é do tipo GameObject, esta variável é utilizada
para gerar dinamicamente uma casa pré-fabricada cubo de pistas visuais.
 boardPlayer , é um bidimensional tipo de dados array, represen-
tando bordo do jogador. A dimensão da matriz é
10x10.
 boardEnemy , é um bidimensional tipo de dados array, represen-
tando bordo do inimigo. A dimensão da matriz é
10x10.
 navios , é um tipo de dados uma matriz dimensional, detém o comprimento
de cada peça que terá de ser colocado no tabuleiro. este
variável é utilizado especificamente pela AI quando é colocar
é pedaços em cima da prancha.

página 229
Vahé Karamian
215
 maxNumberOfHits , é do tipo int, e é usado para representar
o valor máximo atingível para uma vitória.
 playerHitCount , é do tipo int, é o contador para o
pontuação do jogador.
 enemyHitCount , é do tipo int, é o contador para o AI
Ponto.
 blockSize , é do tipo int, que é usado para medir e com-
põr o limite da colocação navio nas placas de jogo.
Pense nisso como uma margem ou uma medida de preenchimento.
 verticais , é do tipo booleano, que é usada para identificar se o atual
peça a ser colocado vai ser vertical ou horizontal.
Como você pode ver, a lista de variáveis para gerir o jogo é bastante
extenso. Vamos ver como cada um está sendo usado quando nós cobrir o
funções na classe.
Variáveis gráficos avançados
As seguintes variáveis são todos do tipo GameObject. Eles são um
referência aos prefabs que representam o modelo 3D para cada navio que
será colocada a bordo do jogador.
 IverHuitfeldt
 IverHuitfeldtAnchorPosition
 AdmiralSergeyGorshkov
 AdmiralSergeyGorshkovAnchorPosition
 MRVikhrIFQ
 MRVikhrIFQAnchorPosition
 Steregushchiy
 SteregushchiyAnchorPosition
 AdmiralKuznetsov
 AdmiralKuznetsovAnchorPosition
Variáveis Graphical User Interface
As seguintes variáveis são utilizadas para referenciar os elementos de interface do usuário em
o jogo. As variáveis que começam com butXXX estão representando o mas-
toneladas definidos na interface do usuário que o usuário pode interagir com. as variáveis

página 230
Unity 3D - Jogo de Programação Intro
216
começando com lblXXX estão fazendo referência rótulos na interface do usuário, as variáveis
iniciar-
ing com imgXXX estão fazendo referência imagens na interface do usuário. a variável
canvasScoreBoard é do tipo da lona e é usado para fazer referência a pontuação
bordo no jogo. Vamos também olhar para estes em mais detalhe na próxima
seção.
 butAircraftCarrier
 butBattleship
 butSubmarine
 butDestroyer
 butPatrolBoat
 butUIReset
 butExit
 butHorizontal
 butVertical
 canvasScoreBoard
 lblPlayerScore
 lblAIScore
 imgYouWin
 imgYouLose
Funções definidas em BoardVer1 Classe
O jogo tem algumas funções que são necessárias para o seu funcionamento.
Nesta seção, vamos listar cada função e passar por cima do código e de-
escriba que as funções estão realizando.
 Awake () , a Awake () é chamado uma vez e é o
primeira função que será executado no ciclo de vida do
jogo. Ele é usado para agarrar uma referência ao AudioSource em
o nível.
 Iniciar () , o Start () função é chamada uma vez, bem, é
chamado após o Awake () função. O Start () função é
responsável por inicializar todas as variáveis do jogo. Isto é
também responsável pela geração de ambas as placas de jogos,
um para o jogador e outra para o inimigo.

página 231
Vahé Karamian
217
 CheckPlayerBoard () , é responsável por entregar o lugar-
mento das peças do jogo em tabuleiro de jogo do jogador.
 CheckAttackBoard () , é responsável pelo tratamento do ataque
e detecção de um sucesso tanto para o jogador eo inimigo.
 Wait4Me () , é uma função usado para temporização.
 Update () , é uma função que é chamada cada frame. o Up-
date () função é o corpo principal do programa de jogo. isto
determina o estado do jogo e chama o apropriado
funções conforme necessário durante a duração do jogo.
 ChangeHitDirection () , esta função é usada pelo AI
tomar uma decisão sobre a direção a sua próxima jogada será.
 PlaceEnemyShips () , esta função é usada pelo AI para de-
cide onde quer colocar os seus navios no tabuleiro de jogo
antes do jogo começar.
 CheckBoardForEnemyPlacement (linha, col, tamanho hor) , este
função é usada pelo AI para determinar se o posicionamento
do navio é válido ou não. É uma função recursiva. Isto é
com base nos dados originais de linha e coluna do tamanho do
navio e a orientação.
 CheckWhichShipWasPlaced (linha, col) , esta função é utilizada
por o AI para determinar qual o navio está já colocada sobre o
tabuleiro de jogo.
 butCreateBattleship (tamanho) , esta função é acionado quando
o jogador escolhe o botão UI definido para um navio específico
para a colocação.
 butCreateBattleShipSetID (shipID) , esta função é desenca-
Gered quando o jogador seleciona o botão UI definido para um
navio específico para a colocação. Os dois funcionam em conjunto pro-
vide o tamanho e a identificação do navio seleccionado.
 butRestart () , esta função faz algum trabalho de limpeza e
reinicia o jogo.
 butExitClick () , esta função termina o jogo.
 butChangeOrientation () , esta função muda a orientação
ção da colocação peça do jogador para o tabuleiro de jogo.
 ResetGUIButtons () , esta função repõe todas as GUI mas-
toneladas quando o usuário reiniciar o jogo.

página 232
Unity 3D - Jogo de Programação Intro
218
Awake () implementação da função
Agora que temos um breve resumo do que cada função é de-
assinado para, podemos olhar para a implementação real e começar a absorver
os detalhes adiante. O primeiro e mais simples de todas as funções é a Awake ()
função.
anular Awake ()
{
este .audioSource = getComponent < AudioSource > ();
}
Código Bloco 49 - Awake () função na classe BoardVer1
Existe apenas uma linha de código, neste método, e é utilizado para obter
os componentes ligados ao AudioSource GameObject onde esta
próprio script está anexado. O GameObject passa a ser o principal
Câmara definida na cena. Precisamos de uma referência ao AudioSource
para que possamos acessar diretamente o áudio queremos jogar em um determinado
Tempo. Você vai ver como esta variável é utilizada em outras funções
listado abaixo.
Start () implementação da função
A próxima função queremos olhar é o Iniciar () função.
anular Iniciar ()
{
#region JOGO DE CONTABILIDADE
Água tmpWater = este .myWater.gameObject.GetComponent < Água > ();
tmpWater.waterMode = água . WaterMode .Refractive;
este .cameraEndGame.gameObject.SetActive ( false );
este .canvasScoreBoard.enabled = false ;
este .count = 0;
este .currentShipID = 0;
este .blockSize = 0;
este .placeEnemyShips = verdadeiro ;
este .START_GAME = false ;
este .PLAYER_TURN = verdadeiro ;
esta .maxNumberOfHits = 17;
este .playerHitCount = 0;

página 233
Vahé Karamian
219
este .enemyHitCount = 0;
este .hit_row = -1;
este .hit_col = -1;
este .hit_dir = HitDirection .none;
este .IsBusy = false ;
este .gotoLastHit = false ;
este .imgYouLose.enabled = false ;
este .imgYouWin.enabled = false ;
este .butUIReset.gameObject.SetActive ( false );
#if UNITY_WEBPLAYER
// Para o jogador web que não precisamos para exibir o botão de saída !!!
this.butExit.gameObject.SetActive (false);
this.butUIReset.GetComponent <RectTransform> (). Traduzir (nova Vector3 (75,
0, 0));
#fim se
Se ( este .vertical)
{
este .butVertical.gameObject.SetActive ( verdadeiro );
este .butHorizontal.gameObject.SetActive ( false );
}
outro
{
este .butVertical.gameObject.SetActive ( false );
este .butHorizontal.gameObject.SetActive ( verdadeiro );
}
#endregion
// Limpar o tabuleiro (s)
para ( int i = 0; i <10; i ++)
{
para ( int j = 0; j <10; j ++)
{
boardPlayer [i, j] = NULL ;
boardEnemy [i, j] = NULL ;
}
}
// Criar um quadro de 10x10 - Conselho 1
int linha = 1;
int col = 1;
para ( int i = 0; i <10; i ++)
{
para ( int j = 0; j <10; j ++)
{
// Instanciar pré-fabricada e colocá-lo corretamente em cena
GameObject tmp = GameObject .Instantiate ( este .BoardUnitPrefab,
nova Vector3 (i, 0, J), esta .BoardUnitPrefab.transform.rota-
ção) como GameObject ;
BoardUIVer1 tmpUI = tmp.GetComponent < BoardUIVer1 > ();

página 234
Unity 3D - Jogo de Programação Intro
220
cadeia name = cadeia .format ( "B1: [{00:00}, {01:00}]" , linha, col);
tmpUI.lblBoardPosition.text = nome;
tmpUI.COL = j;
tmpUI.ROW = i;
boardPlayer [i, j] = tmp;
tmp.name = nome;
col ++;
}
col = 1;
row ++;
}
// Criar um quadro de 10x10 - Conselho 2
linha = 1; col = 1;
para ( int i = 11; i <21; i ++)
{
para ( int j = 0; j <10; j ++)
{
// Instanciar pré-fabricada e colocá-lo corretamente em cena
GameObject tmp = GameObject .Instantiate ( este .BoardUnitAttackPrefab,
nova Vector3 (i, 0, J), esta .BoardUnitAttackPrefab.trans-
form.rotation) como GameObject ;
BoardUIVer1 tmpUI = tmp.GetComponent < BoardUIVer1 > ();
cadeia name = cadeia .format ( "B2: [{00:00}, {01:00}]" , linha, col);
tmpUI.lblBoardPosition.text = nome;
tmpUI.COL = col-1;
tmpUI.ROW = row-1;
boardEnemy [tmpUI.ROW, tmpUI.COL] = tmp;
tmp.name = nome;
col ++;
}
col = 1;
row ++;
}
}
Código Bloco 50 - Iniciar () função na classe BoardVer1
As primeiras duas linhas na função obter uma referência para a água com-
Ponent na myWater variável, e nós mudar o WaterMode para
Refração . Isto muda o modo de processamento de água e, portanto, o
mudanças na aparência no nível.

página 235
Vahé Karamian
221
As próximas duas linhas de código desativa a câmera do jogo final, temos
configuração através da variável cameraEndGame . Também desativar o can-
vas objeto que está fazendo referência ao quadro de pontuação através da
canvasScoreBoard variável. As próximas linhas inicializar todo o VaR
iables que são usados para entregar os dados do jogo.
Indo para o primeiro loop for, estamos inicializando os tabuleiros de jogo para
tanto o jogador como o inimigo. Aqui temos dois loops, um em-
alojado na outra representando as linhas e as colunas do nosso
Pranchas. Eles são criados para percorrer 10 vezes cada um, como é que o tamanho do nosso
borda. Observe que estamos anulando cada posição na matriz / cartão,
preparando-o, portanto, para a criação real do bordo no passo seguinte.
// Criar um quadro de 10x10 - Conselho 1
int linha = 1;
int col = 1;
para ( int i = 0; i <10; i ++)
{
para ( int j = 0; j <10; j ++)
{
// Instanciar pré-fabricada e colocá-lo corretamente em cena
GameObject tmp = GameObject .Instantiate ( este .BoardUnitPrefab,
nova Vector3 (i, 0, J), esta .BoardUnitPrefab.transform.rotation) quanto
GameObject ;
BoardUIVer1 tmpUI = tmp.GetComponent < BoardUIVer1 > ();
cadeia name = cadeia .format ( "B1: [{00:00}, {01:00}]" , linha, col);
tmpUI.lblBoardPosition.text = nome;
tmpUI.COL = j;
tmpUI.ROW = i;
boardPlayer [i, j] = tmp;
tmp.name = nome;
col ++;
}
col = 1;
row ++;
}
Código Bloco 51 - Código de Construção do Conselho de Administração do Jogador
Tudo isso código está fazendo é instanciar o nosso pré-fabricada referenciado pelo
variável BoardUnitPrefab , situa-se numa posição <i, 0, j> , onde i é
a linha, e J é a coluna, e o objecto Vector3 é a posição em 3D
da Unidade de Conselho no espaço 3D. A rotação é definido como o padrão do
transformação do objecto.
página 236
Unity 3D - Jogo de Programação Intro
222
Que uma linha é onde o pré-fabricada Unidade Board é instanciado e
colocado no mundo 3D. As próximas linhas de código, formatar o nome
para a unidade de placa, que é, eles aplicar um rótulo de identificação, tal como,
B1 [00,00] e etc ... o i e j valores são atribuídos aos dados interno
variáveis do BoardUIVer1 classe, ROW e COL respectivamente. E
Finalmente, a Unidade de Placa recentemente instanciado é armazenado no-2 dimensão
matriz sional que representa bordo do jogador no local específico
novamente identificados pelos valores de i e j .
NOTA: Quando a unidade do Conselho é instanciado, ele tem um script anexado a ele
chamados BoardUIVer1.cs. Cada vez que um GameObject é introduzido na cena, o
processo é ter todos os scripts, que são habilitados, ligado a ele ser executado, e em
Neste caso, a Awake () ea função start () será chamado pela primeira vez e apenas uma vez, se
eles são definidos. Isso é mencionado, como um lembrete de que esses scripts seria provavelmente
têm os seus próprios initializations e etc ...
O segundo bloco do loop for cria o conselho para o inimigo.
A lógica do código funciona de forma semelhante, a contabilidade é feita um pouco dife-
rentes. Aqui está a lista para a criação bordo inimigo:
// Criar um quadro de 10x10 - Conselho 2
linha = 1; col = 1;
para ( int i = 11; i <21; i ++)
{
para ( int j = 0; j <10; j ++)
{
// Instanciar pré-fabricada e colocá-lo corretamente em cena
GameObject tmp = GameObject .Instantiate ( este .BoardUnitAttackPrefab,
nova Vector3 (i, 0, J), esta .BoardUnitAttackPrefab.transform.rota-
ção) como GameObject ;
BoardUIVer1 tmpUI = tmp.GetComponent < BoardUIVer1 > ();
cadeia name = cadeia .format ( "B2: [{00:00}, {01:00}]" , linha, col);
tmpUI.lblBoardPosition.text = nome;
tmpUI.COL = col-1;
tmpUI.ROW = row-1;
boardEnemy [tmpUI.ROW, tmpUI.COL] = tmp;
tmp.name = nome;
col ++;
}
col = 1;
row ++;
}
Código Bloco 52 - Código para a Construção Inimigo Board

página 237
Vahé Karamian
223
A maior diferença que você vai notar aqui é o ponto de partida para
a variável i . Esta é porque precisamos de deslocar a criação real
do GameObject a uma coordenada específica. Isto é usado especificamente
apenas para a colocação do objecto no mundo 3D.
Se você notar, utilizamos as variáveis de linha e col para os dados reais
atribuição para a Unidade de Conselho, e não as, i e j variáveis como antes.
Isto é porque, a linha e col representam os números que queremos inter
nalmente para a placa de unidade e também o armazenamento do GameObject na
matriz de 2 dimensionsl representando tabuleiro de jogo do inimigo. Outro que não seja
que, tudo o resto é a mesma lógica.
Update () função de implementação
A próxima função devemos olhar é o Update () função. este
função é o coração do script. Ele é chamado a cada quadro único,
o motor de jogo Unity. Também controla o fluxo do jogo.
// Update é chamado uma vez por quadro
anular Update ()
{
Se ( este .IsBusy)
retornar;
Se ( este .count <5)
{
// Se a seta para cima ou o botão direito do mouse foi clicado, em seguida,
alternar entre
// Vertical e horizontal
se ( Input .GetKeyDown ( KeyCode .UpArrow) || entrada .GetMouseButtonUp (1))
isso ! .vertical = este .vertical;
Se ( este .vertical)
{
este .butVertical.gameObject.SetActive ( verdadeiro );
este .butHorizontal.gameObject.SetActive ( false );
}
outro
{
este .butVertical.gameObject.SetActive ( false );
este .butHorizontal.gameObject.SetActive ( verdadeiro );
}
este .CheckPlayerBoard ();
}
outro
{
se (placeEnemyShips)

página 238
Unity 3D - Jogo de Programação Intro
224
{
// botões de orientação desativar
este .butHorizontal.gameObject.SetActive ( false );
este .butVertical.gameObject.SetActive ( false );
//Debug.Log("I VOU COLOCAR navios inimigos AGORA ");
// Colocar os navios inimigos
esta .PlaceEnemyShips ();
este .START_GAME = verdadeiro ;
}
Se ( este .START_GAME)
{
este .butUIReset.gameObject.SetActive ( verdadeiro );
este .canvasScoreBoard.enabled = verdadeiro ;
este .CheckAttackBoard ();
Se ( este .playerHitCount> = esta .maxNumberOfHits || este .ene-
myHitCount> = esta .maxNumberOfHits)
{
este .START_GAME = false ;
}
este .lblPlayerScore.text = cadeia .format ( "{00:00}" , este .play-
erHitCount);
este .lblAIScore.text = cadeia .format ( "{00:00}" , este .enemyHitCount);
}
outro
{
// Alguém ganhou o jogo!
Se ( esse .playerHitCount> = esta .maxNumberOfHits)
{
// Fazer outro gráfico para representar o ícone do vencedor
este .lblPlayerScore.text = cadeia .format ( "{00:00}" , este .play-
erHitCount);
este .imgYouWin.enabled = verdadeiro ;
}
Se ( esse .enemyHitCount> = esta .maxNumberOfHits)
{
// Fazer outro gráfico para representar o ícone do vencedor
este .lblAIScore.text = cadeia .format ( "{00:00}" , este .ene-
myHitCount);
este .imgYouLose.enabled = verdadeiro ;
// Exibe as restantes peças do navio inimigo
para ( int i = 0; i <10; i ++)
{
para ( int j = 0; j <10; j ++)
{
GameObject tmp = boardEnemy [i, j];

página 239
Vahé Karamian
225
se (tmp.GetComponent < BoardUIVer1 > (). OCUPADOS &&! tmp.Get-
Componente < BoardUIVer1 > (). ATACADO)
{
tmp.transform.GetComponent < Renderer > (). material.color =
Cor .cyan;
}
}
}
}
// Muda o modo de processamento de água
Água tmpWater = este .myWater.gameObject.GetComponent < Água > ();
tmpWater.waterMode = água . WaterMode .Reflective;
este .cameraEndGame.gameObject.SetActive ( verdadeiro );
}
}
}
Código Bloco 53 - função Update () definida na classe BoardVer1
O Update () função é um pouco complexo, mas é administrável.
O primeiro se verifica a condição para ver se o segmento está ocupado com base em um
Variável booleana chamada IsBusy , e se assim for, ele sai da função até que o
próximo ciclo. Esta variável é atualizado por pro- colocação navio da AI
cesso.
O bloco condição próxima
Se ( este .count <5)
lida com o jogador de
colocação navio. A contagem variável é usada para manter o controle do lugar-
mento de pedras do jogador. Assim, a partir de 0, incrementa-se de cada vez
há uma colocação bem sucedida de uma peça do jogo em cima da prancha. Dentro
o bloco if, a verificação de código para a entrada do mouse do usuário para ver se o
botão direito do mouse sobre o mouse ou a seta para cima foi pressionada, se EI-
terap uma destas condições for verdadeiro, então a orientação da peça
colocação será invertido. Isso é feito usando o
este .vertical
variável
capaz.
O próximo conjunto de se os blocos são utilizados para atualizar a interface GUI
com base na entrada de utilizador para o botão de orientação. Finalmente, as chamadas de código
a
este .CheckPlayerBoard ();
função que, em seguida, cuida da ac-
colocação tual da peça do jogo. Esta função será coberto
separadamente.
Na seção else do if condição, determinamos se o AI
precisa para começar a colocar as suas peças do jogo ou o jogo está pronto para começar.

página 240
Unity 3D - Jogo de Programação Intro
226
Dentro do corpo da outra condição, vemos o primeiro se condision
E se
(placeEnemyShips)
. Esta condição verifica a variável placeEnemy-
Navios para determinar se o computador AI ainda tem peças do jogo para
colocação, e em caso afirmativo, em seguida, ele chama o
esta .PlaceEnemyShips ();
função
para completar a colocação das peças em conformidade. Esta função
ser coberto separadamente em detalhe. Uma vez que o retorno de função, ele define o VaR
iable para identificar o início do jogo.
Isso nos leva ao próximo se a condição dentro do bloco else
Se ( este .START_GAME)
. Esse bloco de código é onde o jogo real começa,
e a função principal para lidar com a entrada do utilizador e também a
AI é
este .CheckAttackBoard ();
. Esta função é muito envolvido e
serão abordados separadamente. Cada vez através do Update () função,
o código verifica para ver se há um vencedor no jogo.
A seção else do bloco de código exibe corretamente a pontuação para
o usuário. Se o computador AI é o vencedor do jogo, ele também exibirá
todas as peças do jogo no tabuleiro, o que inclui o hit eo no-hit
peças do jogo.
CheckPlayerBoard () implementação da função
Indo para baixo na ordem de como as funções estão a ser chamado a partir de
dentro do Update () função, vamos cobrir a nossa próxima função chamada
CheckPlayerBoard () .
private void CheckPlayerBoard ()
{
se ( Input .mousePosition! = NULL )
{
// Capturar a posição do mouse e lança um raio para ver o objeto que atingiu
Ray ray = Câmara .main.ScreenPointToRay ( Input .mousePosition);
se ( Física .Raycast (ray, fora tmpHitHighlight, 100))
{
BoardUIVer1 tmpUI = tmpHitHighlight.transform.GetCompo-
nente < BoardUIVer1 > ();
se (tmpHitHighlight.transform.tag.Equals ( "Conselho" ) &&
! TmpUI.OCCUPIED)
{
BoardUIVer1 boardData = boardPlayer [tmpUI.ROW,
tmpUI.COL] .transform.GetComponent < BoardUIVer1 > ();
se (tmpHighlight! = NULL )

página 241
Vahé Karamian
227
{
Se (boardData.OCCUPIED)
tmpHighlight.GetComponent < Renderer > (). material.color =
Cor .Red;
outro
tmpHighlight.GetComponent < Renderer > (). material.color =
Cor .white;
}
Se ( esse .tmpBlockHolder! = NULL )
{
Destroy ( este .tmpBlockHolder);
}
Se ( este .PLACE_BLOCK)
{
este .tmpBlockHolder = new GameObject ();
este .OK_TO_PLACE = verdadeiro ;
se (! este .vertical && (tmpUI.ROW <= 10 - este .blockSize))
{
para ( int i = 0; i < esta .blockSize; i ++)
{
GameObject visuais = GameObject .Instantiate ( este .CubeP-
refab, nova Vector3 (tmpUI.ROW + i, este .CubePrefab.transform.position.y,
tmpUI.COL), este .CubePrefab.transform.rotation) como GameObject ;
GameObject bp = boardPlayer [tmpUI.ROW + i, tmpUI.COL];
BoardUIVer1 bpUI = bp.GetComponent < BoardUIVer1 > ();
se (! bpUI.OCCUPIED)
{
visual.GetComponent < Renderer > (). material.color =
Colorir .gray; // ok para o lugar
}
outro
{
visual.transform.localScale = new Vector3 (0.6f,
0.6f, 0.6f);
visual.GetComponent < Renderer > (). material.color =
Cor .yellow; // Não ok
este .OK_TO_PLACE = false ;
}
visual.transform.parent = este .tmpBlockHolder.trans-
Formato;
}
}
Se ( esse .vertical && (tmpUI.COL <= 10 - este .blockSize))
{
para ( int i = 0; i < esta .blockSize; i ++)
{
GameObject visuais = GameObject .Instantiate ( este .CubeP-
refab, nova Vector3 (tmpUI.ROW, este .CubePrefab.transform.position.y,
tmpUI.COL + i), esta .CubePrefab.transform.rotation) como GameObject ;
GameObject bp = boardPlayer [tmpUI.ROW, tmpUI.COL + i];

página 242
Unity 3D - Jogo de Programação Intro
228
BoardUIVer1 bpUI = bp.GetComponent < BoardUIVer1 > ();
se (! bpUI.OCCUPIED)
{
visual.GetComponent < Renderer > (). material.color =
Colorir .gray; // ok para o lugar
}
outro
{
visual.transform.localScale = new Vector3 (0.6f,
0.6f, 0.6f);
visual.GetComponent < Renderer > (). material.color =
Cor .yellow; // Não ok
este .OK_TO_PLACE = false ;
}
visual.transform.parent = este .tmpBlockHolder.trans-
Formato;
}
}
}
tmpHitHighlight.transform.GetComponent < Renderer > (). mate-
rial.color = Cor .Blue;
tmpHighlight = tmpHitHighlight.transform.gameObject;
}
}
}
Se ( entrada .GetMouseButton (0))
{
// Capturar a posição do mouse e lança um raio para ver o objeto que atingiu
Ray ray = Câmara .main.ScreenPointToRay ( Input .mousePosition);
RaycastHit atingido;
se ( Física .Raycast (ray, fora atingido, 100))
{
Debug log (hit.transform.gameObject.name);
se (hit.transform.tag.Equals ( "board" ))
{
BoardUIVer1 tmpUI = hit.transform.GetComponent < BoardUIVer1 > ();
Se ( este .PLACE_BLOCK && este .OK_TO_PLACE)
{
se (! este .vertical)
{
para ( int i = 0; i < esta .blockSize; i ++)
{
GameObject sB = boardPlayer [tmpUI.ROW + i, tmpUI.COL];
sB.transform.GetComponent < Renderer > (). material.color =
Cor .Green;
sB.GetComponent < BoardUIVer1 > () ocuparam =. verdadeira ;

página 243
Vahé Karamian
229
sB.GetComponent < BoardUIVer1 > (). CubePrefab.gameOb-
ject.GetComponent < Renderer .> () material.color = Cor .Green;
boardPlayer [tmpUI.ROW + i, tmpUI.COL] = sB;
}
}
Se ( este .vertical)
{
para ( int i = 0; i < esta .blockSize; i ++)
{
GameObject sB = boardPlayer [tmpUI.ROW, tmpUI.COL + i];
sB.transform.GetComponent < Renderer > (). material.color =
Cor .Green;
sB.GetComponent < BoardUIVer1 > () ocuparam =. verdadeira ;
sB.GetComponent < BoardUIVer1 > (). CubePrefab.gameOb-
ject.GetComponent < Renderer .> () material.color = Cor .Green;
boardPlayer [tmpUI.ROW, tmpUI.COL + i] = sB;
}
}
este .CheckWhichShipWasPlaced (tmpUI.ROW, tmpUI.COL);
este .OK_TO_PLACE = verdadeiro ;
tmpHighlight = NULL ;
}
// Grupo bloco na placa
Se ( esse .count> = 5)
{
Se ( esse .tmpBlockHolder! = NULL )
{
Destroy ( este .tmpBlockHolder);
}
}
}
}
}
}
Código Bloco 54 - CheckPlayerBoard () Definição de Função
Então, a primeira coisa que esta função faz é verificar para ver se o In-
put.mousePosition não é nulo. Isto é importante, porque as necessidades do usuário
usar o mouse para colocar o seu jogo pedaço em cima da prancha.
A próxima linha de código é muito importante. Estamos criando uma Ray ob-
JECT usando a posição do mouse.

página 244
Unity 3D - Jogo de Programação Intro
230
Definição matemática de um raio: Uma porção de uma linha que se inicia num ponto
e apaga-se em uma determinada direção ao infinito.
Um raio é usado na Unidade, em conjunto com o Raycast () função
definido na Física objecto, para gerar uma linha lógica no espaço 3D
e quando você atirar o raio, ele realmente irá fornecer informações indepen-
ing qualquer objeto em seu caminho. É basicamente usado para Ray Fundição
23
.
Este satetement especial
se ( Física .Raycast (ray, fora tmpHi-
tHighlight, 100))
, É o que faz o nosso trabalho Raycast e também retorna
os dados necessários necessário. Os dados de hit é armazenado em tmpHighligh variação
ble. Antes de continuar, também deve listar algumas variáveis temporárias
que são usadas especificamente dentro do CheckPlayerBoard () função.
GameObject tmpHighlight = NULL ;
RaycastHit tmpHitHighlight;
GameObject tmpBlockHolder = NULL ;
bool privada OK_TO_PLACE = verdadeiro ;
Código Bloco 55 - variáveis temporário utilizado pelo CheckPlayerBoard ()
NOTA: As variáveis enumeradas no bloco de código 55 a re todos também parte da classe
dados, no entanto, eles foram listados logo acima do CheckPlayerBoard () função
para esclarecimentos.
Devido à natureza da configuração da cena sabemos que os únicos objetos
que pode ser atingido pelo Raycast vão ser os Conselhos de Unidade e também
as outras peças do jogo. O que gostaríamos de fazer é extrair o
BoardUIVer1 componente do tmpHitHighlight variável e início
processar o objecto.
Há duas condições que estamos procurando, em primeiro lugar, queremos fazer
-se que o hit raycast registado uma unidade de bordo. Isto é feito com a
identificação da etiqueta. A segunda condição é ter certeza de que o
determinada unidade de bordo não é ocupada. Se forem satisfeitas estas duas condições,
23
Raio de fundição é a utilização de testes de intersecção do raio da superfície de resolver uma
variedade de problemas em
computação gráfica e geometria computacional. O termo foi usado pela primeira vez em
computação gráfica
em um papel 1982 por Scott Roth para descrever um método para render geometria sólida
construtiva
modelos.

página 245
Vahé Karamian
231
prosseguir com o processamento dos dados reais no boardPlayer [,] 2 dimensão
matriz cional armazenar o nó de dados reais.
O código fica bastante complexa aqui, então vamos levá-la a seção por seção
ção.
se ( Física .Raycast (ray, fora tmpHitHighlight, 100))
{
BoardUIVer1 tmpUI = tmpHitHighlight.transform.GetCompo-
nente < BoardUIVer1 > ();
se (tmpHitHighlight.transform.tag.Equals ( "Conselho" ) &&
! TmpUI.OCCUPIED)
{
BoardUIVer1 boardData = boardPlayer [tmpUI.ROW,
tmpUI.COL] .transform.GetComponent < BoardUIVer1 > ();
se (tmpHighlight! = NULL )
{
Se (boardData.OCCUPIED)
tmpHighlight.GetComponent < Renderer > (). material.color =
Cor .Red;
outro
tmpHighlight.GetComponent < Renderer > (). material.color =
Cor .white;
}
Se ( esse .tmpBlockHolder! = NULL )
{
Destroy ( este .tmpBlockHolder);
}
Se ( este .PLACE_BLOCK)
{
este .tmpBlockHolder = new GameObject ();
este .OK_TO_PLACE = verdadeiro ;
se (! este .vertical && (tmpUI.ROW <= 10 - este .blockSize))
{
para ( int i = 0; i < esta .blockSize; i ++)
{
GameObject visuais = GameObject .Instantiate ( este .CubeP-
refab, nova Vector3 (tmpUI.ROW + i, este .CubePrefab.transform.position.y,
tmpUI.COL), este .CubePrefab.transform.rotation) como GameObject ;
GameObject bp = boardPlayer [tmpUI.ROW + i, tmpUI.COL];
BoardUIVer1 bpUI = bp.GetComponent < BoardUIVer1 > ();
se (! bpUI.OCCUPIED)
{
visual.GetComponent < Renderer > (). material.color =
Colorir .gray; // ok para o lugar
}
outro
{

página 246
Unity 3D - Jogo de Programação Intro
232
visual.transform.localScale = new Vector3 (0.6f,
0.6f, 0.6f);
visual.GetComponent < Renderer > (). material.color =
Cor .yellow; // Não ok
este .OK_TO_PLACE = false ;
}
visual.transform.parent = este .tmpBlockHolder.trans-
Formato;
}
}
Se ( esse .vertical && (tmpUI.COL <= 10 - este .blockSize))
{
para ( int i = 0; i < esta .blockSize; i ++)
{
GameObject visuais = GameObject .Instantiate ( este .CubeP-
refab, nova Vector3 (tmpUI.ROW, este .CubePrefab.transform.position.y,
tmpUI.COL + i), esta .CubePrefab.transform.rotation) como GameObject ;
GameObject bp = boardPlayer [tmpUI.ROW, tmpUI.COL + i];
BoardUIVer1 bpUI = bp.GetComponent < BoardUIVer1 > ();
se (! bpUI.OCCUPIED)
{
visual.GetComponent < Renderer > (). material.color =
Colorir .gray; // ok para o lugar
}
outro
{
visual.transform.localScale = new Vector3 (0.6f,
0.6f, 0.6f);
visual.GetComponent < Renderer > (). material.color =
Cor .yellow; // Não ok
este .OK_TO_PLACE = false ;
}
visual.transform.parent = este .tmpBlockHolder.trans-
Formato;
}
}
}
tmpHitHighlight.transform.GetComponent < Renderer > (). mate-
rial.color = Cor .Blue;
tmpHighlight = tmpHitHighlight.transform.gameObject;
}
}
}
Código Bloco 56 - Determinar o que objetar que têm atingido por vazamento ray.

página 247
Vahé Karamian
233
Tentar explicar o que está acontecendo na linha-a-linha será um pouco excessiva
whelming. Não faria mais sentido para dar-lhe um informativo geral
ver no bloco de código e ter você cavar através dele para os detalhes.
Código Bloco 56 do es algumas coisas para nós. A primeira coisa que per-
formas é nosso elenco ray. Nós obter os dados retornados pelo ray casting
functino para determinar que tipo de GameObjects temos atingido. Se o
GameObject retornado é uma Unidade Conselho pertencente ao jogador, eo
Unidade de bordo não está ocupado, começamos o processo principal de recuperar a
principais dados da matriz de 2 dimensões que prendem a placa jogo real
dados. Com base no estado da unidade da placa de sucesso, que altere a cor da
unidade de bordo para vermelho se ele estiver ocupado, visualmente notificando o usuário que
eles não pode colocar uma unidade em que o local particular, ou que é o branco
cor padrão para uma placa de unidade vazio.
Em seguida, se o jogador é capaz de colocar seu bloco, o código itera
através do e gera dinamicamente pistas visuais para a colocação de
a parte do jogo, neste caso, o selecione peça navio. Durante todo o iterações
ção e de verificação da disponibilidade de unidades de tabuleiro ao longo da via,
que determina se a peça do jogo pode ser colocado no local seleccionado ou
não. Se todos os controlos e verificações são OK o programa, em seguida, na verdade,
toma os dados e grava-lo no tabuleiro de jogo do jogador. Este processo
repete até que todas as peças do jogo foram colocados em cima da prancha.
CheckWhichShipWasPlaced () implementação da função
Esta função é usada para inicializar os prefabs do navio seleccionado
para ser colocado no tabuleiro. Usou-se as posições de linha e coluna como a
origem para a colocação ea identificação real do navio é feito
através do ID que foi atribuído em tempo de design.
private void CheckWhichShipWasPlaced ( int linha, int col)
{
interruptor ( este .currentShipID)
{
case 1:
{
se (! este .vertical)
{
// Lugar que o mais vertical
GameObject testingVisual = GameObject .Instantiate ( este .Admi-
ralKuznetsov, nova Vector3 (linha + 2,

página 248
Unity 3D - Jogo de Programação Intro
234
este .AdmiralKuznetsov.transform.position.y, col), este .AdmiralKuz-
netsov.transform.rotation) como GameObject ;
testingVisual.transform.RotateAround (testingVisual.transform.po-
sição, Vector3 .Até, 90.0f);
}
outro
{
GameObject testingVisual = GameObject .Instantiate ( este .Admi-
ralKuznetsov, nova Vector3 (linha, este .AdmiralKuznetsov.transform.position.y,
col + 2), este .AdmiralKuznetsov.transform.rotation) como GameObject ;
}
// Porta-aviões foi colocada, botão de desativar
este .butAircraftCarrier.gameObject.SetActive ( false );
este .count ++;
break;
}
Caso 2:
{
se (! este .vertical)
{
// Lugar que o mais vertical
GameObject testingVisual = GameObject .Instantiate ( este .Stere-
gushchiy, nova Vector3 (linha + 1.5f, este .Steregushchiy.transform.position.y,
col), este .Steregushchiy.transform.rotation) como GameObject ;
testingVisual.transform.RotateAround (testingVisual.transform.po-
sição, Vector3 .Até, 90.0f);
}
outro
{
GameObject testingVisual = GameObject .Instantiate ( este .Stere-
gushchiy, nova Vector3 (linha, este .Steregushchiy.transform.position.y,
col + 1.5f), este .Steregushchiy.transform.rotation) como GameObject ;
}
// Navio de batalha foi colocada, botão de desativar
este .butBattleship.gameObject.SetActive ( false );
este .count ++;
break;
}
Caso 3:
{
se (! este .vertical)
{
// Lugar que o mais vertical
GameObject testingVisual = GameObject .Instantiate ( este .Admiral-
SergeyGorshkov, nova Vector3 (linha + 1,
este .AdmiralSergeyGorshkov.transform.position.y, col),
este .AdmiralSergeyGorshkov.transform.rotation) como GameObject ;
testingVisual.transform.RotateAround (testingVisual.transform.po-
sição, Vector3 .Até, 90.0f);
}

página 249
Vahé Karamian
235
outro
{
GameObject testingVisual = GameObject .Instantiate ( este .Admiral-
SergeyGorshkov, nova Vector3 (linha,
este .AdmiralSergeyGorshkov.transform.position.y, col + 1),
este .AdmiralSergeyGorshkov.transform.rotation) como GameObject ;
}
// Submarine foi colocado, desativar o botão
este .butSubmarine.gameObject.SetActive ( false );
este .count ++;
break;
}
Caso 4:
{
se (! este .vertical)
{
// Lugar que o mais vertical
GameObject testingVisual = GameObject .Instantiate ( este .IverHuit-
Feldt, nova Vector3 (linha + 1,
este .IverHuitfeldt.transform.position.y, col),
este .IverHuitfeldt.transform.rotation) como GameObject ;
testingVisual.transform.RotateAround (testingVisual.transform.po-
sição, Vector3 .Até, 90.0f);
}
outro
{
GameObject testingVisual = GameObject .Instantiate ( este .IverHuit-
Feldt, nova Vector3 (linha,
este .IverHuitfeldt.transform.position.y, col + 1),
este .IverHuitfeldt.transform.rotation) como GameObject ;
}
// Destroyer foi colocado, desativar o botão
este .butDestroyer.gameObject.SetActive ( false );
este .count ++;
break;
}
Caso 5:
{
se (! este .vertical)
{
// Lugar que o mais vertical
GameObject testingVisual = GameObject .Instanti-
comeu ( este .MRVikhrIFQ, nova Vector3 (linha + 0.5f,
este .MRVikhrIFQ.transform.position.y, col), este .MRVikhrIFQ.transform.rota-
ção) como GameObject ;
testingVisual.transform.RotateAround (testingVisual.transform.po-
sição, Vector3 .Até, 90.0f);
}
outro
{
GameObject testingVisual = GameObject .Instanti-
comeu ( este .MRVikhrIFQ, nova Vector3 (linha,

página 250
Unity 3D - Jogo de Programação Intro
236
este .MRVikhrIFQ.transform.position.y, col + 0.5f), este .MRVikhrIFQ.trans-
form.rotation) como GameObject ;
}
// Barco de patrulha foi colocado, desativar o botão
este .butPatrolBoat.gameObject.SetActive ( false );
este .count ++;
break;
}
}
// Dados internos clara
este .currentShipID = 0;
este .blockSize = 0;
}
Código Bloco 57 - Visualmente colocando a peça selecionada para o tabuleiro de jogo
O principal lógico no código aqui é para identificar o ID do navio e
instanciar corretamente o pré-fabricada associado para o tabuleiro de jogo.
PlaceEnemyShips () implementação da função
Uma vez que todas as peças do jogo do jogador foram colocados no
bordo, a AI tem de fazer o mesmo. Os PlaceEnemyShips () função
é usada para colocar as peças para o adversário do computador.
private void PlaceEnemyShips ()
{
este .placeEnemyShips = false ;
para ( int i = 0; i < esta .ships.Length; i ++)
{
int linha = Aleatório .Range (0,9);
int col = Aleatório .Range (0,9);
bool ori = ( aleatório .Range (0, 9)> 5)? verdadeira : false ;
este .CheckBoardForEnemyPlacement (linha, col, este .ships [i], ori);
}
}
Código Bloco 58 - Função de AI para colocar peças do jogo
A função usa um loop for para percorrer todo o jogo
peças que precisam ser colocados no tabuleiro de jogo AI. Dentro do para
loop, a lógica gera uma linha aleatória e uma posição da coluna aleatória
e uma orientação aleatória para o pedaço de corrente que está a ser preparado para
colocação.

página 251
Vahé Karamian
237
CheckBoardForEnemyPlacement () implementação da função
O trabalho real é feito por uma função de apoio denominado Check
BoardForEnemyPlacement () . Esta é uma função recursiva e é aqui
a lista para ele.
private void CheckBoardForEnemyPlacement ( int linha, int col, int tamanho, bool
hor)
{
GameObject checkUnit = boardEnemy [linha, col];
se (checkUnit.GetComponent < BoardUIVer1 > (). OCUPADOS || (linha + size> 9) ||
(Col + size> 9))
{
int R1 = aleatória .Range (0, 9);
int C1 = aleatória .Range (0, 9);
este .CheckBoardForEnemyPlacement (R1, c1, tamanho hor);
retornar;
}
bool okToPlace = verdadeiro ;
se (! hor && (linha + tamanho <10))
{
para ( int i = 0; i <size; i ++)
{
GameObject bp = boardEnemy [row + i, col];
BoardUIVer1 bpUI = bp.GetComponent < BoardUIVer1 > ();
se (! bpUI.OCCUPIED)
{
// OkToPlace = true;
}
outro
{
okToPlace = false ;
}
}
}
se (hor && (tamanho col + <10))
{
para ( int i = 0; i <size; i ++)
{
GameObject bp = boardEnemy [linha, col + i];
BoardUIVer1 bpUI = bp.GetComponent < BoardUIVer1 > ();
se (! bpUI.OCCUPIED)
{
// OkToPlace = true;
}
outro
{
okToPlace = false ;
}
}

página 252
Unity 3D - Jogo de Programação Intro
238
}
Se (okToPlace)
{
se (hor!)
{
para ( int i = 0; i <size; i ++)
{
GameObject visuais = GameObject .Instantiate ( este .CubePrefab,
nova Vector3 (linha + i, 11.9f, col),
este .CubePrefab.transform.rotation) como GameObject ;
visual.GetComponent < Renderer > () material.color =. Cor .yellow;
visual.tag = "enemyPrefabPH" ;
GameObject sB = boardEnemy [row + i, col];
sB.GetComponent < BoardUIVer1 > () ocuparam =. verdadeira ;
boardEnemy [row + i, col] = sB;
visual.gameObject.name = cadeia .format ( "EN-R - [{0}, {1}]" , row +
i, col);
}
}
se (hor)
{
para ( int i = 0; i <size; i ++)
{
GameObject visuais = GameObject .Instantiate ( este .CubePrefab,
nova Vector3 (linha, 11.9f, col + i),
este .CubePrefab.transform.rotation) como GameObject ;
visual.GetComponent < Renderer > () material.color =. Cor .magenta;
GameObject sB = boardEnemy [linha, col + i];
sB.GetComponent < BoardUIVer1 > () ocuparam =. verdadeira ;
boardEnemy [linha, col + i] = sB;
visual.gameObject.name = cadeia .format ( "EN-C - [{0}, {1}]" , fila,
col + i);
}
}
}
outro
{
int R1 = aleatória .Range (0, 9);
int C1 = aleatória .Range (0, 9);
este .CheckBoardForEnemyPlacement (R1, c1, tamanho hor);
}
}
Código Bloco 59 - Função responsável pela colocação peça do jogo AI

página 253
Vahé Karamian
239
Atravessar a função você notar que usamos a linha e col
que foram passados para a função para obter os dados a partir do 2-dimensional
matriz que representa tabuleiro de jogo do computador. A próxima verificação é de-
minar se a posição seleccionada já está ocupado ou não, e se o
linha e coluna, mais o tamanho da peça estão dentro dos limites do jogo
Placa dada a posição. Se este não for o caso, o programa de re-ge-
ates esses valores e chama próprio novamente.
Se o primeiro cheque é passado, vamos passar para a segunda seleção. Somente
como quando estávamos colocando as peças do jogo do jogador, precisamos de uma forma de
determinar se a posição seleccionada pelo computador é válido para lugar-
mento.
Se estamos OK para colocar a peça, em seguida, o programa atualiza o
placas unidade identificada com o status mais recente. Caso contrário, ele gera uma
novo conjunto de linha e coluna e chama a função mais uma vez, e vai
por todo o processo novamente. Isto continua da até que todo o
peças foram correctamente colocada na placa do computador. Se houver
uma falta, então a vez de atacar é alterado para o jogador.
CheckAttackBoard () implementação da função
Seguindo em frente, a próxima função temos lista de é o Check
AttackBoard () função.
private void CheckAttackBoard ()
{
// Verifica para ver quem é transformá-lo é
Se ( este .PLAYER_TURN)
{
se ( Input .mousePosition! = NULL )
{
// Capturar a posição do mouse e lança um raio para ver o objeto que
acertar
Ray ray = Câmara .main.ScreenPointToRay ( Input .mousePosition);
se ( Física .Raycast (ray, fora tmpAttackHitHighlight, 200))
{
BoardUIVer1 tmpUI = tmpAttackHitHighlight.transform.GetCompo-
nente < BoardUIVer1 > ();
Se (tmpAttackHitHighlight.transform.tag.Equals ( "boardAttack" ) &&
! TmpUI.ATTACKED)
{
GameObject pb = boardEnemy [tmpUI.ROW, tmpUI.COL];
BoardUIVer1 bpUI = bp.GetComponent < BoardUIVer1 > ();

página 254
Unity 3D - Jogo de Programação Intro
240
se (tmpAttackHighlight! = NULL )
{
Se (bpUI.ATTACKED)
{
Se (bpUI.ATTACKED)
{
tmpAttackHighlight.GetComponent < Renderer > (). mate-
rial.color = Cor .gray;
}
}
outro
{
tmpAttackHighlight.GetComponent < Renderer > (). mate-
rial.color = Cor .white;
}
}
tmpAttackHitHighlight.transform.GetComponent < Renderer > (). ma-
terial.color = Cor .Blue;
tmpAttackHighlight = tmpAttackHitHighlight.transform.gameOb-
jecto;
}
}
}
Se ( entrada .GetMouseButton (0))
{
Ray ray1 = Câmara .main.ScreenPointToRay ( Input .mousePosition);
RaycastHit atingido;
se ( Física .Raycast (ray1, fora batida, 200))
{
Debug log (hit.transform.gameObject.name);
Se (hit.transform.tag.Equals ( "boardAttack" ))
{
BoardUIVer1 tmpUI = hit.transform.GetCompo-
nente < BoardUIVer1 > ();
GameObject enemyBoard = boardEnemy [tmpUI.ROW, tmpUI.COL];
Debug log ( cadeia .format ( "Board inimigo: {0}" , enemyBoard.trans-
form.name));
// Verificar para ver se temos um hit na placa de jogador
// Precisamos ter certeza de que nós não aumentam apenas porque
estamos acertando a bordo
se (enemyBoard.GetComponent < BoardUIVer1 > (). OCUPADOS &&! eno-
myBoard.GetComponent < BoardUIVer1 > (). ATACADO)
{
// Temos um hit
enemyBoard.transform.GetComponent < BoardUIVer1 > (). OCUPADOS
= Verdadeiro ;
enemyBoard.transform.GetComponent < BoardUIVer1 > (). ATACADO
= Verdadeiro ;

página 255
Vahé Karamian
241
enemyBoard.transform.GetComponent < Renderer > (). mate-
rial.color = Cor .Red;
hit.transform.GetComponent < Renderer > (). material.color =
Cor .Red;
// Temos um hit, áudio explosão jogo
este .audioSource.PlayOneShot ( este .explosionEnemyBlast,
0.75f);
este .playerHitCount + = 1;
este .playerHadHit = verdadeiro ;
}
outro
{
enemyBoard.transform.GetComponent < BoardUIVer1 > (). ATACADO
= Verdadeiro ;
enemyBoard.transform.GetComponent < Renderer > (). mate-
rial.color = Cor .gray;
hit.transform.GetComponent < Renderer > (). material.color =
Cor .gray;
este .playerHadHit = false ;
}
boardEnemy [tmpUI.ROW, tmpUI.COL] = enemyBoard;
tmpAttackHighlight = NULL ;
}
}
}
Se ( entrada .GetMouseButtonUp (0))
{
se (! este .playerHadHit)
{
// Agora vamos capturar o verdadeiro aspecto de virada do jogador vs.
AI
este .PLAYER_TURN =! este .PLAYER_TURN;
este .playerHadHit = false ;
}
}
}
outro
{
int R1 = 0;
int C1 = 0;
Se ( este .gotoLastHit)
{
este .hit_dir = este .hit_dir_last;
este .hit_row = este .hit_row_last;
este .hit_col = este .hit_col_last;
este .gotoLastHit = false ;
}
interruptor ( este .hit_dir)

página 256
Unity 3D - Jogo de Programação Intro
242
{
// Certifique-se de verificar os limites ...
caso HitDirection .Até:
{
R1 = este .hit_row + 1;
c1 = este .hit_col;
break;
}
caso HitDirection .right:
{
c1 = este .hit_col + 1;
R1 = este .hit_row;
break;
}
caso HitDirection .down:
{
R1 = este .hit_row - 1;
c1 = este .hit_col;
break;
}
caso HitDirection .Left:
{
c1 = este .hit_col - 1;
R1 = este .hit_row;
break;
}
default:
{
R1 = aleatória .Range (0, 9);
C1 = aleatória .Range (0, 9);
break;
}
}
se ((R1 <0 || R1> 9) || (c1 <0 || C1> 9))
{
// Nós aldo precisa verificar e alterar hit_direction aqui ...
este .ChangeHitDirection ();
este .CheckAttackBoard ();
// Tentar uma nova unidade
retornar;
// Saída após a chamada de volta
}
Debug log ( cadeia .format ( "R1 = {0}, C1 = {1}" , R1, c1));
GameObject playerBoard = boardPlayer [R1, C1];
// Verificar para ver se a unidade tiver sido atacados antes, se tiver sido
em seguida, tentar um novo local
se (playerBoard.GetComponent < BoardUIVer1 > (). ATACADO)
{
// Nós aldo precisa verificar e alterar hit_direction aqui ...
este .ChangeHitDirection ();

página 257
Vahé Karamian
243
este .CheckAttackBoard ();
// Tentar uma nova unidade
retornar;
// Saída após a chamada de volta
}
// Verificar para ver se temos um hit na placa de jogador
se (playerBoard.GetComponent < BoardUIVer1 > (). ocupada)
{
// Temos um hit
playerBoard.transform.GetComponent < BoardUIVer1 > () ocuparam =. verdadeira ;
playerBoard.transform.GetComponent < BoardUIVer1 > () ATACADO =. verdadeira ;
playerBoard.transform.GetComponent < Renderer > (). material.color =
Cor .Red;
// Temos um hit, áudio explosão jogo
este .audioSource.PlayOneShot ( este .explosionPlayerBlast, 0.75f);
este .enemyHitCount + = 1;
// Temos um hit
esta .hit_col = c1;
este .hit_row = R1;
esta .hit_col_last = c1;
este .hit_row_last = R1;
este .hit_dir_last = este .hit_dir;
Se ( esse .hit_dir == HitDirection .none)
este .hit_dir = HitDirection .Até;
StartCoroutine ( este .Wait4Me ());
}
outro
{
playerBoard.transform.GetComponent < BoardUIVer1 > () ATACADO =. verdadeira ;
playerBoard.transform.GetComponent < Renderer > (). material.color =
Cor .gray;
este .ChangeHitDirection ();
este .PLAYER_TURN =! este .PLAYER_TURN;
este .gotoLastHit = verdadeiro ;
}
boardPlayer [R1, C1] = playerBoard;
}
}
Código Block 60 - CheckAttackBoard lista de funções
A função CheckAttachBoard () é utilizado tanto pelo jogador e
Também a AI durante o tempo de jogo. O que significa que, quando o jogador picaretas
uma placa de unidade no tabuleiro de jogo inimigo, ou o AI seleccionar uma placa de unidade
no tabuleiro de jogo do jogador, então essa função é usada como o ponto de partida

página 258
Unity 3D - Jogo de Programação Intro
244
ponto. Como antes, a função é dependente de mais algumas variáveis para
contabilidade e etc ... O que se segue é uma lista das variáveis usadas dentro
a função:
GameObject tmpAttackHighlight = NULL ;
RaycastHit tmpAttackHitHighlight;
GameObject tmpAttackBlockHolder = NULL ;
#region Memória AI para o sucesso Hit
public enum HitDirection {none, para cima, direita, baixo, esquerda};
int pública hit_row;
// Usado para a linha atual hit
int pública hit_col;
// Usado para col atual hit
pública HitDirection hit_dir;
// Usado para dir atual hit
int pública hit_row_last;
// Usado para última linha hit conhecido
int pública hit_col_last;
// Usado para última col hit conhecido
pública HitDirection hit_dir_last;
// Usado para última dir hit conhecido
bool pública playerHadHit = false ;
bool pública gotoLastHit = false ;
#endregion
função de variáveis utilizadas por CheckAttackBoard () - código de bloco 61
As variáveis que listei n código de bloco 61 são especificamente utilizados pela
CheckAttackBoard () função. Como foi referido anteriormente, têm sido de-
multado antes da função para maior clareza.
Uma grande diferença que deve chamar sua atenção, enquanto você rever
o código, é as variáveis definidas para as operações de IA. As necessidades de IA
para representar a seleção atual hit, e ele também precisa manter o controle de
a sua jogada anterior para que ele possa determinar o local e direção
para mover seguinte. As variáveis definidas no bloco de código 61 ajuda com estes
operações.
O primeiro se os cheques de bloco para ver quem é a vez para o ataque. Como-
suming que é a vez do jogador, o programa mais uma vez usa o raio
lançou a operação para agarrar a unidade de bordo que tenha sido devolvido através do
tmpAttackHighlight variável. A lógica aqui é quase a mesma que a
definido no CheckPlayerBoard () função. Mas observe que a nossa condição
ções são diferentes. Estamos verificando para ter certeza de que está selecionando o
O conselho do inimigo para o movimento de ataque, e que a placa selecionada
unidade não tem sido atacada antes.

página 259
Vahé Karamian
245
Se a condição for atendida, usamos a matriz de dados 2-dimensional que
armazena os dados da placa do inimigo para recuperar o estado atual do conselho
unidade e fazer modificações a ele com base em um êxito ou um fracasso. Durante o
processo também usamos notificação visual com base no estado do tabuleiro.
Esta lógica acontece durante a seleção / movimento do mouse sobre
placa do inimigo. Uma vez que o botão esquerdo do mouse foi clicado, em seguida,
as operações reais começar por se registar um sucesso ou um fracasso.
Se (hit.transform.tag.Equals ( "boardAttack" ))
{
BoardUIVer1 tmpUI = hit.transform.GetComponent < BoardUIVer1 > ();
GameObject enemyBoard = boardEnemy [tmpUI.ROW, tmpUI.COL];
Debug log ( cadeia .format ( "Board inimigo: {0}" , enemyBoard.transform.name));
// Verificar para ver se temos um hit na placa de jogador
// Precisamos ter certeza de que nós não aumentar só porque somos hit-
ting a placa
se (enemyBoard.GetComponent < BoardUIVer1 > (). OCUPADOS &&! enemyBoard.Get-
Componente < BoardUIVer1 > (). ATACADO)
{
// Temos um hit
enemyBoard.transform.GetComponent < BoardUIVer1 > () ocuparam =. verdadeira ;
enemyBoard.transform.GetComponent < BoardUIVer1 > () ATACADO =. verdadeira ;
enemyBoard.transform.GetComponent < Renderer > (). material.color =
Cor .Red;
hit.transform.GetComponent < Renderer .> () material.color = Cor .Red;
// Temos um hit, áudio explosão jogo
este .audioSource.PlayOneShot ( este .explosionEnemyBlast, 0.75f);
este .playerHitCount + = 1;
este .playerHadHit = verdadeiro ;
}
outro
{
enemyBoard.transform.GetComponent < BoardUIVer1 > () ATACADO =. verdadeira ;
enemyBoard.transform.GetComponent < Renderer > (). material.color =
Cor .gray;
hit.transform.GetComponent < Renderer .> () material.color = Cor .gray;
este .playerHadHit = false ;
}
boardEnemy [tmpUI.ROW, tmpUI.COL] = enemyBoard;
tmpAttackHighlight = NULL ;
}
Bloco de código 62 - Registrando um êxito ou um fracasso pelo jogador

página 260
Unity 3D - Jogo de Programação Intro
246
No bloco de código 62, nós isolamos o código responsável pela
registo de um êxito ou um fracasso pelo jogador. Se tivermos um sucesso, nós atualizamos
o estado do tabuleiro da unidade, em conformidade, a exposição, bem como os dados
que representa a placa na matriz 2-dimensional. Da mesma forma que fazemos
o mesmo se o ataque é uma miss.
Há uma última condição é preciso verificar, se o jogador tem um hit,
então será novamente a vez do jogador para selecionar a próxima posição de ataque.
Caso contrário, damos a volta ao AI
Se ( entrada .GetMouseButtonUp (0))
{
se (! este .playerHadHit)
{
// Agora vamos capturar o verdadeiro aspecto de virada do jogador vs. AI
este .PLAYER_TURN =! este .PLAYER_TURN;
este .playerHadHit = false ;
}
}
Código Bloco 63 - Mudando voltas após a seleção do Jogador
Olhando para o cenário onde é a vez do AI para atacar, o AI
verifica para ver se ele tinha um hit do movimento anterior, e se assim for, torna-se
a direção sucesso, a linha hit ea coluna hit. Com base na mações
mação fornecida, decide onde fazer sua próxima jogada. Depois de
mover nós certifique-se de que estão nos limites do tabuleiro. E se
não, nós recursivamente chamar a função para obter uma nova posição de ataque.
Se tudo estiver bem, nós agarrar dados bordo unidade do jogador, e verifique
se tiver sido anteriormente atacados, se assim que nós começamos uma nova posição.
Por fim, verifique se a posição selecionada é ocupado, este
determina se temos um hit para o movimento. O programa executa a
contabilidade necessário, salva os dados atualizados para o 2-dimensional
matriz que representa bordo do jogador e o processo vai para o próximo
passo.

página 261
Vahé Karamian
247
ChangeHitDirection () implementação da função
A AI usa outra função para determinar a direção para acertar
no quadro. Isto é feito através da ChangeHitDirection () função.
Aqui está uma lista da função:
private void ChangeHitDirection ()
{
interruptor ( este .hit_dir)
{
// Mudança de direção com base na lógica
caso HitDirection .none:
{
este .hit_dir = HitDirection .Até;
break;
}
caso HitDirection .Até:
{
este .hit_dir = HitDirection .right;
break;
}
caso HitDirection .right:
{
este .hit_dir = HitDirection .down;
break;
}
caso HitDirection .down:
{
este .hit_dir = HitDirection .Left;
break;
}
caso HitDirection .Left:
{
este .hit_dir = HitDirection .none;
break;
}
}
}
Código Bloco 64 - função usada para mudar a direção hit para o AI
A função é bastante simples. Ele muda a direção de
o hit com base no padrão que foi pré-definida
24
.
A próxima seção irá cobrir as funções e eventos de interface de usuário.
24
Isso é muito básico, e foi implementado para simplificar. Para um melhor desempenho AI
você pode querer considerar a implementação de um algoritmo de recuo para fazer a melhor jogada
com base em dados históricos.

página 262
Unity 3D - Jogo de Programação Intro
248
Jogo User Interface
As seguintes variáveis são utilizadas para referenciar os elementos de interface do usuário em
o jogo. As variáveis que começam com butXXX estão representando o mas-
toneladas definidos na interface do usuário que o usuário pode interagir com. as variáveis
começando com lblXXX estão fazendo referência rótulos na interface do usuário, as variáveis
iniciar-
ing com imgXXX estão fazendo referência imagens na interface do usuário. a variável
canvasScoreBoard é do tipo da lona e é usado para fazer referência a pontuação
bordo no jogo. Vamos também olhar para estes em mais detalhe na próxima
seção.
 butAircraftCarrier
 butBattleship
 butSubmarine
 butDestroyer
 butPatrolBoat
 butUIReset
 butExit
 butHorizontal
 butVertical
 canvasScoreBoard
 lblPlayerScore
 lblAIScore
 imgYouWin
 imgYouLose
As figuras a seguir ilustram os conceitos de interface do usuário:
Figura 81 - Interface de Usuário - Jogador colocação peça do jogo
Na Figura 81 você vai notar a posição dos botões primários
apresentado ao jogador no início do jogo. Os jogadores é espectáculos
cinco botões para cada peça de jogo que necessita de ser colocado sobre o jogo

página 263
Vahé Karamian
249
borda. Uma vez que o jogador escolhe um navio particular, a interface do usuário irá acionar o
as funções necessárias que fornecem o tamanho da peça de jogo, bem como
o ID relacionado com ele. Os detalhes desta matéria é abordada no seguinte
Seções.
O botão no canto superior esquerdo da tela é usado para a ori-
entação do navio que vai ser lugares no conselho, eo
botão no canto superior direito é o botão de saída. Esta é apenas visível no
implementações não-web. Em outras palavras, você precisa encontrar uma maneira para sair da AP-
plication em um computador ou um dispositivo móvel, este botão vai cuidar
isso para você!
Figura 82 - User Interface O Jogo
Figura 82 O jogador coloca todas as peças do jogo, a interface do usuário
do jogo muda para refletir de forma adequada. Todos os elementos da interface associa-
ciado a colocação de peças do jogo são substituídos com os elementos de interface do usuário
associada ao quadro de pontuação e a capacidade de reiniciar o jogo e
ou sair do jogo. Isto é ilustrado i n Figura 82 . Na próxima seção,
vão discutir os detalhes das funções e os elementos de tempo de design de
GUI.
Eventos do botão para colocar Partes do jogo
Existem duas funções de suporte que são utilizadas no início de
o jogo para permitir que o jogador para colocar seus / suas peças do jogo. Estes dois
função são:

página 264
Unity 3D - Jogo de Programação Intro
250
 butCreateBattleShip (tamanho)
 butCreateBattleShipSetID (shipID)
A primeira função define o tamanho da peça do jogo selecionado, eo
segunda função define o ID. A variável tamanho é usado pelos Check
PlayerBoard () função para determinar os limites de colocação das
parte do jogo, e a variável de ID é usado pelo CheckWhichShip-
WasPlaced () função para criar uma instância do pré-fabricada apropriada.
#region eventos de botão PARA COLOCAÇÃO navios de batalha
public void butCreateBattleShip ( int size)
{
//this.PLACE_BLOCK = this.PLACE_BLOCK!;
este .blockSize = size;
}
public void butCreateBattleShipSetID ( int shipID)
{
este .currentShipID = shipID;
}
#endregion
Código Bloco 65 - Função de lidar com parte UI de colocação navio pelo jogador

página 265
Vahé Karamian
251
Figura 83 - Funções Ref. por Mas-
toneladas
A fim de que o conceito de
trabalho, você precisa configurar o en-
biente de um modo específico em
o designer. Quando você está set-
ting-se os componentes de botão
para cada parte do jogo, você vai
precisa também incluem os dois pa-
tros valores que são, em seguida,
usado no código para corretamente
trabalhar na lógica.
A Figura 83, demonstra o
configuração de tempo de design do botão
objeto definido sob a lona.
Note, que, no evento de clique,
anexamos os dois função
ções
25
que precisam de ser disparado.
Cada função tem um único
valor, um para o tamanho e o
outro para o ID.
Seguindo este conceito, você vai ter cada botão disparar ambos
estas funções no evento de clique, e para cada botão os valores para
os parâmetros vão ser diferentes.
Tipo de navio
Tamanho
Identidade
Porta-aviões
5
1
Battleship
4
2
Submarino
3
3
Destruidor
3
4
Barco de patrulha
2
5
Em seguida, devemos olhar para a função de reinício.
25
Desde a escrita deste livro, Unidade só suporta função de valor único são necessários
eventos. Portanto, precisamos configurar-lo desta forma passar vários parâmetros.

página 266
Unity 3D - Jogo de Programação Intro
252
Botão de eventos para Restart
O botão de reinicialização é usado para limpar o jogo e reiniciar todo o
variáveis para seus valores padrão. Isso dá ao jogador a reposição abilityto
o jogo a qualquer momento durante o jogo. Aqui está a lista de códigos de
a função de reposição.
public void butRestart ()
{
GameObject [] playerBoardGO = GameObject .FindGameObjectsWithTag ( "board" );
foreach ( var ir em playerBoardGO)
{
Destroy (ir);
}
GameObject [] enemyBoardGO = GameObject .FindGameOb-
jectsWithTag ( "boardAttack" );
foreach ( var ir em enemyBoardGO)
{
Destroy (ir);
}
GameObject [] enemyPrefabPH = GameObject .FindGameObjectsWithTag ( "eno-
myPrefabPH " );
foreach ( var ir em enemyPrefabPH)
{
Destroy (ir);
}
GameObject [] = shipModels GameObject .FindGameObjectsWithTag ( "shipModel" );
foreach ( var ir em shipModels)
{
Destroy (ir);
}
esta .ResetGUIButtons ();
Começar();
}
Código Bloco 66 - Repor lista de funções
Nesta função, você vai notar que o primeiro loop for é a iteração
por meio de unidades de tabuleiro do jogador e destruí-los um por um. este
processo acontece para todo o outro jogo Objectos presente no 3D
mundo. Assim que o jogo objetos foram destruídos, o ResetGUIBut-
toneladas () função é chamada para repor os elementos GUI.
private void ResetGUIButtons ()
{
este .butAircraftCarrier.gameObject.SetActive ( verdadeiro );

página 267
Vahé Karamian
253
este .butBattleship.gameObject.SetActive ( verdadeiro );
este .butSubmarine.gameObject.SetActive ( verdadeiro );
este .butDestroyer.gameObject.SetActive ( verdadeiro );
este .butPatrolBoat.gameObject.SetActive ( verdadeiro );
este .lblPlayerScore.text = cadeia .format ( "00" );
este .lblAIScore.text = cadeia .format ( "00" );
}
Código Bloco 67 - Função Repor GUI
A função GUI Redefinir garante que os elementos da interface padrão
são visíveis e também redefine os rótulos de pontuação.
No Capítulo 6 - Criando Battleship , discutimos os requisitos
e as especificações do jogo chamado Batalha do navio. Deu algum histórico
fundo no jogo, introduziu o jogo, e apresentou plano
para a implementação. Isto foi seguido de identificação dos objectos de jogo
que seria necessário para o nosso jogo, e mais importante o jogo fluir e
a lógica do jogo necessário para alcançar os nossos objectivos.
No Capítulo 7 - se aprofundar no código, nós olhamos para os scripts que
foram criados para fazer todas as peças em nosso trabalho jogo com um um-
de outros. Começamos por olhar para o BoardUIVer1.cs script que é
responsável pela gestão do estado do conselho unidade individual em
o jogo de tabuleiro. Em seguida, olhou para a implementação de BoardVer1.cs
script que lida com tudo no jogo.
Agora você está pronto para criar alguns jogos divertidos!

página 268

página 269
Vahé Karamian
255
Anexo 1 - Tabela de Figuras
Índice de figuras
Figura 1 - loop diagram.............................................................................................9
Figura 2 - Diagrama de loop foreach ............................................ ....................................... 10
Figura 3 - enquanto diagrama de circuito ............................................ ........................................... 11
Figura 4 - do-while diagrama de circuito .......................................... ....................................... 11
Figura 5-Car Object......................................................................................................18
Figura 6-Avião Composite objeto ............................................ ................................ 23
Figura Exemplo 7-Inheritance ............................................. ......................................... 25
Figura 8-Unidade 5 Editor ............................................ .................................................. ..35
Figura 9-Cube Primitive ............................................. .................................................. 38
Figura 10 Inspector Janela ............................................. ........................................... 40
Figura 11-Transform Tools ............................................. .............................................. 41
Figura 12-Posição ........................................................................................................41
Figura 13-Rotation........................................................................................................41
Figura 14-Scale.............................................................................................................41
Figura 15-New Material nomes CH1EX1MAT ........................................... ................. 42
Figura 16 Aplicando o material CH1EX1MAT ao cubo GameObject .................. 44
Figura 17-CUBE2 posição, rotação, escala ......................................... .......................... 46
Figura 18-Script Anexado ao jogo de objetos .......................................... ......................... 49
Figura 19 - Tipos de propriedade, referência e valor ......................................... ............... 53
Figura 20 - Propriedades de classe Car ............................................ ....................................... 54
Figura 21 - NavMesh Componentes ............................................. .................................. 57
Figura 22 - Conceito Prefab ............................................. .............................................. 59
Figura 23 - Simples 50x50 Terrain ............................................ ..................................... 67
Figura 24 - snap shot de Terrain Ferramenta .......................................... ................................ 68
Figura 25 - Terreno Projeto ............................................. .............................................. 68
Figura 26 - Terreno com textura aplicada ........................................... ............................ 69
Figura 27 - Busca e recolher objetos do jogo .......................................... ....................... 70
Figura 28 - Cube Prefab com Cube Collider .......................................... ...................... 75
Figura 29 - Inspector janela mostrando Box Collider .......................................... ........ 76
Figura 30 - corpo rígido Congelar rotação ............................................ ............................ 79
Figura 31 - Configuração da câmara Terceira Pessoa ........................................... .............................
80
......................................... Collider Interação após IsTrigger está ativado - Figura 32 ..81
Figura 33 - saída do console para detecção de colisão .......................................... .............. 82
Figura 34 - Drop-Off Plataforma ........................................... ........................................... 85
Figura 35 - Drop Off Zona em ação .......................................... ................................... 88
Figura 36 - Representação visual de uma pilha .......................................... ..................... 89
Figura 37 - Console janela mostrando Pilha Ouput após a ordem de sucesso ................ 95
Figura 38 - apenas um conceito para o Nível 2 ......................................... ................................. 96
Figura 39 - Nível 2 Projeto ............................................ ............................................... 97
Figura 40 - Modelo 3D Quarto ............................................ ............................................. 98
Figura 41 - Modelo 3D na cena Unidade .......................................... ................................. 98
Figura 42 - Hierarquia de quarto ........................................... .................................... 99
Figura 43 - Projeto de amostra de unidades de armazenamento e
colecionador ........................................ 112

página 270
Unity 3D - Jogo de Programação Intro
256
Figura 44 - Interface de usuário Amostra 1 ........................................... ................................ 131
Figura 45 - Interface de usuário Amostra 2 ........................................... ................................ 132
Figura 46 - Rect da barra de ferramentas Ferramenta
Botões ........................................... ............................ 134
Figura 47 - Rect Transformar componentes ............................................ ......................... 135
Figura 48 - Pivot interface ............................................. ............................................. 135
Figura 49 - Anchor UI Elements ............................................ ..................................... 136
Figura 50 - Pré-selecionar Anchor componentes ............................................ ............................ 137
Figura 51 - Canvas com painel anexada ........................................... .......................... 143
Figura 52 - Painel de UI e texto Elemento .......................................... ............................. 145
Figura 53 - Collectables UI Implementado ............................................ ....................... 146
Figura 54 - UI adicional para Matching ........................................... ........................... 147
Figura 55 - Elementos adicionais de interface do usuário para o Nível
1 ......................................... ................ 148
Figura 56 - Botão OnClick Evento ............................................ .................................. 149
Figura 57 - Nível 2 Conceito Nível ........................................... ................................... 154
Figura 58 - Nível 3 UI Conceito ........................................... ....................................... 160
Figura 59 - Outra amostra UI ............................................ ....................................... 175
Figura 60 - Background Painel de Estado ............................................ .............................. 177
Figura 61 - Fundo do painel Mensagem ............................................ .......................... 177
Figura 62 - Fundo do painel Inimigo ............................................ ............................ 177
Figura 63 - Painel de texturas aplicadas ao nível 3 ......................................... .................. 178
Figura 64 - Nível 3 UI Enhancement ........................................... ............................... 179
Figura 65 - lona World Space Propriedades ........................................... ..................... 180
Figura 66 - Conceito UI para Bar Saúde .......................................... .............................. 182
Figura 67 - Space World Canvas Hierarquia ........................................... ..................... 182
Figura 68-Grid Amostra layout ............................................ ....................................... 185
Figura 69-Unidade Base Board ............................................ ............................................. 187
Figura 70-Board Unit com textura e Elementos UI Aplicada .................................... 188
Figura 71-A Board...................................................................................................191
A Figura 72 mostra detalhes por Unidade Conselho .......................................... ....................... 192
Figura 73 - Estrutura BoardUnitPlayer ............................................. ........................... 196
Figura 74 - CubeWreck Prefab ............................................. ....................................... 197
Figura 75 - Jogo de Fluxo de Alto Nível ........................................... ................................. 199
Figura 76 - Jogador Navio Placement Diagrama de Fluxo .......................................... ............ 200
Figura 77 - AI Navio Placement Diagrama de Fluxo .......................................... ................ 201
Figura 78 - O Jogo Logic ............................................ .......................................... 202
Figura 79 - Jogo GUI Conceito ............................................ ...................................... 204
Figura 80 - Jogo GUI Score exibição ........................................... .............................. 205
Figura 81 - Interface de Usuário - Jogador colocação peça do jogo ........................................ ..248
Figura 82 - User Interface O Jogo ........................................... .............................. 249
Figura 83 - Funções Ref. por botões ................................................ ........................ 251

página 271
Vahé Karamian
257
Apêndice 2 - Tabela bloco de código
Tabela bloco de código
Código de bloco tipos 1-variáveis de atribuição e de dados ......................................... ............... 5
Código Bloco 2-se ... exemplo de estrutura de outra ......................................... ............................ 5
Código Bloco 3 - declaração if..else Nested ........................................ ................................ 6
Código Bloco 4-switch exemplo estrutura declaração .......................................... ............... 7
Código de bloco amostras estrutura 5 de circuito ........................................... ................................ 12
Código Bloco 6-exemplo de um método .......................................... .................................... 13
Código Bloco 7 - parâmetro passe Método por referência ......................................... .......... 14
Código Bloco programa de 8 simples calculadora de
demonstração .......................................... .................. 16
Código Bloco 9 - Class Car Amostra ........................................... ...................................... 19
Código Bloco 10 - classe Car usando propriedades .......................................... ........................ 21
Código Bloco 11 - Estrutura de Dados MyStack ........................................... .......................... 27
Código Bloco 12 - Código de exemplo Generics ........................................... ............................ 28
Código Bloco 13 - Simples manipulador de eventos Exemplo .......................................... ...............
32
Código Bloco 14 - Class carro com manipulador de eventos ......................................... ....................
34
Código Bloco 15 - SerializeField para Inspector Janela .......................................... ....... 54
Código Bloco 16 - MyCollectable.cs listando .......................................... .......................... 77
Código Bloco 17 - PlayerInput () versão inicial ......................................... ...................... 79
Código Bloco 18 - MyCollectable.cs ver 2 ......................................... ............................. 82
Código Bloco 19 - MyCollectableData.cs ........................................... ............................. 83
Código Bloco 20 - PlayerInput.cs Ver. 2 ................................................. ......................... 84
Código Bloco 21 - PlayerInput.cs Ver. 3 ................................................. ......................... 88
Código Bloco 22 - Estrutura de dados Pilha ........................................... ............................... 90
Código Bloco 23 - PlayerInput.cs Ver. 4 ................................................. ......................... 94
Código Bloco 24 - Código de Seleção de quarto Listing .......................................... ................ 100
Código Bloco 25 - Porta de Correr Listagem de código .......................................... ..................... 102
Código Bloco 26 - RoomSelection script de atualização para incluir
temporizador .............................. 105
Código Bloco 27 - PlayerInput.cs Atualização para incluir Temporizador Estado .........................
107
Código Bloco 28 - atualização SlidingDoor.cs Script para a função Temporizador .............................
108
Código Bloco 29 - Quarto Visitou além de roteiro SlidingDorr.cs ............................... 109
Código Block 30 - Adição de roteiro PlayerInput.cs para lidar com quartos visitou ............... 110
Código Bloco 31 - MyStorage.cs ......................................... versão inicial ................... 114
Código Bloco 32 - MyCollector.cs versão 1 ......................................... ........................ 116
Código Bloco 33 - MyResource.cs versão 1 ......................................... ........................ 117
Código Bloco 34 - MyEnemy.cs versão 1 ......................................... ........................... 121
Código Bloco 35 - PlayerInput.cs com função ataque inimigo .................................... 126
Código Bloco 36 - MyEnemy.cs com função de Ataque ........................................ ......... 129
Código Bloco 37 - Nível 1 Variáveis de lona Jogo ......................................... ............ 148
Código Bloco 38 - Botão dispara para o Nível 1 ......................................... ...................... 149
Código Bloco 39 - Nível 2 Timer e Objective ....................................... código UI ...... 157
Código Block 40 - função Revista RoomVisited () para o Nível 2 ................................... 159
Código Bloco 41 - Listagem MyStorage.cs para UI design ....................................... ......... 163
Código Bloco 42 - Listagem MyCollector.cs para UI design ....................................... ...... 165
Código Bloco 43 - Listagem MyResource.cs para UI design ....................................... ...... 166

página 272
Unity 3D - Jogo de Programação Intro
258
Código Bloco 44-BoardUIVer1 definição de classe ........................................... ................ 189
Código Bloco 45 Criando o dinamicamente Conselho .......................................... .............. 190
Código Bloco 46 Destaque Lines para Mouse Position e ray casting ...................... 195
Código Bloco 47 - Anúncios para BoardUIVer1.cs ......................................... ..................... 209
Código Bloco 48 - Variáveis BoardVer1 ............................................ ............................ 214
Código Bloco 49 - Awake (função) na BoardVer1 ....................................... classe ....... 218
função Start () in BoardVer1 ....................................... classe - Código Bloco 50 ........... 220
Código Bloco 51 - Código de Construção do Conselho de Administração do
jogador ........................................ ..221
Código Bloco 52 - Código de Enemy Board Construção ......................................... ...... 222
Código Bloco 53 - função Update () definida na classe BoardVer1 ................................. 225
Código Bloco 54 - CheckPlayerBoard () função Definição ......................................... 229
Código Bloco 55 - variáveis temporário utilizado pelo CheckPlayerBoard () .......................... 230
Código Bloco 56 - Determinar que objeto temos atingido por vazamento ray ........................ 232
Código Bloco 57 - Visualmente colocando a peça selecionada para o tabuleiro de jogo .................
236
Código Bloco 58 - Função de AI para colocar peças do jogo ....................................... ...... 236
Código Bloco 59 - Função responsável pela colocação peça do jogo AI ........................ 238
Código Block 60 - CheckAttackBoard função de listagem ........................................... ....... 243
Código Bloco 61 - função de variáveis utilizadas por CheckAttackBoard () ............................. 244
Código Bloco 62 - Registrando um êxito ou um fracasso pelo jogador ..................................... .....
245
Código Bloco 63 - Alteração das voltas após a seleção do jogador ......................................... ..246
Código Bloco 64 - função usada para mudar a direção hit para o AI ...................... 247
Bloco de código 65 - Função de lidar com parte UI de colocação navio pelo jogador ............. 250
Código Bloco 66 - Lista função Reset ........................................... ............................. 252
Código Bloco 67 - GUI Função Repor ........................................... .............................. 253

página 273
259

página 274

Potrebbero piacerti anche