Projeto – Quadro Tetris – Debug

 

Comecei o projeto do Quadro Tetris e me deparei com um problema, como analisar o comportamento do jogo se eu não tenho os leds ainda?

Usar o Serial não daria muito certo, pois visualmente seria inviável, então pensei em uma solução mais bonita, fiz um programa básico em Adobe AIR, que lê a Serial e transcreve os dados para um grid, igual seria com os leds, renderizei em 3D um fundo para ficar mais agradável.

O Arduino faz todo o controle e envia para serial uma array de 121 caracteres, com as 120 informações dos led mais o nulo. Envia 0 se o led deve ficar apagado e 1 até 5 para falar qual cor o led acende.

O programa de ajuda foi feito em Adobe AIR utilizando um ANE chamado as3-arduino-connector , ele permite utilizar a Serial com o mesmo comportamento do Arduino.

Para ajudar no debug, coloquei um display lcd 20×4, um joystick e dois botões, resolvi concentrar todos os comandos no arduino para ficar mais rápido o desenvolvimento, posteriormente faço ele conversar com o celular.

Por enquanto o joystick irá mover as peças para os lados, o botão verde irá rotacionar a peça e o vermelho irá fazer a peça cair mais rápido.

Acho que com isso eu ganho em tempo e ainda fica uma coisa mais bonita de ser ver do que uma saída serial cheio de números.

 

Share

Usando eclipse como IDE para o Arduino

Continuando o projeto do Quadro Tetris, senti a necessidade de ter um ambiente de desenvolvimento melhor do que a IDE do arduino, que é bem limitada em recursos de edição do código.
Busquei por alternativas e achei várias, mas optei pelo eclipse com o plugin para arduino, já que sempre utilizei o eclipse para programar em Java os programas para o Lego Mindstorms NXT e também é a que utilizo para desenvolver para o Adobe AIR com o plugin FDT.
Escolhida a IDE, pesquisei como configurar da melhor forma, então abaixo vou resumir o que dever feito para poder sair desenvolvendo para o arduino com mais conforto.

Caso queira ver o vídeo que usei, CLIQUE AQUI, ele mostra o que baixar e instalar de forma mais didática. Esse vídeo foi feito pelo professor Villao do Patrulha Eureka. Tem também uma apresentação com links – AQUI.

Já vou assumir que você fez download e instalou o software do arduino para o seu sistema. Então resumindo você deve:

Fazer download do eclipse no site do projeto, eu baixei a versão 32 bits para manter a compatibilidade com meus projetos do NXT.

Link para o site

O plugin utiliza o CDT (Para programar em C/C++) no eclipse, dependendo do eclipse já vem junto, verifique em Help / About Eclipse se ele está listado como instalado, se não estiver, temos que instalar, para isso abra o eclipse e vá em Help / Install new software e coloque no primeiro campo o link de acordo com sua versão do Eclipse e clique em Add.

Link para as versões do CDT

Não irá aparecer a lista de itens para instalar até deselecionar o item Group Itens by Category , concorde com tudo e mande instalar.

Agora temos que instalar o Plugin do Arduino, chamado Jantje  - Para isso vá no eclipse e clique em Help / Install new software e coloque no primeiro campo o link  http://www.baeyens.it/eclipse/V2 e clique em Add. Aceite tudo e finalize a instalação.

No Eclipse vá em Window/Preferences/Arduino e coloque os paths para as pastas solicitadas.

Caso der a mensagem que falta o make.exe, faça o download do arquivo em ftp://ftp.equation.com/make/32/make.exe e coloque na pasta c:/Windows. Caso queira mais explicações sobre isso, assista esse Vídeo.

Vamos fazer duas modificações no Eclipse para ficar tudo certinho.

Primeiro vamos fazer o Eclipse salvar o projeto antes de dar o build, vá em Window/Preferences/ General -> Workspace and check Save automatically before build e deixe selecionado.

Segundo, vamos linkar a extensão do Arduino .ino com o C++:

Vá em Window/Preferences -> C/C++ -> file types Pressione new e adicione Pattern: *.ino e Type:  C++Source.

Bom com isso você já tem um ambiente bacana para desenvolver.

Share

Projeto – Quadro Tetris Bluetooth

tetris

 

Faz muito tempo que não posto nada aqui, andei meio preguiçoso esses tempos, mas resolvi deixar a preguiça de lado e comecei a pensar em um projeto para fazer em casa no tempo livre.

Eu queria um projeto que realmente gostasse de desenvolver, então tive a ideia de juntar várias coisas que me interessam no mesmo projeto , como games e Arduíno , aí veio a ideia de fazer o clássico jogo tetris, mas utilizando LEDs em um quadro de pendurar na parede, mas controlado por celular via bluetooth.

O projeto será acomodado em um quadro com uma moldura profunda e um grid 8 x 15 com LEDs RGB endereçáveis individualmente, são leds com chips WS2812b internos, existem também os com chip WS2811, são bem parecidos, mas endereçados de 3 em 3, então para esse projeto não serve, a parte física ficará mais ou menos igual a imagem de destaque do post, dentro estará um microcontrolador Arduíno Mega 2560 e um adaptador bluetooth para comunicação com o celular.

