Para entender e acompanhar melhor essa aula, é necessário ter conhecimento sobre variáveis e tipos de dados, e uma noção geral da interface do Unity. Você pode ver aulas e tutoriais sobre esses assuntos nos links a seguir.
O Unity combina o paradigma Orientado a Objetos com o paradigma Orientado a Componente, aonde os objetos das classes que criamos, e das classes que o próprio Unity cria, são componentes que executam quando adicionados a GameObjects, os objetos de cena.
Dessa forma quando montamos um objeto de cena no Unity, com as rotinas que desejamos, montamos um objeto que só possui atributos e métodos por conta de ter dentro de si objetos que o permite fazer as tais ações. A imagem abaixo exemplifica essa questão.
Ela mostra um objeto com cinco componentes, e cada componente é na verdade um objeto de uma classe. A partir disso, por exemplo, o componente CircleCollider2D, é um objeto que permite ao 2DCharacter ter uma área de colisão;, já o código/componente SimpleMove, é um objeto que permite ao 2DCharacter executar um movimento simples controlado pelo usuário, com velocidade configurável. Lembrando, esses componentes rodam como objetos porque foram adicionados a um GameObject, no caso o 2DCharacter .
E perceba, cada componente, quando adicionado a um GameObject, representa uma instância única, com valores distintos entre outras, o que significa que podemos replicar o uso do código SimpleMove para vários GameObjects, todos eles irão rodar um movimento simples, mas cada um terá sua própria velocidade, não interferindo na velocidade dos demais.
Criando um código no Unity, veremos que o próprio Unity gera alguns elementos para nós.
De início, podemos ver que o código gerado é uma classe. Do lado do nome da classe temos ": MonoBehaviour" - esse comando representa que nossa classe herda da classe MonoBehaviour, na próxima aula veremos com mais detalhe o que é uma herança. O que importa no momento é saber que essa herança permite a nossa classe ser usada como componente.
Abaixo, temos dois métodos. Nos códigos do Unity existem uma série de métodos especiais, que vem com a herança da MonoBehaviour. De cara, o código é gerado com dois deles, o Start() e o Update(). Na próxima aula entenderemos melhor sobre métodos, por hora o objetivo é entender POO no Unity.
Seguindo, na aula anterior vimos que uma classe define objetos listando atributos e métodos. No exemplo do movimento, a velocidade é um atributo, pois representa uma informação, e o movimento simples é um método, pois representa uma ação que o objeto irá executar.
Podemos, então, adicionar esse atributo ao código, a velocidade:
Em POO temos algumas regras adicionais para declaração de variáveis/atributos, e métodos também. Do jeito que declaramos o speed, ele está privado, isso significa que o speed não é visível de fora da classe SimpleMove.
Vamos supor que em um jogo de corrida, um carro sofre um ataque de um poder que diminui sua velocidade - com o speed privado, esse poder jamais terá acesso ao a esse atributo.
Se tornarmos o speed público, esse poder terá total acesso a ele, e inclusive poderá modifica-lo de fora da classe. A essa possibilidade de modificar o acesso de um atributo ou método damos o nome de nível de proteção.
Existem três: public, private e protected
public: permite visualização e acesso total ao atributo ou método, e se for atributo, estará visível pelo Inspector;
private: impede todo e qualquer acesso e visualização ao atributo ou método, além de ser invisível no Inspector;
protegido: permite visualização e acesso apenas dentro da herança da classe, ou seja, classes filhas terão acesso ao atributo, mas também será invisível no Inspector;
Além disso, se não colocarmos nada na declaração da variável, como no código acima, o atributo automaticamente será privado.
E se queremos exibir um atributo privado no Inspector podemos usar a diretiva [SerializeField].
A seguir temos alguns exemplos de declarações:
Por último, temos as referências para outros objetos, tanto GameObjects, como componentes. Referência nada mais é que uma variável que guarda um objeto, e, nesse sentido, eles guardam o endereço de memória do objeto.
Quando declaramos uma referência, podemos referenciar tanto objetos de cena, quanto componentes do objeto que contém o código ou componentes de outros objetos.
Para esse tipo de referência, temos três maneiras:
Referenciando um objeto de cena qualquer: criamos uma variável pública ou serializada, que irá gerar um campo no Inspector para linkarmos o objeto desejado;
Referenciando um objeto de cena através de um componente específico: nesse caso a variável pública é declarada usando o tipo do componente desejado, e dai só poderemos linkar objetos que contém o componente desejado;
Referenciando um objeto ou componente exclusivamente por código: usa-se o método GetComponent<>() para pegar o endereço de memória de um componente desejado e guarda-lo na variável;
A seguir encontram-se exemplo dos três casos: