Qual seria a melhor maneira de criar um Map Mundi interativo?
2 participantes
Página 1 de 1
Qual seria a melhor maneira de criar um Map Mundi interativo?
Eu dei uma pesquisada e já vi varias respostas sobre o assunto, mais nada que chegue ao que desejo, como por exemplo utilizando colisores na area dos países, porém seria muito demorado ficar contornando país por país e não sei como fazer para quando o mouse estiver sobre o colisor, apenas aquela parte da imagem mude de cor, no caso a area do colisor, pois estou utilizando uma imagem do mapa por inteiro. Já vi o asset World Map Strategy Kit 2 mas é muito caro para mim.
A unica opção seria montar sprite por sprite de cada país desde o começo? Montando um mapa do zero? Por favor alguem me ajuda, ja procurei por varios tutoriais mas nao acho nenhum, nao quero o script, apenas o que eu poderia utilizar para faze-lo.
Imagem utilizada:
A unica opção seria montar sprite por sprite de cada país desde o começo? Montando um mapa do zero? Por favor alguem me ajuda, ja procurei por varios tutoriais mas nao acho nenhum, nao quero o script, apenas o que eu poderia utilizar para faze-lo.
Imagem utilizada:
Traygus- Iniciante
- PONTOS : 1324
REPUTAÇÃO : 9
Respeito as regras :
Re: Qual seria a melhor maneira de criar um Map Mundi interativo?
O que eu poderia ou qual ferramenta utilizar para fazer o mapa ser interativo?
Traygus- Iniciante
- PONTOS : 1324
REPUTAÇÃO : 9
Respeito as regras :
Re: Qual seria a melhor maneira de criar um Map Mundi interativo?
Primeiro você não vai querer traçar cada país... pesquise por um arquivo .svg com uma projeção equiretangular, é a projeção padrão que a unity usa na esfera 3D que vem por padrão, os svg's normalmente vem já com os paises separados, o que poupa certo tempo, talvez seja preciso traduzir os nomes caso você pegue o mapa em um site gringo.
Com o mapa em mãos, utilize alguma ferramenta 3D pra gerar a mesh, no Blender você pode usar o importador de SVG nativo, uma vez importado ele faz a conversão direta pra objetos do tipo "curva", basta selecionar tudo e exportar como FBX.
Na Unity você importa essa mesh, adiciona um mesh collider para cada país e posiciona o mapa no centro do mundo, preste atenção à posição e escala pois isso vai ser importante mais pra frente.
Em cima da mesh você vai colocar uma nova câmera, utilizando layers você vai limitar a visão da câmera para apenas o mapa importado, você não vai querer que o mapa achatado apareça na câmera principal, cada câmera vê uma coisa.
Crie uma render texture e utilize uma resolução que seja Pot (Power Of Two, 512, 1024, etc) e que tenha a proporção 2:1, similar ao mapa equiretangular. ex: 1024x512;
Atribua a render texture para a câmera que você deixou acima da mesh.
A câmera vê a mesh, renderiza na render texture, fazendo com que seja possível utilizar essa imagem como textura em uma esfera.
Visualmente, a esfera com esse material/textura fica com a projeção correta que encontramos num mapa mundi do tipo globo.
Agora você precisa colocar um mesh collider nessa esfera e com base onde você clica nela, você pega a posição da UV relativa ao toque.
Aqui está um exemplo da Unity sobre como fazer isso:
https://docs.unity3d.com/ScriptReference/Camera.ScreenToWorldPoint.html
https://docs.unity3d.com/ScriptReference/Physics.Raycast.html
https://docs.unity3d.com/ScriptReference/RaycastHit-textureCoord.html
Essa posição precisa ser mapeada sobre o mapa importado, você então dispara um Raycast no mapa, detecta qual mesh (país) ela encontrou e a partir daí você faz o que quiser, muda a cor, acessa o nome, alguma informação que você acrescentou via script, etc.
Se você mudar o material, a câmera que fica sobre a mesh vê isso acontecendo e passa pra textura do globo, visualmente o jogador acha que está clicando e interagindo com o Globo, mas na verdade tudo acontece no mapa 3d importado.
Deixo acima o "how to" e abaixo um vídeo da minha tentativa, pois achei interessante o desafio, como deu um certo trabalho e algumas horas de sono perdidas, se tiver interesse pode me mandar uma mensagem que fechamos um valor legal por esse exemplo, ele inclui a mesh com os países separados, um script de exemplo que faz tudo que falei acima e retorna o nome do país clicado e shaders que fiz especificamente pro projeto, sem isso você teria centenas de materiais caso queira que cada país tenha uma cor única, também é possível combinar com uma textura, como visto abaixo.
Com o mapa em mãos, utilize alguma ferramenta 3D pra gerar a mesh, no Blender você pode usar o importador de SVG nativo, uma vez importado ele faz a conversão direta pra objetos do tipo "curva", basta selecionar tudo e exportar como FBX.
Na Unity você importa essa mesh, adiciona um mesh collider para cada país e posiciona o mapa no centro do mundo, preste atenção à posição e escala pois isso vai ser importante mais pra frente.
Em cima da mesh você vai colocar uma nova câmera, utilizando layers você vai limitar a visão da câmera para apenas o mapa importado, você não vai querer que o mapa achatado apareça na câmera principal, cada câmera vê uma coisa.
Crie uma render texture e utilize uma resolução que seja Pot (Power Of Two, 512, 1024, etc) e que tenha a proporção 2:1, similar ao mapa equiretangular. ex: 1024x512;
Atribua a render texture para a câmera que você deixou acima da mesh.
A câmera vê a mesh, renderiza na render texture, fazendo com que seja possível utilizar essa imagem como textura em uma esfera.
Visualmente, a esfera com esse material/textura fica com a projeção correta que encontramos num mapa mundi do tipo globo.
Agora você precisa colocar um mesh collider nessa esfera e com base onde você clica nela, você pega a posição da UV relativa ao toque.
Aqui está um exemplo da Unity sobre como fazer isso:
https://docs.unity3d.com/ScriptReference/Camera.ScreenToWorldPoint.html
https://docs.unity3d.com/ScriptReference/Physics.Raycast.html
https://docs.unity3d.com/ScriptReference/RaycastHit-textureCoord.html
Essa posição precisa ser mapeada sobre o mapa importado, você então dispara um Raycast no mapa, detecta qual mesh (país) ela encontrou e a partir daí você faz o que quiser, muda a cor, acessa o nome, alguma informação que você acrescentou via script, etc.
Se você mudar o material, a câmera que fica sobre a mesh vê isso acontecendo e passa pra textura do globo, visualmente o jogador acha que está clicando e interagindo com o Globo, mas na verdade tudo acontece no mapa 3d importado.
Deixo acima o "how to" e abaixo um vídeo da minha tentativa, pois achei interessante o desafio, como deu um certo trabalho e algumas horas de sono perdidas, se tiver interesse pode me mandar uma mensagem que fechamos um valor legal por esse exemplo, ele inclui a mesh com os países separados, um script de exemplo que faz tudo que falei acima e retorna o nome do país clicado e shaders que fiz especificamente pro projeto, sem isso você teria centenas de materiais caso queira que cada país tenha uma cor única, também é possível combinar com uma textura, como visto abaixo.
Fagner- Moderador
- PONTOS : 4442
REPUTAÇÃO : 667
Áreas de atuação : Modelagem 3D, Programação.
Respeito as regras :
Re: Qual seria a melhor maneira de criar um Map Mundi interativo?
Amigo muuito obrigado mesmo!! Irei seguir seu tutorial, valeu!
Traygus- Iniciante
- PONTOS : 1324
REPUTAÇÃO : 9
Respeito as regras :
Re: Qual seria a melhor maneira de criar um Map Mundi interativo?
@Fagner Oi amigo, eu consegui ter um progresso muito obrigado, mas surgiu um problema, está desproporcional, eu tenho que clicar fora do globo para pegar os países, voce poderia m visao camera que renderiza e não com o globo. Eu li sobre o RaycastHit .textureCoord mas quando tento aplica-lo a textura retorna Null.
Video do problema:
Video do problema:
Traygus- Iniciante
- PONTOS : 1324
REPUTAÇÃO : 9
Respeito as regras :
Re: Qual seria a melhor maneira de criar um Map Mundi interativo?
Voce poderia me ajudar? Acredito esteja pegando a posição de acordo com a visao da camera que renderiza e não com o globo.
Traygus- Iniciante
- PONTOS : 1324
REPUTAÇÃO : 9
Respeito as regras :
Re: Qual seria a melhor maneira de criar um Map Mundi interativo?
Por enquanto este é o meu script, estou fazendo algo errado?
- Código:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Interactive : MonoBehaviour
{
public Camera cam;
void Start()
{
}
void Update()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Input.GetMouseButtonDown(0))
{
if (Physics.Raycast(ray, out hit,1000))
{
GameObject selectCountry = hit.collider.gameObject;
Debug.Log(selectCountry.name);
Renderer rend = hit.transform.GetComponent<Renderer>();
MeshCollider meshCollider = hit.collider as MeshCollider;
RenderTexture tex = rend.material.mainTexture as RenderTexture;
Debug.Log(tex);
Vector2 pixelUV = hit.textureCoord;
pixelUV.x *= tex.width;
pixelUV.y *= tex.height;
Debug.Log(pixelUV);
}
}
}
}
Traygus- Iniciante
- PONTOS : 1324
REPUTAÇÃO : 9
Respeito as regras :
Re: Qual seria a melhor maneira de criar um Map Mundi interativo?
Andei ocupado jovem por isso estive offline, mas parabéns, tá quase lá.
Olha só, tem dois passos aí que ou você esqueceu ou interpretou diferente.
Primeiro, você faz o raycast na esfera pra pegar a posição da UV que o hit atingiu (Necessita ter um mesh collider, por padrão vem com sphere collider), a UV funciona assim, no canto inferior esquerdo o valor é 0:0, e no superior direito é 1:1.
Supondo que você clicou na esfera e o ponto da UV relacionado com o click é x=0.43 e y = 0.7, essa coordenada entre 0-1 em X e Y precisa ser remapeada no mundo, pra isso você vai usar a posição e escala do seu mapa com países separados.
Como disse antes, o mapa normalmente tem uma proporção 2:1, logo, se você deixar seu mapa com o canto alinhado com a posição 0,0,0 do mundo e as suas dimensões do mapa estiverem com 1 metro de altura por 2 de largura, bastaria pegar o valor vindo da UV e multiplicar apenas o X por 2, já uvx = 0-1 / mapax = 0-2;
então seguindo o exemplo em negrito, x valeria 0.86 e y = 0.7;
Possuindo as coordenadas, você faz um segundo raycast sobre o mapa com essas coordenadas remapeadas.
A sequencia seria essa:
click na esfera>hit para UV>UV para mundo>checa hit no mundo.
Aqui dá pra ver o ponto do clique na esfera e o raycast no mapa:
Olha só, tem dois passos aí que ou você esqueceu ou interpretou diferente.
Primeiro, você faz o raycast na esfera pra pegar a posição da UV que o hit atingiu (Necessita ter um mesh collider, por padrão vem com sphere collider), a UV funciona assim, no canto inferior esquerdo o valor é 0:0, e no superior direito é 1:1.
Supondo que você clicou na esfera e o ponto da UV relacionado com o click é x=0.43 e y = 0.7, essa coordenada entre 0-1 em X e Y precisa ser remapeada no mundo, pra isso você vai usar a posição e escala do seu mapa com países separados.
Como disse antes, o mapa normalmente tem uma proporção 2:1, logo, se você deixar seu mapa com o canto alinhado com a posição 0,0,0 do mundo e as suas dimensões do mapa estiverem com 1 metro de altura por 2 de largura, bastaria pegar o valor vindo da UV e multiplicar apenas o X por 2, já uvx = 0-1 / mapax = 0-2;
então seguindo o exemplo em negrito, x valeria 0.86 e y = 0.7;
Possuindo as coordenadas, você faz um segundo raycast sobre o mapa com essas coordenadas remapeadas.
A sequencia seria essa:
click na esfera>hit para UV>UV para mundo>checa hit no mundo.
Aqui dá pra ver o ponto do clique na esfera e o raycast no mapa:
Fagner- Moderador
- PONTOS : 4442
REPUTAÇÃO : 667
Áreas de atuação : Modelagem 3D, Programação.
Respeito as regras :
Re: Qual seria a melhor maneira de criar um Map Mundi interativo?
Muito obrigado novamente pela explicação!!
Traygus- Iniciante
- PONTOS : 1324
REPUTAÇÃO : 9
Respeito as regras :
Re: Qual seria a melhor maneira de criar um Map Mundi interativo?
Eu consegui realizar até a UV para o mundo, mas não sei qual é o problema, talvez meu mapa seja muito pequeno, eu não sei qual é a dimensão do meu mapa, acho que ele não é 2:1, pois ele está na posição 0,0,0 do mundo e quando multiplico a UVx por 2 o segundo raycast não captura o mapa, fica em posições diferentes em relação ao mapa. Quando clico ele captura e retorna normalmente as coordenadas da UV, aí eu pego essas informações e faço um segundo raycast com a origem nesses pontos.
Eu também fiquei na duvida em relação ao Camera.ScreenToWorldPoint e o Camera.ScreenPointToRay, inicialmente tinha feito com Camera.ScreenPointToRay(Input.mousePosition) e depois tentei fazer com Camera.ScreenToWorldPoint mas nao funcionou, mas acredito que esse não o problema.
Vou mandar um video do que está acontecendo.
- Código:
Vector2 pixelUV = hit.textureCoord; //captura as coordenadas UV da RenderTexture do globo
origin = new Vector3(pixelUV.x, 2, pixelUV.y); //ponto de origem para o Raycast do mapa
Debug.DrawRay(origin, -Vector3.up * 1000, Color.white);
if (Physics.Raycast(origin, -Vector3.up, out RaycastHit hitMap, 1000))
{
Debug.Log(hitMap.collider.gameObject.name);
}
Eu também fiquei na duvida em relação ao Camera.ScreenToWorldPoint e o Camera.ScreenPointToRay, inicialmente tinha feito com Camera.ScreenPointToRay(Input.mousePosition) e depois tentei fazer com Camera.ScreenToWorldPoint mas nao funcionou, mas acredito que esse não o problema.
Vou mandar um video do que está acontecendo.
Traygus- Iniciante
- PONTOS : 1324
REPUTAÇÃO : 9
Respeito as regras :
Re: Qual seria a melhor maneira de criar um Map Mundi interativo?
Sem mexer no projeto não dá pra ter certeza, mas vai clicando na esfera e vendo se a direção que o raycast está indo está correta, talvez seja preciso inverter o X ou o Y vindo da UV.
O correto é usar o ScreenPointToRay mesmo, passando a posição do mouse.
Seu origin não deveria multiplicar o x por 2? está passando o valor direto da UV, então o raio vai ficar no maximo na posição (x=1, y=0, z=1)
O correto é usar o ScreenPointToRay mesmo, passando a posição do mouse.
Seu origin não deveria multiplicar o x por 2? está passando o valor direto da UV, então o raio vai ficar no maximo na posição (x=1, y=0, z=1)
Fagner- Moderador
- PONTOS : 4442
REPUTAÇÃO : 667
Áreas de atuação : Modelagem 3D, Programação.
Respeito as regras :
Re: Qual seria a melhor maneira de criar um Map Mundi interativo?
Olá Fagner, estou tentando acertar esse problema do Raycast, tentei multiplicado o x da UV mas não funcionou, como eu tinha dito meu mapa é pequeno, irei tentar mas uma solução, que vai ser aumentar a escala do mapa no blender e então aplica-la. E depois exportar novamente para unity colocar os mesh collider, ajustar a camera e tentar multiplicar a UVx por 2, e também precisei inverter o UVy, obrigado. Daqui a pouco vou te mandar o projeto caso queira dar uma olhada e se quiser tentar descobrir o que há de errado com meu mapa . Como eu disse acredito que seja por que ele é muito pequeno.
Comparação de Tamanhos:
Comparação de Tamanhos:
Traygus- Iniciante
- PONTOS : 1324
REPUTAÇÃO : 9
Respeito as regras :
Re: Qual seria a melhor maneira de criar um Map Mundi interativo?
Yep, definitivamente tem uma diferença nos tamanhos e isso com certeza impacta no resultado, já que mesmo se usasse o valor vindo diretamente da UV, ainda ficaria errado... pelo que percebi esse é o único problema do projeto, tá 98% lá.
"Por favor alguem me ajuda, ja procurei por varios tutoriais mas nao acho nenhum, nao quero o script, apenas o que eu poderia utilizar para faze-lo"
Já que conseguiu por meios próprios, aqui vai o projeto que fiz, caso queira usar a mesh que já tem a escala correta, pois é mais uma coisa do Blender que da Unity em si e também os materiais, que acho que serão importantes pra você no seu projeto.
O package tem a cena toda que mostrei nos vídeos anteriores, sinta-se livre pra usar qualquer coisa.
Download
"Por favor alguem me ajuda, ja procurei por varios tutoriais mas nao acho nenhum, nao quero o script, apenas o que eu poderia utilizar para faze-lo"
Já que conseguiu por meios próprios, aqui vai o projeto que fiz, caso queira usar a mesh que já tem a escala correta, pois é mais uma coisa do Blender que da Unity em si e também os materiais, que acho que serão importantes pra você no seu projeto.
O package tem a cena toda que mostrei nos vídeos anteriores, sinta-se livre pra usar qualquer coisa.
Download
Fagner- Moderador
- PONTOS : 4442
REPUTAÇÃO : 667
Áreas de atuação : Modelagem 3D, Programação.
Respeito as regras :
Re: Qual seria a melhor maneira de criar um Map Mundi interativo?
Valeu Fagner! Sou muito grato a tudo, portanto irei baixa-lo caso eu não consiga realmente fazer aquele raycast, irei tentar mais algumas soluções, talvez até mudar de mapa aumentar a escala no blender e etc. Mas muito obrigado pelo apoio! Quando eu puder tentarei retribuir!
Traygus- Iniciante
- PONTOS : 1324
REPUTAÇÃO : 9
Respeito as regras :
Tópicos semelhantes
» Qual seria a maneira correta de fazer a rotação de um obj
» Melhor maneira de criar audio de veiculo
» Qual a maneira mais facil de criar musicas pro jogo?
» Qual a diferença principal entre o VisuaStudio e o MonoDevelop?E qual é o melhor?
» qual o melhor metodo de exportar?
» Melhor maneira de criar audio de veiculo
» Qual a maneira mais facil de criar musicas pro jogo?
» Qual a diferença principal entre o VisuaStudio e o MonoDevelop?E qual é o melhor?
» qual o melhor metodo de exportar?
Página 1 de 1
Permissões neste sub-fórum
Não podes responder a tópicos