Toda a logica será gerenciada pelo Arduíno, ficando o celular apenas com a função de enviar comandos básicos para o Arduíno, como o de mover a peça ou girar.

Penso em colocar um vidro jateado sobre as baías dos LEDs, para destacar cada quadrado aceso.

Também estou avaliando a possibilidade de colocar sons e um motor de eixo torto para dar aquele efeito de explosão e sacolejo quando destrói uma linha, mas isso serão itens plus, caso dê vontade após o projeto finalizado.

Nos próximos posts pretendendo descrever cada fase do desenvolvimento, assim criando um diário, ou melhor, semanário do progresso do projeto .

Caso tenham alguma ideia bacana para o projeto, coloca ai nos comentários.

Até a próxima.
Share

Unity 3D – Script para rotacionar objeto no próprio eixo

rodar

Quer ver o script funcionando?  CLIQUE AQUI.

Quer o arquivo fonte do Unity?  DOWNLOAD.

Abaixo coloco o código fonte dos dois arquivos:

RotateObject.cs


using UnityEngine;
using System.Collections;
/// Esse é um script que rotaciona um objeto no seu eixo.
/// Funcionalidades
/// Rotaciona o objeto no próprio eixo com possibilidade de smooth
///
/// Autor: Daniel Almeida - daniel@immersive.com.br / daniel@compilamasnaoroda.com.br
/// Data: 03/05/2014
/// Versão 1

public class RotateObject : MonoBehaviour
{
 //valores iniciais de rotação
 public float rotationX = 0.0f;
 public float rotationY = 0.0f;
 //velocidade que terá a rotação
 public float rotationSpeedX = 250.0f;
 public float rotationSpeedY = 120.0f;
 //Se movimento é com suavização
 public bool smooth = true;
 //limita a rotação no eixo X
 public float rotationMinX = -360.0f;
 public float rotationMaxX = 360.0f;
 //limita a rotação no eixo Y
 public float rotationMinY = -20f;
 public float rotationMaxY = 80f;
 //tempo para dar o smooth
 public float smoothTime = 0.3f;
 //variaveis referencia para velocidade
 private float xVelocity = 0.0f;
 private float yVelocity = 0.0f;
 //guarda o valor de x e y enquanto está interpolando
 private float xSmooth = 0.0f;
 private float ySmooth = 0.0f; 

 void Start()
 {
 //inicia já na posição setada
 xSmooth = rotationX;
 ySmooth = rotationY;
 //inicializa nas posicões passadas
 updateRotation();
 }

 void LateUpdate()
 {
 if (Input.GetMouseButton(0)) {
 rotationX -= Input.GetAxis("Mouse X") * rotationSpeedX * Time.deltaTime;
 rotationY -= Input.GetAxis("Mouse Y") * rotationSpeedY * Time.deltaTime;
 } 

 if (smooth)
 {
 //trava a rotação smooth nos limites
 if (rotationMinX != -360 && rotationMaxX != 360)
 {
 rotationX = Mathf.Clamp(rotationX, rotationMinX, rotationMaxX);
 }
 if (rotationMinY != -360 && rotationMaxY != 360)
 {
 rotationY = Mathf.Clamp(rotationY, rotationMinY, rotationMaxY);
 }

 xSmooth = Mathf.SmoothDamp(xSmooth, rotationX, ref xVelocity, smoothTime);
 ySmooth = Mathf.SmoothDamp(ySmooth, rotationY, ref yVelocity, smoothTime);
 }
 updateRotation();
 }

 void updateRotation()
 {
 Quaternion rotation;

 if (smooth)
 {
 rotation = Quaternion.Euler(ySmooth, xSmooth, 0);
 }
 else
 {
 //acerta os angulos para nao passarem de -360 ou 360
 rotationX = ClampAngle(rotationX, rotationMinX, rotationMaxX);
 rotationY = ClampAngle(rotationY, rotationMinY, rotationMaxY);
 rotation = Quaternion.Euler(rotationY, rotationX, 0);
 }
 transform.rotation = rotation;
 }

 float ClampAngle(float angle, float min, float max)
 {
 //acerta os angulos para nao passarem de -360 ou 360
 if (angle < -360)
 angle += 360;
 if (angle > 360)
 angle -= 360;
 //garante que o angulo esta no intervalor setado
 return Mathf.Clamp(angle, min, max);
 }
}

CameraZoom.cs


using UnityEngine;
using System.Collections;
/// Esse é um script que controla o zoom da câmera
/// Funcionalidades
/// Script conta com smooth de movimento, trava do zoom e possibilidade de setar um novo zoom, dentro do zoom minimo e zoom máximo
///
/// Autor: Daniel Almeida - daniel@immersive.com.br / daniel@compilamasnaoroda.com.br
/// Data: 03/05/2014
/// Versão 1

