Programando com Scripts Prof. Fellipe Aleixo (fellipe.aleixo@ifrn.edu.br)
Parte 1 Básico
Agenda da Parte 1 1. Introdução a utilização de scripts no Unity (definição de comportamento para os objetos) 2. Como usar variáveis 3. Como usar operadores 4. Como usar condicionais 5. Como usar laços de repetição Será presumido o conhecimento prévio de fundamentos de programação orientada a objetos
Scripts A forma de definir comportamentos São anexados aos objetos do jogo e atribuem interatividade aos mesmos Processo básico: 1. Criar um script 2. Anexar a um ou mais objetos do jogo 3. Definir quaisquer propriedades do script com valores ou com referências a outros objetos do jogo
Criando Scripts Importante guarda-los em uma pasta específica Clicando com o botão direito do mouse sobre essa pasta, selecione Create > C# Script Dando um nome ao mesmo Opções de linguagem: Nativas C# e UnityScript (baseada em JavaScript) Extensões possibilidade de utilizar outras linguagens.net compilando para uma DLL compatível
Criando Scripts Ao clicar no script na visão de projeto, na visão do inspetor é exibido o conteúdo do mesmo Clicando duas vezes sobre o script, ele é aberto para edição Visual Studio ou MonoDevelop
Criando Scripts
Anexando um Script a um Objeto Na visão de projeto clique sobre o script e segurando, arraste-o para o objeto desejado Um script pode ser arrastado até um objeto na: (i) visão de hierarquia, (ii) visão de cena e (iii) visão do inspetor O script torna-se um componente do objeto
Anexando um Script a um Objeto
Estrutura de um Script Básico Seção de Using define as bibliotecas que serão utilizadas na construção do script using UnityEngine; using System.Collections; Seção de declaração de classe define o nome da classe representando o script e sua hierarquia public class HelloWorldScript : MonoBehaviour { }
Estrutura de um Script Básico Conteúdo da classe define atributos e métodos { // Método utilizado para a inicialização void Start () { } } // Método executado uma vez por frame do jogo void Update () { } Qualquer saída gerada pelo jogo é exibida na janela de console Window > Console
Variáveis/Atributos Em um script Unity, uma variável pode conter: Tipos primitivos (da linguagem de programação) Objetos do jogo Outros scripts Definição de variáveis: <variable type> <name>; Exemplo: int num1;
Variáveis/Atributos Tipos de escopo: de classe e de método/bloco Visibilidade de atributos (escopo de classe): public e private Modificadores de acessibilidade
Operadores Categoria Operadores Aritméticos + ; - ; * ; / e % Atribuição = ; += ; -= ; *= ; /= ; ++ e -- Igualdade == ; > ; < ; >= ; <= e!= Lógicos && (and) ; (or) e! (not)
Estruturas de Controle de Fluxo As estruturas de controle de fluxo seguem o padrão da linguagem C Condicionais (mais utilizadas): IF IF ELSE IF ELSE IF Laços de repetição (mais utilizadas): WHILE FOR
Parte 2 Interação dos Objetos
Agenda da Parte 2 1. Como escrever métodos 2. Como capturar a entrada do usuário 3. Como trabalhar com componentes locais 4. Como trabalhar com objetos do jogo
Métodos Pode haver uma confusão com a programação orientada a objetos Num script definimos métodos ou funções? Método: representa uma ação ou propósito único Podem trabalhar juntos para resolver tarefas complexas
Métodos Métodos padronizados: Start: contém o código a ser executado quando a primeira cena tiver início Update: contém o código a ser executado em cada frame no desenrolar da cena Padrão para definição: <return type> <name>(<parameters>) { <Inside the method's block> }
Escrevendo Métodos Primeiro passo, questionar-se sobre: Qual a tarefa específica a ser realizada? Quais informações externas são necessárias? É necessário dar alguma informação como retorno? Exemplo: um dado personagem foi atingido por uma bola de fogo, precisamos escrever um método que remove 5 unidades de vida do personagem int TakeDamageFromFireball() { int playerhealth = 100; return playerhealth 5; }
Usando Métodos Uma vez definido, o método pode ser invocado A partir da mesma classe Ou por outro script que possua uma referência Exemplo: int x = TakeDamageFromFireball(); print ("Player health: " + x);
Entrada do Usuário A entrada do usuário pode acontecer a partir de diferentes meios teclados, controles, toque, etc. Entrada básica: Com o Unity, podemos programar uma ação interativa quando for detectado que uma dada tecla foi pressionada Porém, é mais aconselhado utilizar um sistema de mapeamento genérico de controles São configurados através do Input Manager
Entrada do Usuário Para gerenciar a entrada do usuário, utilizamos Edit > Project Settings > Input Pode ver os vários eixos associados as ações de entrada Exemplo:
Propriedades dos Eixos Propriedade Name Descriptive Name/ Descriptive Negative Name Negative Button/ Positive Button Alt Negative Button/ Alt Positive Button Gravity Dead Sensitivity Descrição Nome do eixo como é referenciado em código Nome que será exibido ao jogador na configuração do jogo o nome negativo é equivalente ao nome do eixo oposto Os botões que passam os valores, negativos e positivos, para o eixo (ex.: setas esquerda e direita) Botões alternativos que passam valores para o eixo (ex.: as teclas A e D para o eixo horizontal) Quão rápido o eixo irá retornar ao zero Entradas menores que esse valor serão ignoradas Quão rapidamente o eixo responde à entrada
Propriedades dos Eixos Propriedade Snap Invert Type Axis Joy Num Descrição Quando marcada, fará que o eixo vá imediatamente a zero quando a direção oposta for pressionada Irá inverter os controles, quando marcada O Tipo da entrada. Se será botões do mouse, teclado, movimento do mouse ou movimento do joystick O Eixo correspondente do dispositivo de entrada (não se aplica aos botões) Qual o joystick será utilizado para a entrada. Por padrão, receberá entrada de todos os joysticks
Programando a Entrada Uma vez que os eixos foram definidos, trabalhar com os mesmos no código é simples Será utilizada a classe Input, mais especificamente o método GetAxis() informando o nome do eixo float hval = Input.GetAxis("Horizontal"); Para o eixo horizontal: Pressionar a seta da esquerda (ou o A) à valor negativo Pressionar a seta da direita (ou o D) à valor positivo
Entrada de uma Tecla Específica Um outro tipo de entrada muito utilizada é de uma tecla específica também utiliza a classe Input Método GetKey() que retorna um booleano indicando quando a mesma foi teclada bool iskeydown = Input.GetKey(KeyCode.K); Cada tecla possui um código específico
Entrada do Mouse Para o mouse, precisam ser considerado dois componentes: (i) movimento e (ii) botões Novamente é utilizada a classe Input e o método GetMouseButtonDown() recebendo um inteiro identificando um botão específico bool isbuttondown; //se o botão esquerdo do mouse foi pressionado isbuttondown = Input.GetMouseButtonDown(0); //se o botão direito do mouse foi pressionado isbuttondown = Input.GetMouseButtonDown(1); //se o botão central do mouse foi pressionado isbuttondown = Input.GetMouseButtonDown(3);
Entrada do Mouse O movimento do mouse se dá nos eixos X e Y, o movimento é capturado com o método GetAxis() float value; //movimento no eixo X value = Input.GetAxis("Mouse X"); //movimento no eixo Y value = Input.GetAxis("Mouse Y"); O movimento do mouse é dado através da medida do deslocamento apenas desde o último frame
Acessando Componentes Locais Como pode ser visto da visão do inspetor, um objetos é composto de vários componentes Componentes tais como: uma transformada, um renderizador, uma luz, uma câmera, etc. Scripts também são componentes É possível interagir com componentes em tempo de execução é necessário recupera-los (no Start) Método GetComponent<Type>()
Acessando Componentes Locais O método GetComponent retorna o primeiro do tipo especificado anexado ao mesmo objeto ao qual o script está associado // Um atributo para armazenar o componente de luz private Light lightcomponent; Start () { lightcomponent = GetComponent<Light> (); lightcomponent.type = LightType.Directional; }
Acessando Componentes Locais Acessando a transformada (como objeto implícito): Alterando esse componente, você move o objeto na cena Métodos Translate(), Rotate() e localscale() //Move o objeto positivamente pelo eixo X //O '0f' significa 0 como um valor de ponto flutuante (real) transform.translate(0.05f, 0f, 0f); //Rotaciona o objeto pelo eixo Z transform.rotate(0f, 0f, 1f); //Aumenta o tamanho do objeto ao dobro em todas as direções transform.localscale = new Vector3(1.5f, 1.5f, 1.5f);
Acessando Outros Objetos Em alguns momentos é útil que um script manipule outros objetos e os seus componentes Para recuperar outros objetos através do editor: Criamos um atributo (público) do tipo GameObject Na visão do inspetor, selecionamos o objeto desejado //Este é o objeto do jogo que se deseja acessar public GameObject objectyouwant;
Acessando Outros Objetos Com o script seja chamando de SomeClassScript, a visão do inspetor seria a seguinte: Também é possível arrastar o objeto até o local indicado
Acessando Outros Objetos Outra forma de acessar outros objetos é utilizar um método de busca Find(), FindWithTag() e FindObjectByType() Buscas (i) por nome, (ii) por rótulo ou (iii) por tipo public class SomeClassScript : MonoBehaviour { //Este é o objeto do jogo que se deseja acessar private GameObject target; // Note que não é necessário ser público ao buscar o objeto } void Start() { target = GameObject.Find("Cube"); }
Acessando Outros Objetos Para a definição de rótulos (tags):
Acessando Outros Objetos Após a definição do rótulo, o objeto é associado:
Acessando Outros Objetos Buscando objetos por rótulo: public class SomeClassScript : MonoBehaviour { //Este é o objeto que se deseja acessar private GameObject target; } void Start() { target = GameObject.FindWithTag("TargetCube"); }
Acessando Outros Objetos Buscando objetos por tipo (script associado): public class SomeClassScript : MonoBehaviour { //Este é o objeto que se deseja acessar private GameObject target; void Start () { target = GameObject.FindObjectByType <CubeScript>(); } }
Modificando Componentes do Objeto Uma vez com uma referência a um outro objeto podemos manipular seus componentes //Acesso ao componente local, não é o que se deseja transform.translate(0f, 0f, 0f); //Acesso ao objeto alvo, é isso que se deseja targetobject.transform.translate(0f, 0f, 0f);
Exercitando 1. Crie um novo projeto ou cena 2. Adicione um cubo, posicionado em (0, 0, -5) 3. Crie uma pasta scripts e crie um novo script CubeControlScript, associado ao cubo 4. Com a seguinte funcionalidade: a) Quando for pressionada as setas esquerda e direita movimentam o cubo ao longo do eixo X b) As setas para cima e para baixo movimentam o cubo no eixo Y (positivamente ou negativamente) c) Quando o mouse se mover ao longo do eixo Y, rotacione o cubo no eixo X. Quando o movimento for no eixo X, rotacione o cubo no eixo Y d) Quando for pressionada a tecla M, aumente a escala do cubo. No caso da tecla N, diminua a escala do cubo
Para mais Informações Confira o tutorial oficial (em português): http://unity3d.com/pt/learn/tutorials/topics/scripting Confira também o manual do Unity (sobre Scripts): http://docs.unity3d.com/manual/scriptingsection.html