Category: omeuprojeto
Parte4 – o meu projeto (aprender)
O terreno, coisas interessantes:
shift anula o elemento do terreno;
manipular o brush size e opacity

instalar o package Terrain tools, através do package manager (ativar no project settings, a hipótese de enable preview packages)e surgem outras opções com o package

teclas de atalho com o uso dos brushes: LINK
outras opções, o path finder: LINK
outras opções, o Terrain Tools Sample Asset Pack (free): LINK
depois de instalar é só importar.. neste caso fiz importar tudo. Surge então a hipótese de usar o paint texture e olhar para a secção das layers

Bump Map (informação 3d da imagem, uma layer a partir de mapa 2d, “light catches a shape”)
Height Map (fazer uso do preto/branco para criar informação acerca da altura dos elementos na imagem)
Normal Map (faz uso dos valores de RGB para indicar a direção da luz em termos de x,y e z de cada pixel)
assim sempre que for necessário aplicar uma layer shape é necessário tratar destas três questões:
standart assets para o Unity: LINK
(filtrar… por environment)
Timeline e a Animation
o processo é o mesmo que em Flash ou noutras ferramentas, trabalhar com keyframes e construir e aplicar movimentos entre esses espaços

Parte3 – o meu projeto (aprender)
Alguns dos temas que devem ser debatidos quando se desenvolve um videojogo:
a experiencia do jogador (precisão, e habilidade) (player experience (precision. skillful);
mecânica principal: pilotar habilmente uma nave espacial e evitar o meio ambiente (core mechanic: skilfully fly spaceship and avoid environmental hazards);
loop principal do jogo: ir de a até b para completar o nível e depois avançar para o próximo nível (core game loop: get from a to b to complete the level then progress to the next level).
Outro assunto é o fluxo do jogo e os ecrãs (game flow and screens) e que se resume ao seguinte cenário:

O tema do jogo (estória de elementos gráficos):
uma geração experimental de uma nave espacial;
tentar escapar de um planeta desconhecido.
(qual o tema central do jogo, o nome do jogo,…)
Questões que normalmente surgem quando se desenvolve um videojogo:
quais são os features (características) que eu devo incluir no meu videojogo?
quando é que se deve começar o desenvolvimento?
quais são as prioridades?
e se eu não tiver tempo?
quando é que eu devo parar?
Metodologia Onion Design (core feature ou mecânicas):

Devem haver respostas para:
qual é característica que é única e mais importante para o jogo?
qual é a característica seguinte mais importante?
qual é a característica seguinte mais importante?
(exemplos: movimento do jogador, colisão com o ambiente (e morrer por causa disso), power ups, ir de a para b e começar um novo nível (level progression), existirem obstáculos que se mexem, existência de pontuação, existência de inimigos, fuel..)
Um alternativa a este modelo será a de começar pelo mais difícil e mais complicado primeiro.
coisas interessantes:
A classe MonoBehaviour:
input +infos: LINK
Input.getKey +infos: LINK
simular o vento no jogo, alterar a física do projeto em X por exemplo

o áudio:
deve estar na camara, porque é o local onde o jogador está
para trabalhar o áudio vai ser necessário:
audio listener (na camara)
audio source (o elemento gráfico que tem/produz o áudio)
audio file
problemas com o áudio:
ou quando se faz o play no Unity estar muted
ou no projeto do ficheiro, ir às preferences…

O AudioSource +infos: LINK
O AudioSource PlayOneShot +infos: LINK
As cenas tem que ser geridas e referidas:

O SceneManager + infos: LINK
Pode também existir a necessidade de colocar uma pausa entre o morrer e o renascer, para isso existe o método Invoke()
Tem como referência o uso de uma String e pode ser lento.. alternativa é usar o Coroutine
O Invoke +infos: LINK
Ainda acerca dos prefabs:
convém que sejam feitos como deve ser e não duplicar/acrescentar simplesmente na barra inicial
remover os box colider de todos e aplicar apenas ao elemento pai do prefab
adicionar depois um box colider e moldar de seguida esse box colider com a ferramenta de edit colider
Particle System:
tem um emissor
e tem as partículas
é adicionado como game object ou através de um componente
um particle system tem módulos que permitem controlar o comportamento
se ficar a pink (cor de rosa) ir ao módulo render->material (é porque não tem ainda material)
na secção shape do módulo podemos alterar o comportamento do cone no radius
e manter os loops ativos
Lighting tab:
(menu window-> rendering-> lighting)
permite manipular os elementos relativos ao lighting
existem:
main directional light (sol)
environment lighting ()
scene lights (do tipo spot lights…)
Lighting +infos: LINK
transformações:
através do código
vector3
starting position (x,y,z)
movement vector (x,y,z)
movement factor (efeito de ping pong), entre 0 e 1
Transform +infos: LINK
movimento constante:
Matemátia, Mathf.Sin +infos: LINK
algum código:
using System;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Colisoes : MonoBehaviour
{
[SerializeField] float tempoLoadNivel = 2.0f;
//audio
[SerializeField] AudioClip suscesso;
[SerializeField] AudioClip insucesso;
AudioSource fonteAudio;
[SerializeField] ParticleSystem suscessoParticulas;
[SerializeField] ParticleSystem insucessoParticulas;
bool estadoEmTransicao = false; //lidar com sons, movimentos..
//cheat code
bool desligarColisoes = false;
void Start() {
fonteAudio = GetComponent<AudioSource>();
fonteAudio.Stop();
}
void Update() {
ResponderATeclasDeDebug();
}
void ResponderATeclasDeDebug(){
if(Input.GetKeyDown(KeyCode.L)){
loadOProximoNivel();
}else if(Input.GetKeyDown(KeyCode.C)){
desligarColisoes = !desligarColisoes;
}
}
void OnCollisionEnter(Collision other)
{
if(estadoEmTransicao == true || desligarColisoes == true)
{
return;
}
switch(other.gameObject.tag)
{
case "Amigo":
Debug.Log("Amigo");
break;
case "Fuel":
Debug.Log("Fuel");
break;
case "Finish":
Debug.Log("Parabens terminaste");
//loadOProximoNivel();
ComecarSequenciaSucesso();
break;
default:
//Debug.Log("huns..");
//ou reLoadNivel();
//ou com pausa
//ou Invoke("reLoadNivel", 1f);
//ou Invoke("ComecaSequenciaCrash", 1f); //criar efeito de pausa com disable teclado
ComecaSequenciaCrash();
break;
}
}
void ComecarSequenciaSucesso()
{
estadoEmTransicao = true;
//audio
fonteAudio.Stop();
fonteAudio.PlayOneShot(suscesso);
//particulas
//ParticleSystem.Play();
suscessoParticulas.Play();
//parar o movimento
GetComponent<Movimento>().enabled = true;
//invoke..
Invoke("loadOProximoNivel", tempoLoadNivel);
}
void ComecaSequenciaCrash()
{
estadoEmTransicao = true;
//som
fonteAudio.Stop();
fonteAudio.PlayOneShot(insucesso);
//particulas
//ParticleSystem.Play()...
insucessoParticulas.Play();
//criar efeito de pausa com disable teclado
GetComponent<Movimento>().enabled = false;
Invoke("reLoadNivel", 1f);
}
void loadOProximoNivel()
{
int cenaCorrenteIndex = SceneManager.GetActiveScene().buildIndex;
int proximaCenaIndex = cenaCorrenteIndex + 1;
if(proximaCenaIndex == SceneManager.sceneCountInBuildSettings){
proximaCenaIndex = 0;
}
SceneManager.LoadScene(proximaCenaIndex);
}
void reLoadNivel()
{
//ou SceneManager.LoadScene(0); // é a primeira ou com o nome
//ou SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex); //voltamos ao inicio
//ou
int cenaCorrenteIndex = SceneManager.GetActiveScene().buildIndex;
SceneManager.LoadScene(cenaCorrenteIndex);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movimento : MonoBehaviour //herança : MonoBehaviour
{
Rigidbody rb;
[SerializeField] float forcaDoTrust = 100.0f;
[SerializeField] float rotacaoDoTrust = 1.0f;
//audio
AudioSource ruidoMotor;
[SerializeField] AudioClip motorFogetao;
//sistema de particulas do motor
[SerializeField] ParticleSystem motorFogetaoParticulas;
[SerializeField] ParticleSystem motorEsquerdaFogetaoParticulas;
[SerializeField] ParticleSystem motorDireitaFogetaoParticulas;
void Start()
{
rb = GetComponent<Rigidbody>();
//audio
ruidoMotor = GetComponent<AudioSource>();
ruidoMotor.Stop();
motorFogetaoParticulas.Stop();
}
void Update()
{
InteratividadeThrust();
InteratividadeRotacao();
}
void InteratividadeThrust()
{
//getKeyDown: só para saber se ele primiu a tecla
//ou (Input.GetKey("up")) ou (Input.GetKey(KeyCode.UpArrow)) //duas escolhas, diferentes signatures
if(Input.GetKey(KeyCode.Space))
{
InicioThrust();
}
else
{
PararThrust();
}
}
void InicioThrust()
{
Debug.Log("Foi pressionado a tecla de SPACE");
//rb.AddRelativeForce(0,1,0); //Vector3 são 3 valores:xyz
//Vector3 permite aceder à direcção e velocidade
rb.AddRelativeForce(Vector3.up * forcaDoTrust * Time.deltaTime);
//equivalente a rb.AddRelativeForce(0,1,0);
//audio
if (!ruidoMotor.isPlaying)
{
//ruidoMotor.Play(); //só para um som
ruidoMotor.PlayOneShot(motorFogetao);
}
//particulas
if (!motorFogetaoParticulas.isPlaying)
{
motorFogetaoParticulas.Play();
}
}
void PararThrust()
{
ruidoMotor.Stop();
motorFogetaoParticulas.Stop();
}
void InteratividadeRotacao()
{
if(Input.GetKey(KeyCode.A))
{
RotacaoEsquerda();
}
else if(Input.GetKey(KeyCode.D))
{
RotacaoDireita();
}
else
{
PararRotacao();
}
}
void RotacaoEsquerda()
{
Debug.Log("Foi pressionado a tecla de A");
RotacaoMetodo(rotacaoDoTrust); //xyz: 0,0,1
if (!motorDireitaFogetaoParticulas.isPlaying)
{
motorDireitaFogetaoParticulas.Play();
}
}
void RotacaoDireita()
{
Debug.Log("Foi pressionado a tecla de D");
//transform.Rotate(-Vector3.forward * rotacaoDoTrust * Time.deltaTime); //xyz: 0,0,1
//ou transform.Rotate(Vector3.back * rotacaoDoTrust * Time.deltaTime); //xyz: 1,0,0
if (!motorEsquerdaFogetaoParticulas.isPlaying)
{
motorEsquerdaFogetaoParticulas.Play();
}
RotacaoMetodo(-rotacaoDoTrust);
}
private void PararRotacao()
{
motorDireitaFogetaoParticulas.Stop();
motorEsquerdaFogetaoParticulas.Stop();
}
void RotacaoMetodo(float rotacaoDesteFrame)
{
//freezar o sistema de rotação não deixar o sistema de fisica tomar posse
rb.freezeRotation = true; //para rodar manualmente
transform.Rotate(Vector3.forward * rotacaoDesteFrame * Time.deltaTime);
rb.freezeRotation = false; // unfreezar para que o sistema de fisica tome conta das ações
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class oscilador : MonoBehaviour
{
Vector3 posicaoDeInicio;
[SerializeField] Vector3 vectorDeMovimento;
//slider
[SerializeField] [Range(0,1)] float vectorDeFactor;
//periodo de tempo
[SerializeField] float periodo = 2f;
void Start()
{
//posição inciial
posicaoDeInicio = transform.position;
Debug.Log(posicaoDeInicio);
}
// Update is called once per frame
void Update()
{
//para medir o tempo..
/*
if(periodo == 0f){
//protecção
return;
}
*/
//por ser float a comparação com == pode comprometer.
if(periodo <= Mathf.Epsilon){
//protecção
return;
}
float ciclos = Time.time / periodo; //vai crescendo com o tempo
//usar Tau, o tal Pi que não é pi e tem em conta o raio
const float tau = Mathf.PI * 2; // o valor constante de 6.283
float rawSenoOnda = Mathf.Sin(ciclos * tau); //andar entre -1 e 1
Debug.Log(rawSenoOnda);
vectorDeFactor = (rawSenoOnda + 1f) / 2f; //calculo que vai de 0 a 1
Vector3 offset = vectorDeMovimento * vectorDeFactor;
transform.position = posicaoDeInicio + offset;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class QuitJogo : MonoBehaviour
{
void Update()
{
if(Input.GetKeyDown(KeyCode.Escape))
{
Debug.Log("Terminou o jogo!!!");
Application.Quit();
}
}
}
Parte2 – o meu projeto (aprender)
o GameDesign deste projeto:
a experiência do jogador ( player experience ) : agilidade
a mecânica do jogo ( core mechanic ) : movimentos, e de evitar obstáculos
o modo continuo do jogo ( game loop ): ir de a para b

coisas interessantes:
a função Time.deltaTime
usar o cinemachine (para termos acesso a diferentes camaras) +infos: LINK
box colider (lidar com as colisões)
rigidbody (vai permitir trabalhar as colisões, lidar com problemas de rotação, através de congelar (freeze nos constrains)
cores +infos: LINK
GameObject.GetComponent + infos: LINK
Time.time +infos: LINK
Tags +infos: LINK
Transform +infos: LINK
algum código:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ColisaoMuros : MonoBehaviour
{
private void OnCollisionEnter(Collision other)
{
//Debug.Log("colisao com um muro");
//Collision, tipo de variavel
//other, quem colidiu comigo
//OnCollisionEnter, quando "entra" na colisão
//se colidirem contigo muda de cor
//GetComponent<MeshRenderer>().material.color = Color.grey;
//2) a colisão só deve acontecer se for com o objecto do jogador
if(other.gameObject.tag == "Player"){
GetComponent<MeshRenderer>().material.color = Color.grey;
//mudar a tag
gameObject.tag = "colisao";
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Mover : MonoBehaviour
{
//para ficar disponivel no inspctor usamos o [SerializeField]
//[SerializeField] float andaX = 0.0f;
//[SerializeField] float andaY = 0.01f;
//[SerializeField] float andaZ = 0.0f;
// Start is called before the first frame update
float andaY = 0.0f;
[SerializeField]float movimentoVelocidade = 6.0f;
void Start()
{
Debug.Log("parte 2 - inicio do jogo");
ImprimirInstrucoes();
//para mover
}
// Update is called once per frame
void Update()
{
MoverOJogador();
}
void ImprimirInstrucoes(){
Debug.Log("Bem vindo ao jogo");
Debug.Log("Move o jogador com as setas ou WSAD");
Debug.Log("Não vás contras os muros..");
}
void MoverOJogador(){
float andaX = Input.GetAxis("Horizontal")*Time.deltaTime*movimentoVelocidade;
float andaZ = Input.GetAxis("Vertical")*Time.deltaTime*movimentoVelocidade;
transform.Translate(andaX, andaY, andaZ);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Pontuacao : MonoBehaviour
{
int pontuacao = 0;
private void OnCollisionEnter(Collision other) {
if(other.gameObject.tag != "colisao"){
pontuacao=pontuacao+1;
Debug.Log("pontos: "+pontuacao);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Queda : MonoBehaviour
{
[SerializeField] float TempoACorrer = 3.0f;
MeshRenderer rendererizacao;
Rigidbody corpoDoMuro;
void Start() {
//esconder a mesh do objeto
//GetComponent<MeshRenderer>().enabled = false;
rendererizacao = GetComponent<MeshRenderer>();
rendererizacao.enabled = false;
corpoDoMuro = GetComponent<Rigidbody>();
corpoDoMuro.useGravity = false;
}
void Update()
{
//Time.time, o tempo que passou desde o inicio de play no jogo
//Debug.Log(Time.time);
if(Time.time > TempoACorrer){
//Debug.Log("ja passaram 3 segundos");
rendererizacao.enabled = true;
corpoDoMuro.useGravity = true;
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Roda : MonoBehaviour
{
[SerializeField] float rodaX = 0.0f;
[SerializeField] float rodaY = 0.50f;
[SerializeField] float rodaZ = 0.0f;
// Update is called once per frame
void Update()
{
transform.Rotate(rodaX,rodaY,rodaZ);
}
}
Parte1 – o meu projeto (aprender)
coisas interessantes:
tecla F para centrar no objeto que queremos,
realizar um reset nas propriedades com o lado direito do rato no inspetor,
alt+botão esquerdo do rato, selecionado o objeto podemos mover em torno dele
coisas usadas e instaladas:
visual studio code
no VSC instalar o Unity Code Snippets
no VSC instalar o C#
Instalação do Unity
Provavelmente por já ter tido uma instalação de uma versão do Unity, e que foi apenas removida pelo uso do Add/Remove programs em ambiente windows, tive problemas em voltar a instalar.
Surgia sempre o erro de “Installation Aborted” instalação ficava a meio caminho.
A solução foi instalar a interface (hub) de instalação do Unity mais antigo deste local (LINK) e de seguida fui instalar o hub da versão mais recente e funcionou!
Vou usar a versão do Unity 2020.2.4f1, parece que é a mais recente e é uma versão final..
+infos(sobre o erro): LINK