public class CameraZoom : MonoBehaviour
{

//Objeto alvo, ele que será o foco do zoom
public Transform target;
public bool zoomActive = true;
//zoom inicial, minimo , maximo , velocidade e desacelaração do zoom
public float zoom = 10.0f;
public float zoomMin = 5.0f;
public float zoomMax = 20.0f;
public float zoomSpeed = 10.0f;
public float zoomDampening = 5.0f;
//----------------------------------------------------------Variáveis PRIVADAS------------------------------------------
private float currentzoom;
private float desiredzoom;
private float zoomDistance;
void Start()
{
desiredzoom = zoom;
currentzoom = zoom;
updatePosition();
}
void LateUpdate()
{
if (zoomActive)
{
desiredzoom -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * zoomSpeed * Mathf.Abs(desiredzoom);
desiredzoom = Mathf.Clamp(desiredzoom, zoomMin, zoomMax);
currentzoom = Mathf.Lerp(currentzoom, desiredzoom, Time.deltaTime * zoomDampening);
zoom = currentzoom;
}
updatePosition();
}

void updatePosition()
{
transform.position = transform.rotation * new Vector3(0.0f, 0.0f, -zoom) + target.transform.position;
}

float ClampAngle(float angle, float min, float max)
{
//acerta os angulos para nao passarem de -360 ou 360
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
//garante que o angulo esta no intervalor setado
return Mathf.Clamp(angle, min, max);
}
public void setZoom(float _zoom)
{
desiredzoom = Mathf.Clamp(_zoom, zoomMin, zoomMax);
}

//----------------------------------------------------------METODO doLockZoom------------------------------------------
public void doLockZoom(bool zoomLock)
{
zoomActive = !zoomLock;
}
}
Share

Documentário – Sala de Notícias l Do joystick para o trabalho

Vi esse vídeo rodando no facebook, achei bacana e vou colocar aqui.
Fala sobre o mercado de games e como entrar nele, o que achei legal é que os entrevistados são realistas, sem aquele discurso apenas apaixonado que todo desenvolvedor de games tem, “faço games porque amo games”, eles são mais pé no chão sobre o mercado brasileiro, que todo mundo sabe que quase não existe, sem ser indie.

Share

Totem Interativo – Chillibeans

Esse trabalho nós da Immersive em parceria com a XFrame e APEK desenvolvemos um totem interativo 3D para a Chillibeans.

É um totem touchscreen de 70 polegadas na vertical, que foi instalado em uma loja da Chillibeans em São Paulo, nele o cliente consegue navegar e configurar 4 modelos de óculos.

Em cada modelo pode ser trocada a cor das hastes, das lentes, da frente e ainda escolher uma textura para ser aplicada na parte interna da haste, após configurado os óculos, o cliente pode tirar fotos e compartilhar no facebook,  enviar por email e realizar a compra, onde o software gera um pedido e o óculos é montado na hora, de acordo com o que foi estudado no 3D.

O aplicativo é alimentado por um banco de dados do estoque da loja, após a venda faz o update no banco para retirar o que foi vendido.

O cliente pode salvar os óculos que está criando para comparar com outros modelos que ele criou, tudo isso facilmente configurável.

Share

Unite – Vídeos gravados durante os eventos da Unity

Eventos são sempre bons lugares para obter informação e experiências sobre algo,  a Unity3D faz isso muito bem promovendo a UNITE.

UNITE é um evento itinerante que promove palestras sobre Unity3D, desenvolvimento de jogos, cases, enfim todos os assuntos que são relacionados nessa área, acontece em todo o mundo, até no Brasil já teve e para nossa alegria eles filmam todos os eventos e colocam no site, falae, são gente boa né.

A maioria dos vídeos são em inglês.

Clique na imagem acima ou no LINK AQUI para acessar a página principal dos vídeos da UNITE.

Share

Garbage Collector – Gambiarra para forçar a passagem – AS3

Acho que todo mundo que programa em action script 3 sabe como é chato o lance de Garbage Collector, ele passa quando quer e olhe lá.
Você pode remover os Listeners, remover o child mas mesmo assim o objeto fica na memória, se der um trace dentro do movieclip ele ainda aparece, mas temos uma gambiarra que pode ajudar a remover esses lixos da memória, basta utilizar o código abaixo:

try {
new LocalConnection().connect('foo');
new LocalConnection().connect('foo');
} catch (e:*) {}

O que ele faz é tentar um localConnection 2 vezes seguidas, como irá falhar nas 2 vezes, na segunda vez ele chama o garbage collector, não me pergunte porque isso funciona, mas funciona.
Esse código não causa erro nem nada e é muito útil.

Abaixo um exemplo disso:

O código usado foi o seguinte:

import flash.events.Event;
import flash.display.MovieClip;

criarBTN.addEventListener(MouseEvent.CLICK , onCriar);
removerBTN.addEventListener(MouseEvent.CLICK , onRemover);
gambiarraBTN.addEventListener(MouseEvent.CLICK , onGambiarra);

function onCriar(event:Event):void
{
       //cria um moviclip de estrela e passa o campo de saida como argumento apenas para dar saída no texto
	var temp:EstrelaMC = new EstrelaMC();
	temp.saida = saidaTXT;
	areaMC.addChild(temp);
	temp.x = Math.random() * 350;
	temp.y = Math.random() * 100;
	temp = null;
}
function onRemover(event:Event):void
{
        //Remove todas as estrelas
	while (areaMC.numChildren > 0)
	{
		areaMC.removeChildAt(0);
	}
	saidaTXT.text = "Limpando os movieclips \n";
}
function onGambiarra(event:Event):void
{
        //Chama a gambiarra para limpar a memória
	saidaTXT.text = "Gambiarra Executada - Memória Limpa\n";
	try
	{
		new LocalConnection().connect('foo');
		new LocalConnection().connect('foo');
	}
	catch (e: * )
	{
	}
}

