SchultzGames
Para tirar dúvidas, crie um tópico especifico na área "Dúvidas em Geral" e aguarde ser respondido. Evite comentar em tópicos não relacionados a sua dúvida :D
TÓPICOS RECENTES:
Tópico:
Postado em:
Postado por:
Arquivo jar não encontrado
OBJETO sendo detruído imediatamente mesmo com o...
Meu site de Modelos 3D
DÚVIDA - ao pressionar andar, o player parece cancelar a gravidade (VÍDEO)
[RESLVIDO] Unity - "transform.SetParent()" em 2 objetos move outros objetos
Dúvida sobre resoluções de tela
Duvida na AppleStore
pressionando a tecla abaixar, o player continua andando abaixado (2D).
Fala Pessoal! Saiu mais um trailer do jogo que venho desenvolvendo
[RESOLVIDO] passar de uma animação para a outra rapidamente pelo animator
Unity - PlayerPrefs n são apagados no Celular mesmo Reiniciando o Aparelho
Modeloes 3D do Site Sketchfab
Blender - Modelos Importados transparentes
[PEDIDO]Cololar jogo na loja play store
Como pegar um objeto e fazer ele aparecer em forma de Estamina no Inspector
Procuro Pessoas para Projeto
Algum tutorial de como fazer um app que receba fotos e q fiqu armazenado no
Procuro um time para um jogo de corrida
[RESOLVIDO] Botões de Ataque e Pular carrega duas animações ao mesmo tempo
DEATH ISLAND 0.2.5 SURVIVAL GAME 4 ANOS EM DESENVOLVIMENTO
Player travando na colisão com o chão Unity 2D
Como resolver vazamento de memoria?
Instanciar uma classe nos atributos de outra classe é uma boa prática?
Jogo multiplayer com steam
Unity - Renderizção com Câmera Jogo Lento e travando. Alguém pfv?!
Mini Quarteirão com Texturas 3D VENDA
Controle do braço e cabeça no fps
PRECISO FAZER QUE MEU GAME FIQUE ONLINE
Ativar o objeto correto em Clones.
[TUTORIAL] Como fazer um interruptor simples (Unity 2018)
Preciso de 20 testadores jogo mobile
O Labirinto II - Trailer Oficial
Ue posso divulgar meu game que ainda esta em criaçao aqui no forum?
[RESOLVIDO] Inverter o sprite para a direçao que o personagem anda.
Set Active não a reabiilitado C#
Build APK VR Google Cardbord com video.
[PROGRAMADOR FREELA] $$
Mais Um jogo!
Collider (mesh?)
[TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
WW2 Low poly Pack (Free)
Procuro freelancer
Novo Teaser do jogo Dark Age
Unity Admob Erro
Sombras estão quadradas na build
nao consigo fazer o player sentar no sofa alguem me ajuda
Unity - Ao mudar de scene, todas as Lights são deletadas
210 Linhas de código para inimigo é muito grande?
modelar avatar e skins para um jogo web
ShapeKeys do Blender para a Unity altera áreas próximas
COMO EVITAR QUE UM OBJETO (PLAYER,ITEM ETC...) ATRAVESSE UMA PAREDE.
Ajuda em Script de Verificação de Ação e Reação
unity Failed to load PlayerSettings (internal index #0). Most likely data f
Materiais do Blander não aparecem no MeshRendere do Objeto na Unity
Repetiçoes de Textura no Terreno
SERVER IS DOWN - UNITY+MSQL
Procuro programadores - Novo jogo
Problema com o MS VEHICLES
Preciso de ajuda com a Unity
Problema com vídeo em 360° na Unity
Problemas no MS Vehicles
unity- eventos na Animação com Armature/Bones vinda do blender não funciona
ajuda exibir resultados simulados em uma liga Game Unity
Unity - ParticleSystem não é redirecionado no rawimage no canvas
Como resolver o problema de "face orientation" no Blender.
[DÚVIDA] Tive um problema com meu Canvas
erro na Directional Light
Problemas com o Directional Light da Unity 3D
Novo jogo da franquia Sphere game em desenvolvimento
malha da roda não girando com wheel collider unity
Problemas com ambiguidade
Touch mobile
INVALID TOKEN
Como acessar o "HD Render Pipeline" do HDRP por script?
CHAT GPT PRA JOGO DE TIRO? comentem
Tutorial script inimigo segue e foge do player
Ainda vale a pena lançar Asset na Asset Store?
Ajuda com tabela de historico de pontuaçao.
[TUTORIAL] Entrar no carro estilo GTA
Como derrapar um Whell Collider
Como altertar o valor do "Asymptote Value" do Whell Collider via Script
Preciso de ajuda para substituir valor de variavel em outro script
Ajuda com Top Down Shooter utilizando Photon
Duvida com Netcode
[RESOLVIDO] Unity - Movendo a Câmera na Horizontal/Vertical com Touch
Alguém me ajuda com os anúncios pfv
Segundo Trailer do jogo Dark Age, Feliz Natal a todos!
Unity - ScrollRect, Viewport, Content - O Conteúdo ñ inicia no topo
Coleta de itens
Unity - Cadastro do email do jogador
[GRATIS] PACK DE MODELOS 3D PARA JOGO DE TERROR
Onde Conseguir músicas para meu Jogo?
error CS0246 em Script
Alguem teve ja esse problema?
[Projeto em Andamento] Draug, um jogo de hordas
DISPONIVEL PARA FAZER MODELOS 3D
Unity-Loja.Como os Jogadores terão acesso aos ítens comprados na PlayStore?
Bugando depois do Build.
Primeiro Trailer do jogo Dark Age
Qua Out 23, 2024 8:39 pm
Sex Out 18, 2024 4:05 pm
Dom Out 06, 2024 6:02 pm
Sáb Out 05, 2024 6:37 am
Qui Out 03, 2024 10:09 pm
Seg Set 30, 2024 9:25 am
Sáb Set 28, 2024 11:39 am
Seg Set 09, 2024 7:33 am
Dom Set 08, 2024 10:08 pm
Ter Set 03, 2024 11:59 am
Qua Ago 28, 2024 7:45 pm
Qua Ago 28, 2024 7:18 pm
Qua Ago 28, 2024 8:34 am
Dom Ago 25, 2024 8:37 pm
Sáb Ago 24, 2024 1:58 pm
Sex Ago 23, 2024 3:30 pm
Sex Ago 23, 2024 3:23 pm
Qua Ago 21, 2024 5:48 pm
Dom Ago 18, 2024 8:51 pm
Sex Ago 16, 2024 12:59 pm
Qua Ago 14, 2024 10:57 am
Sáb Ago 10, 2024 8:03 pm
Sex Ago 09, 2024 7:37 pm
Dom Ago 04, 2024 4:41 pm
Dom Ago 04, 2024 3:16 pm
Qui Jul 25, 2024 2:48 pm
Dom Jul 21, 2024 7:07 pm
Dom Jul 21, 2024 12:07 am
Sáb Jul 13, 2024 12:33 am
Qui Jun 27, 2024 5:49 pm
Qui Jun 20, 2024 12:30 pm
Dom Jun 09, 2024 7:43 pm
Dom Jun 09, 2024 2:16 pm
Seg Jun 03, 2024 11:39 am
Seg maio 27, 2024 12:45 pm
Seg maio 20, 2024 9:01 pm
Dom maio 19, 2024 3:08 pm
Sáb maio 18, 2024 11:46 am
Sáb maio 11, 2024 8:55 am
Qui maio 09, 2024 11:33 pm
Seg Abr 29, 2024 9:34 pm
Qui Abr 25, 2024 3:34 pm
Seg Abr 22, 2024 5:15 pm
Seg Abr 15, 2024 12:23 pm
Seg Abr 08, 2024 9:27 pm
Seg Abr 08, 2024 8:01 am
Sáb Abr 06, 2024 8:05 pm
Qui Abr 04, 2024 11:34 pm
Qui Abr 04, 2024 11:13 pm
Sex Mar 22, 2024 2:41 pm
Dom Mar 10, 2024 2:30 pm
Sex Mar 01, 2024 1:27 pm
Qui Fev 22, 2024 9:57 pm
Ter Fev 20, 2024 12:15 am
Seg Fev 19, 2024 1:06 pm
Seg Fev 12, 2024 1:56 pm
Seg Fev 12, 2024 1:17 pm
Dom Fev 11, 2024 8:55 pm
Dom Fev 11, 2024 11:16 am
Seg Fev 05, 2024 4:18 pm
Dom Fev 04, 2024 9:39 pm
Qua Jan 31, 2024 11:59 pm
Ter Jan 30, 2024 7:37 pm
Ter Jan 23, 2024 6:33 pm
Dom Jan 21, 2024 6:03 pm
Sáb Jan 20, 2024 7:03 pm
Sáb Jan 20, 2024 6:58 pm
Sáb Jan 20, 2024 6:39 pm
Sex Jan 19, 2024 8:40 am
Dom Jan 14, 2024 5:30 pm
Qua Jan 10, 2024 10:29 pm
Qua Jan 10, 2024 8:55 pm
Qua Jan 10, 2024 7:14 pm
Ter Jan 09, 2024 3:55 pm
Ter Jan 09, 2024 8:04 am
Sáb Jan 06, 2024 8:02 pm
Sex Jan 05, 2024 7:01 am
Sex Jan 05, 2024 12:12 am
Qui Jan 04, 2024 6:55 pm
Qui Jan 04, 2024 12:52 pm
Qui Jan 04, 2024 4:34 am
Ter Jan 02, 2024 11:48 pm
Dom Dez 31, 2023 7:25 pm
Qua Dez 27, 2023 5:44 pm
Qua Dez 27, 2023 3:08 pm
Sáb Dez 23, 2023 7:27 pm
Sáb Dez 23, 2023 5:06 pm
Qui Dez 21, 2023 8:10 pm
Seg Dez 18, 2023 2:04 pm
Sex Dez 15, 2023 5:11 pm
Qui Dez 14, 2023 9:13 pm
Qui Dez 14, 2023 2:47 pm
Qui Dez 14, 2023 1:48 pm
Qua Dez 13, 2023 8:58 pm
Ter Dez 12, 2023 2:32 pm
Seg Dez 11, 2023 1:53 pm
Qua Dez 06, 2023 8:13 pm
Sáb Dez 02, 2023 8:06 pm
Qui Nov 30, 2023 7:49 am



































































































[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças

5 participantes

Ir para baixo

TUTORIAL [TUTORIAL] Desenvolvendo um jogo de quebra-cabeças

Mensagem por MayLeone Ter Jan 15, 2019 7:36 pm

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Jigsaw-Puzzle-PNG


Olá pessoal! No tutorial de hoje nós vamos desenvolver um jogo de quebra-cabeças (aqueles clássicos de encaixar as peças para formar uma imagem) na engine Unity.
Em nosso tutorial, será possível escolher qualquer imagem de qualquer tamanho para montar o quebra-cabeças, também será possível decidir o nível de dificuldade do mesmo, onde podemos ter quantidade de peças diferentes dependendo da grade selecionada, por exemplo, uma grade 4x4 terá ao todo 16 peças para serem montadas.
Em nosso jogo, teremos uma grade que irá orientar o jogador da onde cada peça deverá se encaixar, então em nosso tutorial iremos programar também a criação dessa grade proporcional à quantidade de peças, iremos criar o sistema de clique com o mouse, verificação de vitória, recorte da imagem e muito mais.
O resultado final será exatamente esse aqui:



Recortando a imagem:
Uma das primeiras coisas que faremos em nosso tutorial será "cortar" em vários pedacinhos a imagem que será usada como quebra-cabeças.
Antes de iniciarmos de fato a programação de tal sistema no Unity, vamos entender como faríamos esse tipo de "recorte", irei usar como exemplo a imagem abaixo:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Image

Essa imagem foi reduzida para se adequar ao tamanho do site corretamente, porém ela possui originalmente as dimensões 900x800 (largura e altura).
Supondo que desejamos cortar essa imagem em exatos 4 pedaços, isso significa que teremos uma grade 2x2 ou seja, teremos 2 pedaços a serem cortados horizontalmente e mais 2 pedaços na vertical, totalizando 4 peças.
Então tudo certo, sabemos a quantidade de peças e a grade (quantas imagens iremos ter nas linhas e colunas), mas a grande pergunta é... Qual o tamanho(dimensão) de cada pedaço, para que sejam cortados com exatidão sem sobrar partes da imagem?
O cálculo é mais simples do que pensa, para saber a largura do pedaço, basta dividir a largura total da imagem pelo valor da grade (no caso aqui, 2) e o mesmo com a altura, divida a altura da imagem pela dimensão da grade (2).
Por fim, iremos concluir que cada pedaço terá 450x400 de dimensão (900/2) e (800/2), isso significa que teremos 4 imagens de 450x400 de dimensão numa grade 2x2, ou seja, 2 imagens para as colunas e 2 para as linhas, dessa forma:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B2

O padrão se repete caso queria ter mais peças.
Por exemplo, no caso de querer 9 peças, teremos uma grade 3x3, ou seja, teremos 3 imagens para as linhas e 3 para as colunas.
Cada pedaço terá 300x266 pixels de altura e largura (caso a imagem possua 900x800 de dimensão).

Dessa forma, podemos então descobrir o tamanho de cada retângulo (parte da imagem/peça) quando formos cortar as peças através de código.

Script para recortar as peças:
Agora que está entendido como iremos "cortar" a imagem, abra um novo projeto 2D na engine com o nome "Puzzle Game" e importe a imagem que desejá cortar, também crie um prefab de um sprite 2D com o nome de "Piece", a única coisa que ele terá por enquanto será um box collider 2D.
Esse prefab será responsável por "ser a peça", onde exibirá seu sprite como sendo uma parte da imagem.

Para cortar uma imagem devemos utilizar uma Texture2D para representá-la, porém, para poder manipular as textures importadas do projeto devemos permitir que elas sejam passíveis à leitura e escrita, portanto, clique na imagem importada e através do inspector vá à opção "Texture Type >> Advanced" e marque a caixa "Read/Write Enabled" e dê apply:


[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B1


Dessa forma poderemos ter acesso à textura via código.

Agora crie um script chamado "CropTextures" para que possamos recortar as imagens.

Vamos agora criar algumas variáveis públicas para esse script: Um enumerador que irá definir o tamanho da grade do jogo, variando entre as grades 2x2 até 9x9 (você pode colocar mais, se desejar), uma variável do tipo do nosso enumerador para receber a resolução da grade, uma variável do tipo Texture2D chamada "sourceTexture" para recebermos a imagem que será cortada e uma variável do tipo "GameObject" para armazenar o prefab da peça a ser instanciada.
Também criaremos duas variáveis privadas, uma do tipo "int" chamada "amoutPieces" que representará a quantidade de peças e um Vector2 chamado "resolutionPieces" para armazenar a resolução de cada parte da imagem (aquele retângulo que vimos no exemplo anterior):


[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B3



Vamos agora criar um método chamado "StartComponents" para inicializarmos alguns valores.
Por enquanto os únicos valores a serem iniciados serão a quantidade de peças que deve representar o índice do enum "Options", e a resolução das peças que deve ser calculada de acordo com o cálculo que eu mostrei a vocês, ou seja, resolutionPieces.x deve ser a largura da texture dividida pela grade na horizontal, e resolutionPieces.y deve ser a altura da texture dividida pela grade na vertical:


[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B4


Chame esse método dentro do Start do script.

Agora vamos criar o método que de fato cortará a textura em vários pedaços, para criá-lo deixe-o retornar uma Texture2D, chame-o de "CropTexture" e defina dois parâmetros do tipo inteiro, um chamado "row" para representar a coluna que ele deve cortar a imagem e outro chamado "line" para representar a linha.
Agora crie duas variáveis locais (chamadas resolutionX e resolutionY) para que elas recebam os valores da resolução das peças arredondadas (utilize o Mathf.RoundToInt para isso):

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B5

Então agora utilizaremos uma função da classe "Texture2D" que se chama "GetPixels".
Essa função irá retornar os pixels de uma textura/imagem de acordo com a posição e tamanho que serão passados como argumento em formato de um retângulo, deverá ser passado a posição na imagem onde os pixels serão obtidos e a resolução dessa área. A função retorna os pixels da área desejada em forma de um vetor do tipo "Color".

Vamos então criar uma variável local chamada "pixels" do tipo array Color e fazer com que receba a função "GetPixels" sendo chamada através da textura que será anexada ao inspector que ficará armazenada na variável "sourceTexture":

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B6

Agora devemos passar o retângulo (área que deve-se obter os pixels da imagem) como argumento da função.
Esse argumento é um retângulo como já dito, que vai pedir a posição X da onde ele vai obter os pixels e a posição Y, então multiplique o valor da coluna (row) pela resolução em X da peça (row*resolutionX) e multiplique a linha pela resolução em Y (line*resolutionY).
Para saber o tamanho da área a ser obtida, basta passar o valor da resolução em X e em Y, respetivamente:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B7

Como iremos criar um laço de repetição que irá percorrer a imagem completa de acordo com as dimensões da mesma, a função "CropTexture" irá ser chamada toda vez que uma parte da imagem for percorrida, representada pelos parâmetros "row" e "line" para sabermos em qual coluna e linha o laço está, dessa forma, a nossa função irá retornar um pedaço da textura num local específico da imagem toda vez que for chamada.

Agora vamos criar uma nova Texture2D para ser retornada da função com a parte da imagem que foi recortada através da função "GetPixels"
Para isso, basta criar uma variável local chamada "tex" e dentro do seu construtor passar a resolução dessa nova textura a ser criada, no caso, resolutionX e resolutionY.
Após fazer isso, preencha essa nova textura com os pixels obtidos anteriormente e que estão armazenados no array "pixels", através da função "SetPixels". Aplique essa atualização através da função "Apply" e retorne da função a variável "tex":

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B8

Criando as posições para as peças:
Nessa altura do tutorial nós temos como retornar cada parte da imagem de acordo com sua resolução, mas ainda não temos onde colocar essas imagens das peças.
Nós iremos representar a imagem de cada peça a partir daquele prefab já citado anteriormente que é apenas um sprite2D com um collider.
Antes de instanciarmos o prefab com a imagem cortada em seu sprite, vamos definir as possíveis posições onde esses prefabs serão sorteados.
Para que o jogo fique mais interesse, vamos sortear os pedacinhos em locais aleatórios da cena e toda vez que o jogo ser iniciado novamente, os pedacinhos irão trocar de posições.

Vamos criar mais algumas variáveis do tipo "Vector2": uma chamada "position" que irá guardar a posição da peça que será instanciada, outra chamada "distancePieces" que irá guardar a resolução do tamanho das peças para que possamos instanciá-las uma do lado da outra, e duas listas do tipo "Vector2" uma chamada "positions" para guardar todas as posições possíveis que as peças ficarão, e outra chamada "sortedPieces" que irá armazenadas as peças já sorteadas, para que não se repita um local e alguma peça fique sobre a outra:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B9

Criaremos agora um método sem retorno chamado "CreatePositions" que vai ser responsável por de fato, criar as possíveis posições para que as peças possam ser instanciadas.
Vamos calcular primeiramente a distância de cada peça, que deve ser em "x" a resolução da peça em X divida por 100 (se a resolução da peça for 300, por exemplo, a distância entre essas peças na Unity será de 3 pixels, já que estamos utilizando 100 pixels per unit para o tamanho da imagem) e para Y será o mesmo princípio.
Depois disso, crie um laço de repetição que tem como contador um inteiro chamado "x" e que vai ser incrementado até que o mesmo seja menor que a quantidade de peças, e dentro desse laço defina outro laço com o contador chamado "y" que irá ser incrementado até que seu valor seja menor que a quantidade de peças.
Agora adicione dentro da lista "positions" um novo Vector2 em x tendo a distância das peças multiplicado pelo contador "x" e em "y" a distância das peças multiplicado pelo contador "y":

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B10

Então se por exemplo temos uma peça com resolução de 400 pixels(de largura e altura) e uma grade 2x2, as posições serão:

0 e 0,
0 e 4,
4 e 0,
4 e 4.

Ou seja, teremos duas peças nas posições 0;0 e 0;4 (primeira linha) e duas peças nas posições 4;0 e 4;4 (segunda linha), ou seja, uma grade 2x2 com duas linhas e duas colunas.
A distância entre cada peça é de 4 pixels tanto em x quanto em y, pois dividimos a resolução da peça por 100, fazendo com que quando as peças forem instanciadas em alguma dessas quatro posições, elas fiquem exatamente uma do lado da outra, formando então uma grade 2x2 com 4 peças.

Chame esse método "CreatePositions" dentro do Start do script.

Randomizando posições:
Agora que temos dentro da lista "positions" todas as possíveis posições para as peças, vamos randomizá-las, sorteando aleatoriamente sempre uma nova posição para a peça que está sendo instanciada.
Para tal, crie um método chamado "RandomPosition" que retorna um Vector2.
Dentro desse método crie uma variável local chamada "sorted" para definirmos se alguma posição válida foi sorteada, então inicie essa variável como sendo "false".
Crie uma outra variável local chamada "pos" que irá conter as posições sorteadas e a inicialize como um Vector zero.
Agora crie um laço "while" que irá ficar sendo executado enquanto "sorted" for false.
Dentro do laço faça com que a variável "pos" receba um valor aleatório dentro da lista "positions" através do método Random.Range.
Após isso, nós iremos armazenar dentro da variável "sorted" se essa posição sorteada aleatoriamente já foi sorteada antes, para isso, basta verificar se dentro da lista "sortedPositions" o valor de "pos" não está contido nela.
Caso "sorted" seja true (ou seja, o valor ainda não foi sorteado) armazene dentro da variável "sortedPositions" o valor de "pos", já que é uma posição que ainda não foi sorteada. Após o laço, apenas retorne "pos":

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B11

Pronto! Agora temos um método que irá randomizar as posições das peças de acordo com as possíveis posições na cena.

Instanciando as peças:
Vamos então finalmente instanciar as peças na cena que irão representar as partes da textura recortada.
Crie um método sem retorno com o nome "CreatePiece" e o chame dentro do Start do script.
Agora vamos instanciar os prefabs de acordo com a quantidade de peças.
Para isso, vamos criar dois laços de repetições aninhados (igual fizemos com o CreatePositions), assim, nós iremos percorrer as linhas e colunas da textura como um todo.
Vamos representar o primeiro laço pela obtenção das linhas da imagem(esse contador será chamado de 'i') e o segundo laço, as colunas da imagem (contador com o nome de 'j'), para representarmos uma matriz ixj.
Se começarmos o laço 'i' do zero, ele vai começar da última linha da imagem, ou seja, a primeira parte da imagem vai ser obtida a partir da última linha da mesma, então se quisermos que a primeira parte da imagem seja obtida a partir da sua primeira linha, devemos iniciar esse laço de trás pra frente, assim a imagem será recortada de cima para baixo da esquerda para a direita.
Então crie uma variável local chamada "start" e nela armazene "amoutPieces" -1.
Agora crie o laço "i" iniciando de start, e tendo seu delimitador até que "i" seja maior ou igual a 0, recebendo um decremento de um em um.
Já dentro do laço 'i' com o laço 'j', sua definição é mais simples: basta o iniciar a partir do 0, e se delimitar até que seu valor seja menor que "amoutPieces", recebendo o incremento de um em um:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B12

Vamos finalmente criar o prefab contendo a parte da textura cortada, crie uma variável local chamada "texture" e a faça receber a chamada da nossa função "CropTexture", passando como argumento j e i, respectivamente.
Faça com que a variável "position" receba a chamada da nossa função "RandomPosition" para que seja sorteada uma posição para esse prefab, e por fim, faça com que uma variável local chamada "quad" receba a instância do prefab "piecePrefab", na posição "position".

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B13

Agora faremos com que esse prefab tenha como imagem (sprite) o pedaço da peça cortada que está armazenada na variável "texture":
Através da variável "quad" pegue o componente "SpriteRenderer" do objeto e acesse sua propriedade "sprite". Através do comando "Sprite.Create" crie um novo sprite para esse prefab, passando como argumento a textura que irá ser criada (no caso, a variável "texture" que contém a parte cortada da imagem), e um novo retângulo que irá definir a dimensão desse sprite, ou seja, 0 e 0 para a imagem ser obtida a partir do canto inferior esquerdo, com as dimensões de "texture" para a largura e altura, e após definir o retângulo, defina o pivot dessa imagem, recomendo que seja central, sendo um novo Vector2 com os valores 0.5 e 0.5 (centro da imagem):

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B14

Vamos então ajustar o colisor do sprite para que fique do tamanho da textura cortada, para isso, através da variável "quad" obtenha o componente "BoxCollider2D"e faça acesso à propriedade "size", dentro dela armazene um novo Vector2 com "X" sendo o valor de "distancePieces.x" e "Y" sendo "distancePieces.y":

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B15


Salve o script.
Agora crie um novo objeto vazio em cena com o nome de "GameManager" e nele adicione o script "CropTexture".
Através do inspector selecione um tamanho qualquer para a grade, anexe a imagem que deseja ser recortada para o quebra-cabeças e o prefab da peça:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B16

Teste o jogo e em tempo de execução ajuste a posição e campo de visão da câmera. 
Perceba que as peças são instanciadas de acordo com a grade selecionada, em diversos pedaços, um do lado do outro:


[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B17
Exemplo de grade 4x4 com 16 peças.

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B18
Exemplo de grade 2x2 com 4 peças.

Criando a grade:
Com a instanciação das peças, vamos então criar a instância da grade, para que cada parte da imagem seja encaixada corretamente.
Para tal, crie através de um editor de imagens de sua preferência um quadrado com a resolução 150x150(por exemplo), transparente e com uma borda interna cinza com 2 pixels de espessura. Salve a imagem em formato .png com o nome de "quad", a imagem será mais ou menos assim:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Quad
Importe a imagem para o projeto.
Agora crie um novo Sprite na cena com o nome de "Grid", contendo apenas um BoxCollider2D com a opção "Is Trigger" marcada, tendo como "sprite" a imagem que acabara de importar. Faça com que esse objeto se torne um prefab.

Vamos então voltar para o script "CropTexture" e criar a variável "gridPrefab" como pública:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B19

Após ter feito isso, crie um método sem retorno chamado "CreateGrid" que vai receber três parâmetros: dois inteiros chamados "j" e "i" e um GameObject chamado "quad".

Crie uma variável local chamada "grid" e a faça receber o Instantiate contendo o prefab "gridPrefab", um novo Vector2 recebendo em "x" a variável 'j' multiplicando a distância das peças em X e subtraindo esse valor por 10 (fazendo com que a grade seja instanciada com 10 pixels de distância das peças), e em "y" a variável 'i' multiplicando a distância das peças em Y.
Vamos também criar uma variável local chamada "newScale" para determinar a nova escala desse sprite de acordo com a grade das peças, fazendo com que essa variável receba um novo Vector2 em "x" sendo a resolução da peça em x dividida pela largura do sprite "quad" (que no caso é 150) e em "y" a resolução da peça em y também dividida por 150.
Agora é só aplicar "newScale" em x e y para "localScale" de "grid":

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B21

Agora chame o método "CreateGrid" dentro do método "CreatePiece" após criar a peça passando como argumento as variáveis "j" e "i" e também "quad":

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B22

Salve o script e através do inspector anexe o prefab "grid" na variável "gridPrefab" no GameManager. Teste o jogo:


[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B23

Exemplo de uma grade criada a partir de 9 peças (grade 3x3).

Script da peça:
Temos agora as peças e grade em cena, mas elas não possuem nenhuma interação com o usuário.
Vamos então criar o script responsável por "controlarmos" as peças, crie um novo c# script com o nome de "PieceScript".
Vamos então criar nossas variáveis públicas (que serão acessadas a partir de outra classe), portanto terão como atributo "HiddenInInspector": duas variáveis do tipo Vector2 uma chamada "startPosition" e outra com o nome de "endPosition", e duas variáveis do tipo bool, uma chamada "canMove" que vai verificar se essa peça pode se mover e outra "cancelPiece" que vai verificar se essa peça parou de ser manipulada.
Como variáveis privadas nós teremos a variável do tipo SpriteRenderer com o nome de "sprite" e uma outra do tipo float chamada "timeToLerp" para criarmos um efeito "Lerp" ao soltar a peça, essa variável irá iniciar com o valor 20.
Dentro do Start do script inicie a variável ''sprite'' com a obtenção do componente "SpriteRenderer" do objeto:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B24

A variável "startPosition" vai ser responsável por informar ao programa qual é a posição em que a peça foi instanciada, portanto, salve esse script e volte ao script "CropTexture" e antes de criar a grade dentro do método "CreatePiece", através da variável "quad" obtenha o script "PieceScript" e faça acesso à variável "StartPosition" definindo a variável "position":

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B25

Já a variável "EndPosition" é responsável por informar ao programa qual é a parte da grade correta para que a peça seja posicionada, então é crucial que você vá ao método "CreateGrid" e através do parâmetro "quad" faça acesso ao script "PieceScript" e à propriedade "endPosition" da peça, fazendo com que receba a posição (transform.position) da grade que acabou de ser criada:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B27


Salve o script.
Vamos agora criar um script chamado "GameManager" que vai conter a score atual do jogador, o score que ele deve obter e a peça atual que está sendo manipulada.
Crie esse script com três variáveis públicas e estáticas, uma do tipo GameObject chamada "currentPiece" e duas do tipo int uma chamada "currentScore" e "scoreTotal". Salve o script:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B28

Volte para o script "CropTexture" e no método "StartComponents" faça com que "currentScore" inicie em zero e com que "scoreTotal" receba a quantidade de peças vezes ela mesma:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B29

Salve esse script e volte para o script "PieceScript".

Clicando na peça:
Após fazer esses pequenos ajustes, vamos fazer de fato a peça ser "levada" pelo mouse, ao clicar na mesma.
Defina o evento "OnMouseOver" no script "PieceScript" para ser disparado quando o ponteiro do mouse estiver sob o objeto da peça. Dentro do método crie uma condição que vai verificar o lado do mouse que foi pressionado, caso for o esquerdo(0) e cancelPiece for false e currentPiece for null (não há no momento nenhuma outra peça sendo manipulada pelo mouse), faremos com que currentPiece receba esse gameObject(essa peça) e que canMove fique true.
Caso o lado do mouse direito for pressionado (1), cancelPiece for false e canMove for true, iremos fazer com que cancelPiece receba true, pois com o lado direito do mouse nós iremos "soltar" a peça:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B30

Agora dentro do Update do script nós vamos criar uma validação se "canMove" for true, e caso for, a peça poderá seguir o ponteiro do mouse.
Primeiro faça com que a sortingOrder do sprite fique igual a 1 (para ficar sobre todas as outras peças), e então crie uma variável local chamada mouseP para receber a posição do mouse de acordo com o mousePosition.
vamos ajustar o eixo 'z' da posição do mouse para as definições da tela do jogo(Mundo do Unity) e não com relação à tela do computador, para isso, basta fazer com que mouseP.z receba a posição "z" da peça menos a posição "z" da câmera.
Então finalmente faça com que o transform.position do objeto(peça) receba a posição do mouse (mouseP) com relação ao mundo dentro do Unity:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B31

Através desses comandos, é possível que o sprite do objeto siga o ponteiro do mouse pela tela.

Faremos agora a função de cancelamento da peça, caso o jogador queira "largá-la".
Crie um método sem retorno chamado "CancelPiece" e dentro dele faça com que currentPiece receba 'null' (pois não estamos mais manipulando nenhuma peça), e faça com que a posição da peça volte para sua posição inicial com uma certa suavização utilizando o método "MoveTowards", saindo da posição atual onde o objeto se encontra, tendo como destino o Vector "startPosition" num tempo de acordo com a variável "TimeToLerp" multiplicado por time.DeltaTime.
Faça também com que a variável "canMove" fique false e depois uma validação se a posição do objeto é igual à posição "startPosition", caso for, faça com que o sortingOrder volte a ser 0 e que cancelPiece volte a ficar false:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B32

Dentro do Update faça com que CancelPiece seja chamado se "cancelPiece" for verdadeiro:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B33

Salve o script e o adicione ao prefab "Piece". Agora ao testar o jogo, você percebe que pode fazer com que a peça siga o mouse ao clicar na mesma, e se clicar com o lado direito, a peça se 'solta' e volta para seu ponto de origem suavemente:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B34

Clicando na grade:
Agora que podemos transitar com a peça pela tela através do mouse, vamos criar o script da grade que irá verificar se a peça que estamos manipulando faz parte daquele pedaço da grade.
Crie um novo C# script com o nome de "GridScript".
Dentro do Update desse script, vamos verificar se o mouse está sob o colisor desse objeto (grade) , então crie uma validação através do BoxCollider2D do objeto, e do método "OverlapPoint, passando como argumento a posição do mouse de acordo com o mundo dentro do Unity.
Caso o mouse esteja sob esse collider, chame o método "Check" que iremos definir a seguir.

O método "Check" deve ser sem retorno, e dentro dele vamos verificar se o botão esquerdo o mouse foi pressionado (0) e se currentPiece não é nulo, ou seja, temos alguma peça sendo manipulada no momento.
Caso ambas sentenças forem verdadeiras, iremos criar uma segunda condição que verifica se "endPosition" de "currentPiece" é igual a posição dessa parte da grade, caso sim, iremos posicionar a peça exatamente na mesma posição que esse pedaço da grade, faremos com que o sortingOrder de "currentPiece" volte a ser 0, destruiremos o script "PieceScript" do "currentPiece" para que não possamos mais clicar na peça e movimentá-la, faremos com que currentPiece volte a ser nulo, incrementamos o score do jogador e por fim, destruímos o objeto da grade (Para evitar de clicar nela novamente e melhorar a performance do jogo, já que não iremos mais usar esse script).

Caso a peça corrente não tenha como 'destino' essa parte da grade, apenas faça com que ela "volte" para seu local de origem fazendo com que "cancelPiece" fique true.
O script deve estar assim:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B36


Salve o script e adicione-o no prefab "Grid". Teste o jogo e veja que agora é possível encaixar as peças:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B37

Verificando final de jogo:
Para verificar o final do jogo é bem simples: Primeiro crie um Canvas com um text ancorado e devidamente dimensionado com o texto "Congratulations":

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B38

E por padrão deixe-o desativado.
Agora vá para o script "GameManager" e crie uma variável pública do tipo "Text" chamada "text" (referencie a biblioteca "UI" dentro do script!)
Agora dentro do Update crie uma validação se currentScore for igual a totalScore, o gameObject de "text" irá ser ativado:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B39

Agora anexe esse script no objeto "GameManager" e faça com que o text do canvas seja armazenado na variável "text" desse script.
Teste o jogo e tente montar o quebra-cabeças: Perceba que quando você o completa o jogo "se encerra" e a mensagem de congratulações aparece na tela:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B40

Mostrando imagem original:
Outro sistema que podemos fazer é o de mostrar a imagem como ela é quando montada, ao clicar num botão.
É muito fácil criar esse sistema, basta criar uma imagem dentro do Canvas e a posicionar, ancorar e redimensionar da forma que achar melhor:


[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B41

Desativa a imagem também.
Agora vá para o script "CropTextures" crie uma variável pública do tipo Image chamada "img" (referencie a biblioteca UI) e no método "StartComponents" faça com que ela receba a textura da imagem do quebra-cabeças de acordo com sourceTexture, igual já fizemos anteriormente:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B43

Salve o script e anexe a imagem na variável "img"do script do GameManager.
Crie agora um Button dentro do Canvas com o Texto "View Image" e o ancore e posicione da forma que achar melhor.
Crie um novo C# script chamado "ButtonScript" e crie uma variável pública do tipo "Image" chamada "img" e uma variável private booleana chamada "isEnabled" iniciando em "false".
Agora defina um método público sem retorno chamado "ClickViewImage" e faça com que a variável "isEnabled" receba seu oposto. Após isso, faça com que a "img" seja ativada se isEnabled for true e desativada se isEnabled for false:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B44

Salve o script e o adicione no botão dentro do Canvas, anexando a imagem desativada dentro da variável "img". Dentro do evento "OnClick" clique no sinal de mais (+)  e em "None" adicione o próprio objeto do botão, e após isso em "No Function" vá em "ButtonScript >> ClickViewImage" para esse método seja disparado quando clicarmos no botão.
Teste o jogo e clique no button: Perceba que quando faz isso, a imagem original do quebra-cabeças aparece no canto da tela, e ao clicar novamente no button, ela é desativada:


[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B46

Isso pode auxiliar o jogador a ver como a imagem é de fato para poder montar o quebra-cabeças.

Final:
E chegamos (ufa) a mais um final de tutorial por aqui! A sugestão que eu ainda tenho para melhorar o jogo é criar um menu que possibilite o jogador a escolher com qual imagem ele quer jogar(uma gama de opções de imagens, ao invés de uma) e a dificuldade através da escolha da grade.
Esse tutorial foi muito trabalhoso de fazer (acho que foi o mais de todos) portanto, se gostou e se te ajudou em algo (mesmo se não for com relação ao desenvolvimento de um quebra-cabeças, mas ao aprender sobre algum comando que você não sabia) deixe o seu feedback, isso é muito importante para me motivar a continuar postando tutoriais e aulas aqui.
Por fim, caso queira, aqui está o link do código fonte no gitHub: https://github.com/mayleone1994/PuzzleGame

Até mais!
MayLeone
MayLeone
Instrutor

Feminino PONTOS : 3813
REPUTAÇÃO : 602
Áreas de atuação : Unity & C#
Respeito as regras : [TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Aad8pUi

http://compilemosfacil.blogspot.com.br

Ir para o topo Ir para baixo

TUTORIAL Re: [TUTORIAL] Desenvolvendo um jogo de quebra-cabeças

Mensagem por dstaroski Ter Jan 15, 2019 7:48 pm

Nossa! Parabéns ai! Show!
dstaroski
dstaroski
Instrutor

Masculino PONTOS : 6299
REPUTAÇÃO : 1123
Idade : 35
Áreas de atuação : Teologia, Unity 3D, C#, HTML, CSS, Dart, Flutter.

Respeito as regras : [TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Aad8pUi

http://diegodeoliveira.gamejolt.io/defeattheilluminatis

Ir para o topo Ir para baixo

TUTORIAL Re: [TUTORIAL] Desenvolvendo um jogo de quebra-cabeças

Mensagem por MarcosSchultz Ter Jan 15, 2019 10:57 pm

Que tutorial topppp.

@MayLeone, você já pensou em vender cursos na Udemy? A qualidade dos seus tutoriais é bem alta, e o principal, é bastaante detalhado.

Meio que direto aparece gente pedindo se eu tenho cursos pra vender na Udemy, ou seja, tem público. Qualidade alta em tutoriais pode ser bem explorada em sites de vendas de tutoriais, e gera um money extra significativo as vezes.
MarcosSchultz
MarcosSchultz
Administrador

Masculino PONTOS : 64984
REPUTAÇÃO : 2654
Idade : 28
Áreas de atuação : Administrador do fórum
Respeito as regras : [TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Aad8pUi

https://www.schultzgames.com

Ir para o topo Ir para baixo

TUTORIAL Re: [TUTORIAL] Desenvolvendo um jogo de quebra-cabeças

Mensagem por MayLeone Qua Jan 16, 2019 11:35 am

Vlw Marcos!
Eu realmente queria começar um curso de criação de jogos para iniciantes com Unity lá na Udemy, massssss me falta o essencial, um equipamento descente (máquina boa + microfone), sem dizer que minha casa é bem barulhenta, então quase sempre eu me estresso gravado vídeos, por isso prefiro escrever, apesar de que dá muito mais trabalho.
Mas eu pretendo normalizar essa situação e levar a sério a ideia desses cursos e etc.
Obrigada pelo feeback, é bem importante pra eu saber se estou no caminho certo.

Vlw vc também, dstaroski!
MayLeone
MayLeone
Instrutor

Feminino PONTOS : 3813
REPUTAÇÃO : 602
Áreas de atuação : Unity & C#
Respeito as regras : [TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Aad8pUi

http://compilemosfacil.blogspot.com.br

Ir para o topo Ir para baixo

TUTORIAL Re: [TUTORIAL] Desenvolvendo um jogo de quebra-cabeças

Mensagem por fabricadegame Ter maio 28, 2019 9:31 am

MayLeone escreveu:Vlw Marcos!
Eu realmente queria começar um curso de criação de jogos para iniciantes com Unity lá na Udemy, massssss me falta o essencial, um equipamento descente (máquina boa + microfone), sem dizer que minha casa é bem barulhenta, então quase sempre eu me estresso gravado vídeos, por isso prefiro escrever, apesar de que dá muito mais trabalho.
Mas eu pretendo normalizar essa situação e levar a sério a ideia desses cursos e etc.
Obrigada pelo feeback, é bem importante pra eu saber se estou no caminho certo.

Vlw vc também, dstaroski!

Ou MayLeone, você escreve bem e de uma forma bastante didática. Existem poucos livros em português da Unity ou talvez nenhum. Ainda existem alguns cursos regulares, técnicos e superiores que estão demandando esse tipo de conteúdo.
O que acha de começar um projeto de um livro? Eu acho que vc teria um bom conteúdo final,l viu.

fabricadegame
Membro
Membro

PONTOS : 2213
REPUTAÇÃO : 11
Respeito as regras : [TUTORIAL] Desenvolvendo um jogo de quebra-cabeças WvDYdlf

Ir para o topo Ir para baixo

TUTORIAL Re: [TUTORIAL] Desenvolvendo um jogo de quebra-cabeças

Mensagem por Diego Felix Ter Jun 18, 2019 9:46 am

MayLeone escreveu:
[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Jigsaw-Puzzle-PNG


Olá pessoal! No tutorial de hoje nós vamos desenvolver um jogo de quebra-cabeças (aqueles clássicos de encaixar as peças para formar uma imagem) na engine Unity.
Em nosso tutorial, será possível escolher qualquer imagem de qualquer tamanho para montar o quebra-cabeças, também será possível decidir o nível de dificuldade do mesmo, onde podemos ter quantidade de peças diferentes dependendo da grade selecionada, por exemplo, uma grade 4x4 terá ao todo 16 peças para serem montadas.
Em nosso jogo, teremos uma grade que irá orientar o jogador da onde cada peça deverá se encaixar, então em nosso tutorial iremos programar também a criação dessa grade proporcional à quantidade de peças, iremos criar o sistema de clique com o mouse, verificação de vitória, recorte da imagem e muito mais.
O resultado final será exatamente esse aqui:



Recortando a imagem:
Uma das primeiras coisas que faremos em nosso tutorial será "cortar" em vários pedacinhos a imagem que será usada como quebra-cabeças.
Antes de iniciarmos de fato a programação de tal sistema no Unity, vamos entender como faríamos esse tipo de "recorte", irei usar como exemplo a imagem abaixo:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Image

Essa imagem foi reduzida para se adequar ao tamanho do site corretamente, porém ela possui originalmente as dimensões 900x800 (largura e altura).
Supondo que desejamos cortar essa imagem em exatos 4 pedaços, isso significa que teremos uma grade 2x2 ou seja, teremos 2 pedaços a serem cortados horizontalmente e mais 2 pedaços na vertical, totalizando 4 peças.
Então tudo certo, sabemos a quantidade de peças e a grade (quantas imagens iremos ter nas linhas e colunas), mas a grande pergunta é... Qual o tamanho(dimensão) de cada pedaço, para que sejam cortados com exatidão sem sobrar partes da imagem?
O cálculo é mais simples do que pensa, para saber a largura do pedaço, basta dividir a largura total da imagem pelo valor da grade (no caso aqui, 2) e o mesmo com a altura, divida a altura da imagem pela dimensão da grade (2).
Por fim, iremos concluir que cada pedaço terá 450x400 de dimensão (900/2) e (800/2), isso significa que teremos 4 imagens de 450x400 de dimensão numa grade 2x2, ou seja, 2 imagens para as colunas e 2 para as linhas, dessa forma:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B2

O padrão se repete caso queria ter mais peças.
Por exemplo, no caso de querer 9 peças, teremos uma grade 3x3, ou seja, teremos 3 imagens para as linhas e 3 para as colunas.
Cada pedaço terá 300x266 pixels de altura e largura (caso a imagem possua 900x800 de dimensão).

Dessa forma, podemos então descobrir o tamanho de cada retângulo (parte da imagem/peça) quando formos cortar as peças através de código.

Script para recortar as peças:
Agora que está entendido como iremos "cortar" a imagem, abra um novo projeto 2D na engine com o nome "Puzzle Game" e importe a imagem que desejá cortar, também crie um prefab de um sprite 2D com o nome de "Piece", a única coisa que ele terá por enquanto será um box collider 2D.
Esse prefab será responsável por "ser a peça", onde exibirá seu sprite como sendo uma parte da imagem.

Para cortar uma imagem devemos utilizar uma Texture2D para representá-la, porém, para poder manipular as textures importadas do projeto devemos permitir que elas sejam passíveis à leitura e escrita, portanto, clique na imagem importada e através do inspector vá à opção "Texture Type >> Advanced" e marque a caixa "Read/Write Enabled" e dê apply:


[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B1


Dessa forma poderemos ter acesso à textura via código.

Agora crie um script chamado "CropTextures" para que possamos recortar as imagens.

Vamos agora criar algumas variáveis públicas para esse script: Um enumerador que irá definir o tamanho da grade do jogo, variando entre as grades 2x2 até 9x9 (você pode colocar mais, se desejar), uma variável do tipo do nosso enumerador para receber a resolução da grade, uma variável do tipo Texture2D chamada "sourceTexture" para recebermos a imagem que será cortada e uma variável do tipo "GameObject" para armazenar o prefab da peça a ser instanciada.
Também criaremos duas variáveis privadas, uma do tipo "int" chamada "amoutPieces" que representará a quantidade de peças e um Vector2 chamado "resolutionPieces" para armazenar a resolução de cada parte da imagem (aquele retângulo que vimos no exemplo anterior):


[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B3



Vamos agora criar um método chamado "StartComponents" para inicializarmos alguns valores.
Por enquanto os únicos valores a serem iniciados serão a quantidade de peças que deve representar o índice do enum "Options", e a resolução das peças que deve ser calculada de acordo com o cálculo que eu mostrei a vocês, ou seja, resolutionPieces.x deve ser a largura da texture dividida pela grade na horizontal, e resolutionPieces.y deve ser a altura da texture dividida pela grade na vertical:


[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B4


Chame esse método dentro do Start do script.

Agora vamos criar o método que de fato cortará a textura em vários pedaços, para criá-lo deixe-o retornar uma Texture2D, chame-o de "CropTexture" e defina dois parâmetros do tipo inteiro, um chamado "row" para representar a coluna que ele deve cortar a imagem e outro chamado "line" para representar a linha.
Agora crie duas variáveis locais (chamadas resolutionX e resolutionY) para que elas recebam os valores da resolução das peças arredondadas (utilize o Mathf.RoundToInt para isso):

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B5

Então agora utilizaremos uma função da classe "Texture2D" que se chama "GetPixels".
Essa função irá retornar os pixels de uma textura/imagem de acordo com a posição e tamanho que serão passados como argumento em formato de um retângulo, deverá ser passado a posição na imagem onde os pixels serão obtidos e a resolução dessa área. A função retorna os pixels da área desejada em forma de um vetor do tipo "Color".

Vamos então criar uma variável local chamada "pixels" do tipo array Color e fazer com que receba a função "GetPixels" sendo chamada através da textura que será anexada ao inspector que ficará armazenada na variável "sourceTexture":

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B6

Agora devemos passar o retângulo (área que deve-se obter os pixels da imagem) como argumento da função.
Esse argumento é um retângulo como já dito, que vai pedir a posição X da onde ele vai obter os pixels e a posição Y, então multiplique o valor da coluna (row) pela resolução em X da peça (row*resolutionX) e multiplique a linha pela resolução em Y (line*resolutionY).
Para saber o tamanho da área a ser obtida, basta passar o valor da resolução em X e em Y, respetivamente:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B7

Como iremos criar um laço de repetição que irá percorrer a imagem completa de acordo com as dimensões da mesma, a função "CropTexture" irá ser chamada toda vez que uma parte da imagem for percorrida, representada pelos parâmetros "row" e "line" para sabermos em qual coluna e linha o laço está, dessa forma, a nossa função irá retornar um pedaço da textura num local específico da imagem toda vez que for chamada.

Agora vamos criar uma nova Texture2D para ser retornada da função com a parte da imagem que foi recortada através da função "GetPixels"
Para isso, basta criar uma variável local chamada "tex" e dentro do seu construtor passar a resolução dessa nova textura a ser criada, no caso, resolutionX e resolutionY.
Após fazer isso, preencha essa nova textura com os pixels obtidos anteriormente e que estão armazenados no array "pixels", através da função "SetPixels". Aplique essa atualização através da função "Apply" e retorne da função a variável "tex":

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B8

Criando as posições para as peças:
Nessa altura do tutorial nós temos como retornar cada parte da imagem de acordo com sua resolução, mas ainda não temos onde colocar essas imagens das peças.
Nós iremos representar a imagem de cada peça a partir daquele prefab já citado anteriormente que é apenas um sprite2D com um collider.
Antes de instanciarmos o prefab com a imagem cortada em seu sprite, vamos definir as possíveis posições onde esses prefabs serão sorteados.
Para que o jogo fique mais interesse, vamos sortear os pedacinhos em locais aleatórios da cena e toda vez que o jogo ser iniciado novamente, os pedacinhos irão trocar de posições.

Vamos criar mais algumas variáveis do tipo "Vector2": uma chamada "position" que irá guardar a posição da peça que será instanciada, outra chamada "distancePieces" que irá guardar a resolução do tamanho das peças para que possamos instanciá-las uma do lado da outra, e duas listas do tipo "Vector2" uma chamada "positions" para guardar todas as posições possíveis que as peças ficarão, e outra chamada "sortedPieces" que irá armazenadas as peças já sorteadas, para que não se repita um local e alguma peça fique sobre a outra:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B9

Criaremos agora um método sem retorno chamado "CreatePositions" que vai ser responsável por de fato, criar as possíveis posições para que as peças possam ser instanciadas.
Vamos calcular primeiramente a distância de cada peça, que deve ser em "x" a resolução da peça em X divida por 100 (se a resolução da peça for 300, por exemplo, a distância entre essas peças na Unity será de 3 pixels, já que estamos utilizando 100 pixels per unit para o tamanho da imagem) e para Y será o mesmo princípio.
Depois disso, crie um laço de repetição que tem como contador um inteiro chamado "x" e que vai ser incrementado até que o mesmo seja menor que a quantidade de peças, e dentro desse laço defina outro laço com o contador chamado "y" que irá ser incrementado até que seu valor seja menor que a quantidade de peças.
Agora adicione dentro da lista "positions" um novo Vector2 em x tendo a distância das peças multiplicado pelo contador "x" e em "y" a distância das peças multiplicado pelo contador "y":

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B10

Então se por exemplo temos uma peça com resolução de 400 pixels(de largura e altura) e uma grade 2x2, as posições serão:

0 e 0,
0 e 4,
4 e 0,
4 e 4.

Ou seja, teremos duas peças nas posições 0;0 e 0;4 (primeira linha) e duas peças nas posições 4;0 e 4;4 (segunda linha), ou seja, uma grade 2x2 com duas linhas e duas colunas.
A distância entre cada peça é de 4 pixels tanto em x quanto em y, pois dividimos a resolução da peça por 100, fazendo com que quando as peças forem instanciadas em alguma dessas quatro posições, elas fiquem exatamente uma do lado da outra, formando então uma grade 2x2 com 4 peças.

Chame esse método "CreatePositions" dentro do Start do script.

Randomizando posições:
Agora que temos dentro da lista "positions" todas as possíveis posições para as peças, vamos randomizá-las, sorteando aleatoriamente sempre uma nova posição para a peça que está sendo instanciada.
Para tal, crie um método chamado "RandomPosition" que retorna um Vector2.
Dentro desse método crie uma variável local chamada "sorted" para definirmos se alguma posição válida foi sorteada, então inicie essa variável como sendo "false".
Crie uma outra variável local chamada "pos" que irá conter as posições sorteadas e a inicialize como um Vector zero.
Agora crie um laço "while" que irá ficar sendo executado enquanto "sorted" for false.
Dentro do laço faça com que a variável "pos" receba um valor aleatório dentro da lista "positions" através do método Random.Range.
Após isso, nós iremos armazenar dentro da variável "sorted" se essa posição sorteada aleatoriamente já foi sorteada antes, para isso, basta verificar se dentro da lista "sortedPositions" o valor de "pos" não está contido nela.
Caso "sorted" seja true (ou seja, o valor ainda não foi sorteado) armazene dentro da variável "sortedPositions" o valor de "pos", já que é uma posição que ainda não foi sorteada. Após o laço, apenas retorne "pos":

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B11

Pronto! Agora temos um método que irá randomizar as posições das peças de acordo com as possíveis posições na cena.

Instanciando as peças:
Vamos então finalmente instanciar as peças na cena que irão representar as partes da textura recortada.
Crie um método sem retorno com o nome "CreatePiece" e o chame dentro do Start do script.
Agora vamos instanciar os prefabs de acordo com a quantidade de peças.
Para isso, vamos criar dois laços de repetições aninhados (igual fizemos com o CreatePositions), assim, nós iremos percorrer as linhas e colunas da textura como um todo.
Vamos representar o primeiro laço pela obtenção das linhas da imagem(esse contador será chamado de 'i') e o segundo laço, as colunas da imagem (contador com o nome de 'j'), para representarmos uma matriz ixj.
Se começarmos o laço 'i' do zero, ele vai começar da última linha da imagem, ou seja, a primeira parte da imagem vai ser obtida a partir da última linha da mesma, então se quisermos que a primeira parte da imagem seja obtida a partir da sua primeira linha, devemos iniciar esse laço de trás pra frente, assim a imagem será recortada de cima para baixo da esquerda para a direita.
Então crie uma variável local chamada "start" e nela armazene "amoutPieces" -1.
Agora crie o laço "i" iniciando de start, e tendo seu delimitador até que "i" seja maior ou igual a 0, recebendo um decremento de um em um.
Já dentro do laço 'i' com o laço 'j', sua definição é mais simples: basta o iniciar a partir do 0, e se delimitar até que seu valor seja menor que "amoutPieces", recebendo o incremento de um em um:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B12

Vamos finalmente criar o prefab contendo a parte da textura cortada, crie uma variável local chamada "texture" e a faça receber a chamada da nossa função "CropTexture", passando como argumento j e i, respectivamente.
Faça com que a variável "position" receba a chamada da nossa função "RandomPosition" para que seja sorteada uma posição para esse prefab, e por fim, faça com que uma variável local chamada "quad" receba a instância do prefab "piecePrefab", na posição "position".

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B13

Agora faremos com que esse prefab tenha como imagem (sprite) o pedaço da peça cortada que está armazenada na variável "texture":
Através da variável "quad" pegue o componente "SpriteRenderer" do objeto e acesse sua propriedade "sprite". Através do comando "Sprite.Create" crie um novo sprite para esse prefab, passando como argumento a textura que irá ser criada (no caso, a variável "texture" que contém a parte cortada da imagem), e um novo retângulo que irá definir a dimensão desse sprite, ou seja, 0 e 0 para a imagem ser obtida a partir do canto inferior esquerdo, com as dimensões de "texture" para a largura e altura, e após definir o retângulo, defina o pivot dessa imagem, recomendo que seja central, sendo um novo Vector2 com os valores 0.5 e 0.5 (centro da imagem):

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B14

Vamos então ajustar o colisor do sprite para que fique do tamanho da textura cortada, para isso, através da variável "quad" obtenha o componente "BoxCollider2D"e faça acesso à propriedade "size", dentro dela armazene um novo Vector2 com "X" sendo o valor de "distancePieces.x" e "Y" sendo "distancePieces.y":

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B15


Salve o script.
Agora crie um novo objeto vazio em cena com o nome de "GameManager" e nele adicione o script "CropTexture".
Através do inspector selecione um tamanho qualquer para a grade, anexe a imagem que deseja ser recortada para o quebra-cabeças e o prefab da peça:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B16

Teste o jogo e em tempo de execução ajuste a posição e campo de visão da câmera. 
Perceba que as peças são instanciadas de acordo com a grade selecionada, em diversos pedaços, um do lado do outro:


[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B17
Exemplo de grade 4x4 com 16 peças.

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B18
Exemplo de grade 2x2 com 4 peças.

Criando a grade:
Com a instanciação das peças, vamos então criar a instância da grade, para que cada parte da imagem seja encaixada corretamente.
Para tal, crie através de um editor de imagens de sua preferência um quadrado com a resolução 150x150(por exemplo), transparente e com uma borda interna cinza com 2 pixels de espessura. Salve a imagem em formato .png com o nome de "quad", a imagem será mais ou menos assim:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Quad
Importe a imagem para o projeto.
Agora crie um novo Sprite na cena com o nome de "Grid", contendo apenas um BoxCollider2D com a opção "Is Trigger" marcada, tendo como "sprite" a imagem que acabara de importar. Faça com que esse objeto se torne um prefab.

Vamos então voltar para o script "CropTexture" e criar a variável "gridPrefab" como pública:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B19

Após ter feito isso, crie um método sem retorno chamado "CreateGrid" que vai receber três parâmetros: dois inteiros chamados "j" e "i" e um GameObject chamado "quad".

Crie uma variável local chamada "grid" e a faça receber o Instantiate contendo o prefab "gridPrefab", um novo Vector2 recebendo em "x" a variável 'j' multiplicando a distância das peças em X e subtraindo esse valor por 10 (fazendo com que a grade seja instanciada com 10 pixels de distância das peças), e em "y" a variável 'i' multiplicando a distância das peças em Y.
Vamos também criar uma variável local chamada "newScale" para determinar a nova escala desse sprite de acordo com a grade das peças, fazendo com que essa variável receba um novo Vector2 em "x" sendo a resolução da peça em x dividida pela largura do sprite "quad" (que no caso é 150) e em "y" a resolução da peça em y também dividida por 150.
Agora é só aplicar "newScale" em x e y para "localScale" de "grid":

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B21

Agora chame o método "CreateGrid" dentro do método "CreatePiece" após criar a peça passando como argumento as variáveis "j" e "i" e também "quad":

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B22

Salve o script e através do inspector anexe o prefab "grid" na variável "gridPrefab" no GameManager. Teste o jogo:


[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B23

Exemplo de uma grade criada a partir de 9 peças (grade 3x3).

Script da peça:
Temos agora as peças e grade em cena, mas elas não possuem nenhuma interação com o usuário.
Vamos então criar o script responsável por "controlarmos" as peças, crie um novo c# script com o nome de "PieceScript".
Vamos então criar nossas variáveis públicas (que serão acessadas a partir de outra classe), portanto terão como atributo "HiddenInInspector": duas variáveis do tipo Vector2 uma chamada "startPosition" e outra com o nome de "endPosition", e duas variáveis do tipo bool, uma chamada "canMove" que vai verificar se essa peça pode se mover e outra "cancelPiece" que vai verificar se essa peça parou de ser manipulada.
Como variáveis privadas nós teremos a variável do tipo SpriteRenderer com o nome de "sprite" e uma outra do tipo float chamada "timeToLerp" para criarmos um efeito "Lerp" ao soltar a peça, essa variável irá iniciar com o valor 20.
Dentro do Start do script inicie a variável ''sprite'' com a obtenção do componente "SpriteRenderer" do objeto:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B24

A variável "startPosition" vai ser responsável por informar ao programa qual é a posição em que a peça foi instanciada, portanto, salve esse script e volte ao script "CropTexture" e antes de criar a grade dentro do método "CreatePiece", através da variável "quad" obtenha o script "PieceScript" e faça acesso à variável "StartPosition" definindo a variável "position":

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B25

Já a variável "EndPosition" é responsável por informar ao programa qual é a parte da grade correta para que a peça seja posicionada, então é crucial que você vá ao método "CreateGrid" e através do parâmetro "quad" faça acesso ao script "PieceScript" e à propriedade "endPosition" da peça, fazendo com que receba a posição (transform.position) da grade que acabou de ser criada:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B27


Salve o script.
Vamos agora criar um script chamado "GameManager" que vai conter a score atual do jogador, o score que ele deve obter e a peça atual que está sendo manipulada.
Crie esse script com três variáveis públicas e estáticas, uma do tipo GameObject chamada "currentPiece" e duas do tipo int uma chamada "currentScore" e "scoreTotal". Salve o script:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B28

Volte para o script "CropTexture" e no método "StartComponents" faça com que "currentScore" inicie em zero e com que "scoreTotal" receba a quantidade de peças vezes ela mesma:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B29

Salve esse script e volte para o script "PieceScript".

Clicando na peça:
Após fazer esses pequenos ajustes, vamos fazer de fato a peça ser "levada" pelo mouse, ao clicar na mesma.
Defina o evento "OnMouseOver" no script "PieceScript" para ser disparado quando o ponteiro do mouse estiver sob o objeto da peça. Dentro do método crie uma condição que vai verificar o lado do mouse que foi pressionado, caso for o esquerdo(0) e cancelPiece for false e currentPiece for null (não há no momento nenhuma outra peça sendo manipulada pelo mouse), faremos com que currentPiece receba esse gameObject(essa peça) e que canMove fique true.
Caso o lado do mouse direito for pressionado (1), cancelPiece for false e canMove for true, iremos fazer com que cancelPiece receba true, pois com o lado direito do mouse nós iremos "soltar" a peça:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B30

Agora dentro do Update do script nós vamos criar uma validação se "canMove" for true, e caso for, a peça poderá seguir o ponteiro do mouse.
Primeiro faça com que a sortingOrder do sprite fique igual a 1 (para ficar sobre todas as outras peças), e então crie uma variável local chamada mouseP para receber a posição do mouse de acordo com o mousePosition.
vamos ajustar o eixo 'z' da posição do mouse para as definições da tela do jogo(Mundo do Unity) e não com relação à tela do computador, para isso, basta fazer com que mouseP.z receba a posição "z" da peça menos a posição "z" da câmera.
Então finalmente faça com que o transform.position do objeto(peça) receba a posição do mouse (mouseP) com relação ao mundo dentro do Unity:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B31

Através desses comandos, é possível que o sprite do objeto siga o ponteiro do mouse pela tela.

Faremos agora a função de cancelamento da peça, caso o jogador queira "largá-la".
Crie um método sem retorno chamado "CancelPiece" e dentro dele faça com que currentPiece receba 'null' (pois não estamos mais manipulando nenhuma peça), e faça com que a posição da peça volte para sua posição inicial com uma certa suavização utilizando o método "MoveTowards", saindo da posição atual onde o objeto se encontra, tendo como destino o Vector "startPosition" num tempo de acordo com a variável "TimeToLerp" multiplicado por time.DeltaTime.
Faça também com que a variável "canMove" fique false e depois uma validação se a posição do objeto é igual à posição "startPosition", caso for, faça com que o sortingOrder volte a ser 0 e que cancelPiece volte a ficar false:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B32

Dentro do Update faça com que CancelPiece seja chamado se "cancelPiece" for verdadeiro:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B33

Salve o script e o adicione ao prefab "Piece". Agora ao testar o jogo, você percebe que pode fazer com que a peça siga o mouse ao clicar na mesma, e se clicar com o lado direito, a peça se 'solta' e volta para seu ponto de origem suavemente:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B34

Clicando na grade:
Agora que podemos transitar com a peça pela tela através do mouse, vamos criar o script da grade que irá verificar se a peça que estamos manipulando faz parte daquele pedaço da grade.
Crie um novo C# script com o nome de "GridScript".
Dentro do Update desse script, vamos verificar se o mouse está sob o colisor desse objeto (grade) , então crie uma validação através do BoxCollider2D do objeto, e do método "OverlapPoint, passando como argumento a posição do mouse de acordo com o mundo dentro do Unity.
Caso o mouse esteja sob esse collider, chame o método "Check" que iremos definir a seguir.

O método "Check" deve ser sem retorno, e dentro dele vamos verificar se o botão esquerdo o mouse foi pressionado (0) e se currentPiece não é nulo, ou seja, temos alguma peça sendo manipulada no momento.
Caso ambas sentenças forem verdadeiras, iremos criar uma segunda condição que verifica se "endPosition" de "currentPiece" é igual a posição dessa parte da grade, caso sim, iremos posicionar a peça exatamente na mesma posição que esse pedaço da grade, faremos com que o sortingOrder de "currentPiece" volte a ser 0, destruiremos o script "PieceScript" do "currentPiece" para que não possamos mais clicar na peça e movimentá-la, faremos com que currentPiece volte a ser nulo, incrementamos o score do jogador e por fim, destruímos o objeto da grade (Para evitar de clicar nela novamente e melhorar a performance do jogo, já que não iremos mais usar esse script).

Caso a peça corrente não tenha como 'destino' essa parte da grade, apenas faça com que ela "volte" para seu local de origem fazendo com que "cancelPiece" fique true.
O script deve estar assim:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B36


Salve o script e adicione-o no prefab "Grid". Teste o jogo e veja que agora é possível encaixar as peças:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B37

Verificando final de jogo:
Para verificar o final do jogo é bem simples: Primeiro crie um Canvas com um text ancorado e devidamente dimensionado com o texto "Congratulations":

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B38

E por padrão deixe-o desativado.
Agora vá para o script "GameManager" e crie uma variável pública do tipo "Text" chamada "text" (referencie a biblioteca "UI" dentro do script!)
Agora dentro do Update crie uma validação se currentScore for igual a totalScore, o gameObject de "text" irá ser ativado:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B39

Agora anexe esse script no objeto "GameManager" e faça com que o text do canvas seja armazenado na variável "text" desse script.
Teste o jogo e tente montar o quebra-cabeças: Perceba que quando você o completa o jogo "se encerra" e a mensagem de congratulações aparece na tela:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B40

Mostrando imagem original:
Outro sistema que podemos fazer é o de mostrar a imagem como ela é quando montada, ao clicar num botão.
É muito fácil criar esse sistema, basta criar uma imagem dentro do Canvas e a posicionar, ancorar e redimensionar da forma que achar melhor:


[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B41

Desativa a imagem também.
Agora vá para o script "CropTextures" crie uma variável pública do tipo Image chamada "img" (referencie a biblioteca UI) e no método "StartComponents" faça com que ela receba a textura da imagem do quebra-cabeças de acordo com sourceTexture, igual já fizemos anteriormente:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B43

Salve o script e anexe a imagem na variável "img"do script do GameManager.
Crie agora um Button dentro do Canvas com o Texto "View Image" e o ancore e posicione da forma que achar melhor.
Crie um novo C# script chamado "ButtonScript" e crie uma variável pública do tipo "Image" chamada "img" e uma variável private booleana chamada "isEnabled" iniciando em "false".
Agora defina um método público sem retorno chamado "ClickViewImage" e faça com que a variável "isEnabled" receba seu oposto. Após isso, faça com que a "img" seja ativada se isEnabled for true e desativada se isEnabled for false:

[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B44

Salve o script e o adicione no botão dentro do Canvas, anexando a imagem desativada dentro da variável "img". Dentro do evento "OnClick" clique no sinal de mais (+)  e em "None" adicione o próprio objeto do botão, e após isso em "No Function" vá em "ButtonScript >> ClickViewImage" para esse método seja disparado quando clicarmos no botão.
Teste o jogo e clique no button: Perceba que quando faz isso, a imagem original do quebra-cabeças aparece no canto da tela, e ao clicar novamente no button, ela é desativada:


[TUTORIAL] Desenvolvendo um jogo de quebra-cabeças Untitled%2B46

Isso pode auxiliar o jogador a ver como a imagem é de fato para poder montar o quebra-cabeças.

Final:
E chegamos (ufa) a mais um final de tutorial por aqui! A sugestão que eu ainda tenho para melhorar o jogo é criar um menu que possibilite o jogador a escolher com qual imagem ele quer jogar(uma gama de opções de imagens, ao invés de uma) e a dificuldade através da escolha da grade.
Esse tutorial foi muito trabalhoso de fazer (acho que foi o mais de todos) portanto, se gostou e se te ajudou em algo (mesmo se não for com relação ao desenvolvimento de um quebra-cabeças, mas ao aprender sobre algum comando que você não sabia) deixe o seu feedback, isso é muito importante para me motivar a continuar postando tutoriais e aulas aqui.
Por fim, caso queira, aqui está o link do código fonte no gitHub: https://github.com/mayleone1994/PuzzleGame

Até mais!
Muito bom MayLeone, eu estava procurando algo do tipo esses dias em vídeo e não encontrei nada, ao menos bem explicado não, e geralmente quando encontro é em inglês e as vezes dificulta um pouco, realmente seria uma boa pra você o que o Marcos disse logo acima, criar um curso e mandar pra udemy, talento e conhecimento para criar um conteúdo de qualidade você tem, bom é isso agradeço pelo tutorial já me deu mais uma ideia kkkk e sucesso aí, vlw!!!  Vitoria
Diego Felix
Diego Felix
Avançado
Avançado

Masculino PONTOS : 3239
REPUTAÇÃO : 84
Idade : 34
Áreas de atuação : Modelagem 3D, Roteirista.
Respeito as regras : [TUTORIAL] Desenvolvendo um jogo de quebra-cabeças WvDYdlf

https://www.blogger.com/blogger.g?blogID=2315682099830977662#ove

Ir para o topo Ir para baixo

Ir para o topo

- Tópicos semelhantes

 
Permissões neste sub-fórum
Não podes responder a tópicos