Como mostrado, mesmo retirando as estrelas, os movieclips ainda continuam na memória, executando as instruções.
É isso ae, até a próxima, espero que não demore mais um ano.

Share

Sugestão de leitura – Ebook Games Independentes

Perambulando pela internet encontrei esse Ebook grátis que fala sobre o desenvolvimento de jogos independentes, foi feito por David de Oliveira Lemes para o seu mestrado.

Fica a dica para quem se interessa pelo assunto.

Link para DOWNLOAD

SUMÁRIO do Ebook

Introdução: vamos jogar?   14

1 – Criação de jogos digitais   17
1.1 – Características fundamentais dos jogos digitais 19
1.2 – O game e a cena independente 27
1.3 – Rascunhos, argumento e organização de ideias 33
1.4 – Mecânica de jogo, gêneros e narrativa 43
1.5 – Papéis e personagens 49

2 – Planejamento de jogos digitais 53
2.1 –Game design e gerenciamento de projetos 53
2.2 – Criação e design de personagens 63
2.3 – Níveis: progressão, dificuldades e jogabilidade 73
2.4 – Roteiro: formatando o documento de game design 81
2.5 – Linguagem de programação e bibliotecas 87

3 – Desenvolvimento de jogos digitais91
3.1 – Interfaces para games 91
3.2 – Modelagem 3D: objetos, cenários e mundos 99
3.3 – Produção de imagens 2D: texturas e similares 107
3.4 – Ambientação e produção sonora 111
3.5 – Motor de jogo: engine e suas funcionalidades 117
Share

Script de Câmera Orbital – Unity3D

Precisei fazer um app que usa intensamente uma câmera orbital e teria que rodar tanto em tablets quanto em desktop.
Pesquisei um monte, mas os scripts que achei sempre faltava algo, então juntei um coisa aqui uma ali e fiz um script até que bem completo.
Falta ainda fazer a câmera seguir um ponto em movimento e colidir com paredes etc, mas como não iria utilizar isso não fiz agora.
Uma breve descrição do que o script faz, tudo isso controlado por variáveis expostas e funções públicas:

  • Funciona tanto para mobile quanto desktop
  • Troca o ponto algo com ou sem smooth
  • Possibilidade de usar o botão direito ou esquerdo do mouse para rotacionar
  • Possibilidade de usar as setas do teclado para rotacionar
  • Zoom com scroll do mouse ou control + seta , 2 dedos no mobile , com velocidade controlavel
  • Seleção de quais eixos serão usados
  • Rotação com ou sem smooth , com velocidade controlável
  • Trava de ângulo nos eixos , para limitar a rotação
  • Trava de zoom mínimo e zoom máximo

Ainda tem alguns scripts de exemplo para trocar a rotação ou o ponto central, com várias opções para controle.

Contact Point é para centralizar o ponto da câmera aonde clicar no objeto e Seconds to Action funciona no mobile apenas, dedo por x segundos sobre o objeto/botão para ativar a ação.

O código fonte está bem comentado para facilitar.

Abaixo um link com um exemplo rodando e também um projeto com o código fonte.

DOWNLOAD CÓDIGO FONTE

EXEMPLO ONLINE

Vou colocar o código aqui escondido também

using UnityEngine;
using System.Collections;
/// <Descricao>
/// componente 'TransfereTargetCamera'
/// Esse é um script que gira a camera entorno de um ponto
/// Funcionalidades
/// Seleção de eixos para rotacionar
/// Rotação com ou sem desaceleração
/// Trava de angulos para rotação
/// Troca de eixo com ou sem desaceleração
/// Zoom com ou sem desaceleração
/// Metodo para ver se está sendo rotacionada a camera
/// Metodos para alterar os paramentros da camera
/// Versão para web/standalone e mobile
/// 
/// Autor: Daniel Almeida - daniel@immersive.com.br / daniel@compilamasnaoroda.com.br
/// Data: 02/12/2011
/// Versão 1
/// </Descricao>
public class CameraOrbitalMouse : MonoBehaviour
{
    //----------------------------------------------------------Variáveis PÚBLICAS------------------------------------------
    public bool mobile = false;
    //Objeto alvo, em torno dele que a camera girará
    public Transform target;
    //se deve seguir o objeto alvo
    //private bool followsTarget = false;
    //se precisa clicar para rotacionar
    public bool mouseClicked = true;
    //se setas do teclado giram a camera
    public bool arrowMode = false;
    public float arrowVelocityX = 1;
    public float arrowVelocityY = 1;
    public float arrowZoomVelocity = 1;

    //seleciona se rotacionará no angulo x,y, ou em ambos
    public enum MouseButtons : int { LEFT, RIGHT };
    public MouseButtons mouseButton;
    //seleciona se rotacionará no angulo x,y, ou em ambos
    public enum Axis : int { X, Y, XY };
    public Axis eixo;
    //Se movimento é com suavização
    public bool smooth = false;
    //tempo para dar o smooth
    public float smoothTime = 0.3f;
    //valores iniciais de rotação
    public float rotationX = 0.0f;
    public float rotationY = 0.0f;
    //limita a rotação no eixo X
    public float rotationMinX = -360.0f;
    public float rotationMaxX = 360.0f;
    //limita a rotação no eixo Y
    public float rotationMinY = -20f;
    public float rotationMaxY = 80f;
    //velocidade que terá a rotação
    public float rotationSpeedX = 250.0f;
    public float rotationSpeedY = 120.0f;
    //se terá zoom
    public bool zoomActive = true;
    //zoom inicial, minimo , maximo , velocidade e desacelaração do zoom
    public float zoom = 10.0f;
    public float zoomMin = 5.0f;
    public float zoomMax = 20.0f;
    public float zoomSpeed = 10.0f;
    public float zoomDampening = 5.0f;
    //----------------------------------------------------------Variáveis PRIVADAS------------------------------------------
    // private bool travaZoom = true;
    private float currentzoom;
    private float desiredzoom;
    //guarda o valor da posicao final do target
    private Vector3 targetPosition = Vector3.zero;
    //guarda o valor de x e y enquanto está interpolando
    private float xSmooth = 0.0f;
    private float ySmooth = 0.0f;
    //variaveis referencia para velocidade
    private float xVelocity = 0.0f;
    private float yVelocity = 0.0f;
    //smooth do reposicionamento
    private bool targetSmooth = false;
    private Vector3 posSmooth = Vector3.zero;
    private Vector3 posVelocity = Vector3.zero;
    //guarda se a câmera está sendo rotacionada pelo usuário
    private bool movingSmooth = false;
    private bool movingMouse = false;
    private Vector3 positionOld;
    private float lastMouseX;
    private float lastMouseY;
    private bool rotationLock = false;
    private bool travaZoom = true;

    //----------------------deletar tudo 
    public float zoomNearLimit = 5;
    public float zoomFarLimit = 12;
    public float zoomScreenToWorldRatio = 3.0f;
    public float orbitScreenToWorldRatio = 1.0f;
    public float twistScreenToWorldRatio = 5.0f;

    // don't change these
    Vector3 orbitSpeed = Vector3.zero;
    //float twistSpeed = 0;
    float distWeight = 0;
    float zoomDistance;
    // float zoomSpeedMobile = 0;
    float lastf0f1Dist;


    //----------------------------------------------------------EXECUTADO AO INICIAR----------------------------------------
    void Start()
    {
        //verifica se o target foi setado
        if (target == null)
        {
            Debug.LogWarning("O Target da câmera não foi setado, mantendo posição (0,0,0) para o target", gameObject);
        }
        else
        {
            targetPosition = target.position;
        }
        //faz toda válidação dos inputs do zoom
        if (zoomMin < 0)
        {
            Debug.LogWarning("Zoom mínimo menor que zero, alterando para o valor padrão = 0", gameObject);
            zoomMin = 0;
        }
        if (zoomMax < 0 || zoomMax < zoomMin)
        {
            Debug.LogWarning("Zoom máximo não pode ser menor que zero ou menor que o zoom mínimo, alterando para o valor zoomMin + 10", gameObject);
            zoomMax = zoomMin + 10;
        }
        if (zoom < zoomMin || zoom > zoomMax)
        {
            Debug.LogWarning("Zoom fora no range mínimo e máximo, alterando para o valor máximo", gameObject);
            zoom = zoomMax;
        }

        if (zoomDampening < 0)
        {
            Debug.LogWarning("zoomDampening < 0 causa o mesmo efeito do que = 0 , setando o valor para 0", gameObject);
            zoomDampening = 0;
        }

        if (zoomSpeed < 0)
        {
            Debug.LogWarning("zoomSpeed < 0 causa o mesmo efeito do que = 0 , setando o valor para 0", gameObject);
            zoomSpeed = 0;
        }

        //seta o zoom desejado e o zoom corrente        
        desiredzoom = zoom;
        currentzoom = zoom;

        // faz o rigidbody não afetar rotação
        if (rigidbody)
        {
            rigidbody.freezeRotation = true;
        }
        //inicia já na posição setada
        xSmooth = rotationX;
        ySmooth = rotationY;
        //inicializa posicoes
        posSmooth = target.position;
        //inicializa nas posicões passadas
        updatePosition();
        //pega a posicao inicial da camera
        positionOld = transform.position;
        //pega a posicao inicial do mouse
        lastMouseX = Input.GetAxis("Mouse X");
        lastMouseY = Input.GetAxis("Mouse Y");

    }
    //----------------------------------------------------------EXECUTADO UMA VEZ POR FRAME------------------------------------------
    // chamado uma x por frame
    void Update()
    {
       /* if (followsTarget) {
            if (target == null)
            {
                Debug.LogWarning("O Target da câmera não foi setado, mantendo posição (0,0,0) para o target", gameObject);
            }
            else
            {
                targetPosition = target.position;
            }
        }*/
    }
    void LateUpdate()
    {
        //Debug.Log("orbit x " + orbitSpeed.x + "    orbit y " + orbitSpeed.y);
        if (!mobile)
        {
            //verifica qual axe foi escolhido
            if (!mouseClicked || (Input.GetMouseButton(0) && (mouseButton == MouseButtons.LEFT)) || (Input.GetMouseButton(1) && (mouseButton == MouseButtons.RIGHT)) || (arrowMode && !Input.GetKey("left ctrl") && !Input.GetKey("right ctrl") && (Input.GetKey("up") || Input.GetKey("down") || Input.GetKey("left") || Input.GetKey("right"))))
            {

                if (((eixo == Axis.X) || (eixo == Axis.XY)) && !rotationLock)
                {
                    if (Input.GetKey("up") || Input.GetKey("down") || Input.GetKey("left") || Input.GetKey("right"))
                    {
                        
                            rotationX += (Input.GetKey("right") ? 1 : (Input.GetKey("left") ? -1 : 0)) * arrowVelocityX * rotationSpeedX * Time.deltaTime;
                       
                    }

                    else
                    {
                        //faz as contas no eixo x
                        rotationX += Input.GetAxis("Mouse X") * rotationSpeedX * Time.deltaTime;
                    }
                }
                if (((eixo == Axis.Y) || (eixo == Axis.XY)) && !rotationLock)
                {
                    if (Input.GetKey("up") || Input.GetKey("down") || Input.GetKey("left") || Input.GetKey("right"))
                    {                       
                            rotationY += (Input.GetKey("down") ? 1 : (Input.GetKey("up") ? -1 : 0)) * arrowVelocityY * rotationSpeedY * Time.deltaTime;
                      
                    }
                    
                    else
                    {
                        //faz as contas no eixo y
                        rotationY -= Input.GetAxis("Mouse Y") * rotationSpeedY * Time.deltaTime;
                    }
                }

                //verifica se o mouse está sendo movido
                movingMouse = (lastMouseX != Input.GetAxis("Mouse X") || lastMouseY != Input.GetAxis("Mouse Y"));
            }
            else
            {
                movingMouse = false;
            }
           
        }
        else
        {
            if (!rotationLock)
            {
                Touch f0;
                if (Input.touchCount == 1)
                {

                    // finger data
                    f0 = Input.GetTouch(0);

                    // finger delta
                    Vector3 f0Delta = new Vector3(f0.deltaPosition.x, -f0.deltaPosition.y, 0);

                    // if finger moving
                    if (f0.phase == TouchPhase.Moved)
                    {


                        // compute orbit speed
                        orbitSpeed += (f0Delta + f0Delta * distWeight) * Time.deltaTime;

                        rotationX = orbitSpeed.x * rotationSpeedX * 0.2f;
                        rotationY = orbitSpeed.y * rotationSpeedY * 0.3f;
                        movingMouse = true;
                    }
                }
                else if (Input.touchCount == 2)
                {
                    f0 = Input.GetTouch(0);
                    if (f0.phase == TouchPhase.Moved)
                    {
                        Touch touch2 = Input.touches[1];
                        desiredzoom = Vector2.Distance(f0.position, touch2.position);
                        if (travaZoom)
                        {
                            travaZoom = false;
                        }
                        else
                        {
                            zoom += (currentzoom - desiredzoom) * Time.deltaTime;
                        }
                        zoom = Mathf.Clamp(zoom, zoomMin, zoomMax);

                        currentzoom = desiredzoom;
                    }
                }
                else
                {
                    movingMouse = false;
                }
            }
            if (Input.touchCount != 2)
            {
                travaZoom = true;
            }
        }
        if (smooth)
        {
            //trava a rotação smooth nos limites
            if (rotationMinX != -360 && rotationMaxX != 360)
            {
                rotationX = Mathf.Clamp(rotationX, rotationMinX, rotationMaxX);
            }
            if (rotationMinY != -360 && rotationMaxY != 360)
            {
                rotationY = Mathf.Clamp(rotationY, rotationMinY, rotationMaxY);
            }

            xSmooth = Mathf.SmoothDamp(xSmooth, rotationX, ref xVelocity, smoothTime);
            ySmooth = Mathf.SmoothDamp(ySmooth, rotationY, ref yVelocity, smoothTime);
        }
        //se smooth do zoom ativo...
        if (zoomActive && !mobile)
        {

            if (arrowMode && (Input.GetKey("left ctrl") || Input.GetKey("right ctrl")) && (Input.GetKey("up") || Input.GetKey("down")))
            {
              
                    desiredzoom -= (Input.GetKey("down") ? -1 : (Input.GetKey("up") ? 1 : 0)) * Time.deltaTime * arrowZoomVelocity * zoomSpeed * Mathf.Abs(desiredzoom);
               
            }        
            else
            {
                desiredzoom -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * zoomSpeed * Mathf.Abs(desiredzoom);
            }

            //clamp the zoom min/max
            desiredzoom = Mathf.Clamp(desiredzoom, zoomMin, zoomMax);
            // For smoothing of the zoom, lerp zoom
            currentzoom = Mathf.Lerp(currentzoom, desiredzoom, Time.deltaTime * zoomDampening);
            zoom = currentzoom;
        }

        if (targetSmooth)
        {

            posSmooth = Vector3.SmoothDamp(posSmooth, targetPosition, ref posVelocity, smoothTime);
        }

        //pega a ultima posicao do mouse
        lastMouseX = Input.GetAxis("Mouse X");
        lastMouseY = Input.GetAxis("Mouse Y");

        updatePosition();

    }

    void updatePosition()
    {

        Quaternion rotation;
        Vector3 position;

        if (smooth)
        {
            //acerta os angulos para nao passarem de -360 ou 360
            //xSmooth = ClampAngle(xSmooth, rotationMinX, rotationMaxX);
            //ySmooth = ClampAngle(ySmooth, rotationMinY, rotationMaxY);
            //garante que o angulo esta no intervalor setado
            //pega a rotacao
            rotation = Quaternion.Euler(ySmooth, xSmooth, 0);
        }
        else
        {
            //acerta os angulos para nao passarem de -360 ou 360
            rotationX = ClampAngle(rotationX, rotationMinX, rotationMaxX);
            rotationY = ClampAngle(rotationY, rotationMinY, rotationMaxY);
            //garante que o angulo esta no intervalor setado
            //pega a rotacao
            rotation = Quaternion.Euler(rotationY, rotationX, 0);
        }
        //faz a conta da posicao
        if (targetSmooth)
        {
            position = rotation * new Vector3(0.0f, 0.0f, -zoom) + posSmooth;
        }
        else
        {
            position = rotation * new Vector3(0.0f, 0.0f, -zoom) + targetPosition;
        }

        //seta nos valores
        transform.rotation = rotation;
        transform.position = position;

        //se está sendo movida a camera
        movingSmooth = positionOld != transform.position;       

        positionOld = transform.position;
    }

    float ClampAngle(float angle, float min, float max)
    {
        //acerta os angulos para nao passarem de -360 ou 360
        if (angle < -360)
            angle += 360;
        if (angle > 360)
            angle -= 360;
        //garante que o angulo esta no intervalor setado
        return Mathf.Clamp(angle, min, max);
    }
    //----------------------------------------------------------METODO setTarget------------------------------------------
    //Esse método serve para se passar um novo target para a câmera
    //deve ser informado se terá transição de uma posição para outra ou se o corte será seco
    //Parametros : novaPosicao(Vector3, transform ou gameObject)
    //             smoothly (bool)
    public void setTarget(Vector3 novaPosicao, bool smoothly = false)
    {
        targetPosition = novaPosicao;
        targetSmooth = smoothly;
        //se não for para ter suavidade sincroniza o ponto inicial e final, isso previne que se clicar em um objeto que tem o smooth
        //ele partirá do ponto corrente.
        if (!targetSmooth)
        {
            posSmooth = targetPosition;
        }
    }
    //sobrecarga para o metodo setTarget
    public void setTarget(Transform novaPosicao, bool smoothly = false)
    {
        setTarget(novaPosicao.position, smoothly);
    }
    //sobrecarga para o metodo setTarget
    public void setTarget(GameObject novaPosicao, bool smoothly = false)
    {
        setTarget(novaPosicao.transform.position, smoothly);
    }
    //----------------------------------------------------------METODO isMoving------------------------------------------
    //metodo usado para saber se a camera está girando
    //parametro affectedSmooth = true pega se a camera está em movimento (usuário ou smooth movendo)
    //parametro affectedSmooth = false pega se a camera está em movimento (apenas o usuário a movendo)
    public bool isMoving(bool affectedSmooth = false)
    {
        if (affectedSmooth)
        {
            return movingSmooth;
        }
        else
        {
            return movingMouse;
        }

    }
    //----------------------------------------------------------METODO setRotation------------------------------------------
    public void setRotation(float newRotationX, float newRotationY, bool smoothly)
    {
        //pega o valor no range de -360 a 360
        float rotationXNormalizado = rotationX % 360;
        float rotationYNormalizado = rotationY % 360;
        //apara as arestas
        rotationX = ClampAngle(newRotationX, rotationMinX, rotationMaxX);
        rotationY = ClampAngle(newRotationY, rotationMinY, rotationMaxY);
        //pega o valor no range de -360 a 360
        xSmooth = xSmooth % 360;
        ySmooth = ySmooth % 360;

        //clipa a rotação para pegar o caminho mais perto do ponto de destino
        if (rotationX - rotationXNormalizado > 180)
        {
            rotationX -= 360;
        }
        else if (rotationX - rotationXNormalizado < -180)
        {
            rotationX += 360;
        }
        //clipa a rotação para pegar o caminho mais perto do ponto de destino
        if (rotationY - rotationYNormalizado > 180)
        {
            rotationY -= 360;
        }
        else if (rotationY - rotationYNormalizado < -180)
        {
            rotationY += 360;
        }
        //se mudança a seco, iguala a variavel de smooth
        if (!smoothly)
        {
            xSmooth = rotationX;
            ySmooth = rotationY;
        }
    }

    public void setZoom(float _zoom)
    {
        desiredzoom = Mathf.Clamp(_zoom, zoomMin, zoomMax);
    }

    //----------------------------------------------------------METODO setRotationAndLock------------------------------------------
    //faz o mesmo que setrotation mas manda travar a rotação 
    public void setRotationAndLock(float newRotationX, float newRotationY, bool smoothly, bool rotationLock)
    {
        setRotation(newRotationX, newRotationY, smoothly);
        doLockRotation(rotationLock);
    }
    //----------------------------------------------------------METODO doLockRotation------------------------------------------
    //faz o mouse não rotacionar mais a camera
    public void doLockRotation(bool rotationLock)
    {
        this.rotationLock = rotationLock;
    }

    //----------------------------------------------------------METODO doLockZoom------------------------------------------
    //faz o mouse não dar mais zoom na camera
    public void doLockZoom(bool zoomLock)
    {
        zoomActive = !zoomLock;
    }
}

using UnityEngine;
using System.Collections;

/// <Descricao>
/// componente 'TransfereTargetCamera'
/// Este script deve ser usado em conjunto com o script CameraOrbitalMouse.cs,
/// Ele envia uma nova posição para o target e diz se deve ser com transição ou se já troca
/// de lugar na hora.
/// </Descricao>
[AddComponentMenu("Scripts/TransfereTargetCamera")]
public class TransfereTargetCamera : MonoBehaviour
{
    //camera que será afetada
    public Camera cameraTarget;
    public bool smooth = false;
    public enum MouseButtons : int { LEFT, RIGHT };
    public MouseButtons mouseButton;
    public Transform useObjectPosition;
    public Vector3 targetPosition = Vector3.zero;
    public bool contactPoint;
    public float secondsToAction = 2;
    private float contadorTempo = 0;
    private bool contando = false;

    void Start()
    {

    }

    void update()
    {

    }

    void OnMouseOver()
    {
        if ((Input.GetMouseButton(0) && (mouseButton == MouseButtons.LEFT)) || (Input.GetMouseButton(1) && (mouseButton == MouseButtons.RIGHT)))
        {
            if (cameraTarget && !contactPoint && !cameraTarget.GetComponent<CameraOrbitalMouse>().mobile)
            {
                // Debug.DrawLine(collider.con)
                cameraTarget.GetComponent<CameraOrbitalMouse>().setTarget(useObjectPosition != null ? useObjectPosition.position : targetPosition, smooth);
            }
        }
    }

    void Update()
    {
        if (cameraTarget.GetComponent<CameraOrbitalMouse>().mobile)//acoes para mobile
        {
            Touch f0;

            if (Input.touchCount >= 1)
            {

                // finger data
                f0 = Input.GetTouch(0);


                // if finger moving
                if (f0.phase == TouchPhase.Began)
                {
                    contadorTempo = 0;
                    contando = true;
                }
                else if (f0.phase == TouchPhase.Ended || f0.phase == TouchPhase.Canceled || f0.phase == TouchPhase.Moved)
                {
                    contando = false;
                }
            }


            if (contando)
            {
                contadorTempo += Time.deltaTime;

                if (contadorTempo >= secondsToAction)
                {
                    Ray ray = Camera.main.ScreenPointToRay(new Vector3(f0.position.x, f0.position.y, 0)); // Construct a ray from the current mouse coordinates

                    RaycastHit hit;

                    if (Physics.Raycast(ray, out hit))
                    {
                        cameraTarget.GetComponent<CameraOrbitalMouse>().setTarget(hit.point, smooth);
                        Debug.Log("atiraaa", gameObject);
                    }

                    cameraTarget.GetComponent<CameraOrbitalMouse>().setTarget(hit.point, smooth);
                    contando = false;
                    contadorTempo = 0;
                }
            }
        }
        else//acoes para standalone / web
        {

            if (((Input.GetMouseButton(0) && (mouseButton == MouseButtons.LEFT)) || (Input.GetMouseButton(1) && (mouseButton == MouseButtons.RIGHT))) && contactPoint)
            {

                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // Construct a ray from the current mouse coordinates

                RaycastHit hit;

                if (Physics.Raycast(ray, out hit))
                {
                    if (hit.collider.gameObject == gameObject)
                    {
                        cameraTarget.GetComponent<CameraOrbitalMouse>().setTarget(hit.point, smooth);
                    }
                }
            }
        }
    }
}

using UnityEngine;
using System.Collections;

/// <Descricao>
/// componente 'SetaNovaRotacao'
/// </Descricao>
[AddComponentMenu("Scripts/SetaNovaRotacao")]
public class SetaNovaRotacao : MonoBehaviour
{

    //camera que será afetada
    public Camera cameraTarget;
    public float rotationX = 0;
    public float rotationY = 0;
    public bool smooth = false;
    
    void Start()
    {

    }

    void OnMouseDown()
    {
        if (cameraTarget)
        {
            cameraTarget.GetComponent<CameraOrbitalMouse>().setRotation(rotationX, rotationY, smooth );
            
        }
    }   
}

using UnityEngine;
using System.Collections;

/// <Descricao>
/// componente 'SetaNovaRotacao'
/// </Descricao>
[AddComponentMenu("Scripts/SetaNovaRotacao")]
public class SetaNovaRotacaoTrava : MonoBehaviour
{

    //camera que será afetada
    public Camera cameraTarget;
    public float rotationX = 0;
    public float rotationY = 0;
    public bool smooth = false;
    public bool rotationLock = false;
    void Start()
    {

    }

    void OnMouseDown()
    {
        if (cameraTarget)
        {
            cameraTarget.GetComponent<CameraOrbitalMouse>().setRotationAndLock(rotationX, rotationY, smooth , rotationLock);
            
        }
    }
}

Share

Pages:123456