Criando um aplicativo de coloração no Unity3D

imagem

Essa história começou em uma noite gelada de primavera, quando surgiu a pergunta: existe uma maneira de determinar o grau de preenchimento de uma forma geométrica arbitrária com tinta (ou seja, em que porcentagem ela é atualmente pintada)? Sim, para que não apenas diminua a velocidade, mas voe a 60 fps nos dispositivos móveis mais fracos.

Para aqueles que não entenderam imediatamente o que eu estava falando, explicarei: uma abordagem raster é possível para o problema, assim como ... não uma abordagem raster.

No primeiro caso, tudo é simples, o tópico inundação e algoritmos relacionados foram estudados e implementados com êxito no YP para todos os gostos. Há uma matriz de pixels a serem preenchidos, suas bordas. Contamos o número de pontos inundados, dividimos pelo número total e voila - temos a porcentagem estimada na saída. Mas - com um grande número de pixels (e ppi em dispositivos modernos, você mesmo sabe qual deles), além disso - se houver muitas dessas figuras, encontramos vários cálculos em cada quadro que aquecem agradavelmente o dispositivo, mas não a alma.

De qualquer forma, trabalhar com o raster parecia antidesportivo. O olhar estava voltado para aterros onipotentes. Várias horas emocionantes de codificação relaxada e persistente provaram a hipótese: você pode usar algo como “ cor de vértice ” - cor de vértice.

Um pouco sobre a cor dos vértices
O canal de informações adicionais nativas disponíveis na estrutura de dados do triângulo é o mesmo mesh.colors . Teoricamente, ele pode ser usado para qualquer finalidade, dependendo do que está escrito no shader, mas nesse caso, o byte estimado armazenará exatamente o valor atual do preenchimento de cores para cada vértice. Seu sombreador o usa ao renderizar e, com o Unity, um material, você pode criar um número ilimitado de malhas multicoloridas com um material para todos. O mais interessante é que os valores das cores dos vértices são interpolados por hardware entre si, o que permite fazer gradientes de luz.

Acho que vale a pena mencionar por que era necessária a notória porcentagem de sombreamento, com a qual o artigo começou. A idéia principal da aplicação de coloração foi a seguinte: a figura final consiste em um conjunto de polígonos. O aplicativo irá sequencialmente e automaticamente desativar o elemento usuário por elemento . Assim, até que você termine de pintar uma peça até o fim, você não passará para a próxima. Essa decisão me pareceu muito elegante, atraente e, à luz do domínio global dos corantes de "pixel" nas histórias, também era nova.

Primeiros passos


Obviamente, para criar uma coloração completa, era necessário criar muitas soluções intrigantes. Em primeiro lugar, eu queria que, por toda a natureza poligonal da aplicação, a coloração fosse percebida como a mais raster, ou seja, a tinta deveria se espalhar sob o dedo e ter uma aparência mais ou menos realista. O requisito inicial para o desempenho máximo não desapareceu em lugar nenhum e continuou pendurando uma formidável nuvem cumulus em todo o processo.

O primeiro passo foi fazer o mosaico humano (quebrar um grande polígono que consiste em um conjunto de triângulos em um grupo estocástico de pequenos triângulos). De fato, se obtivermos uma matriz de vértices e escrevermos a cor do vértice ao preenchermos, podemos determinar por uma passagem normal pela matriz se a figura está completamente preenchida e que outras peças permanecem sem pintura - semelhante ao algoritmo de pixel, mas com muito mais liberdade .

imagem

Então começou uma emocionante jornada ao mundo dos shaders. Como você entende, não consigo descobrir completamente todos os achados e segredos, mas direi que, ao interagir com o mapa de ruído e os raios Unity da velha escola que emitem dos meus dedos, o efeito do pincel foi alcançado, e mesmo com a propagação de tinta ao longo dos triângulos adjacentes ao dedo. O uso da cor de vértice tornou possível dispensar um material Unity em absolutamente todas as partes componentes da figura e, portanto, as chamadas no programa finalizado não excedem 5-7 (dependendo da presença de menus e partículas).

O golpe é feito pelo habitual Unity Line Renderer, que traiçoeiramente traiçoeira algumas figuras, movendo-se e mostrando falhas nas articulações. Isso não pôde ser derrotado; portanto, a tarefa prioritária é reescrever o componente do zero. Uma impressão digital também é um Trail Renderer padrão, mas seu shader usa uma verificação z para que os oligoelementos não se sobreponham, criando artefatos feios. A textura "quadriculado" do fundo ajuda, entre outras coisas, a avaliar o tamanho do elemento que está sendo pintado : quanto maior, menor o tamanho das células.

imagem

Funcionalidade não esperada


Durante o teste, muitas vezes, em algum ponto nos cantos da figura, havia picos vazios, o que era difícil de determinar visualmente. Apesar do fato de o gatilho para alternar para o próximo elemento funcionar quando o nível de preenchimento era de 97%, a situação é “ o que fazer a seguir? »- com um grau de ocupação de 90% a 97% - surgiam com frequência e confundiam usuários (que basicamente não tinham mais de 12 anos). Eu não queria definir um gatilho de menos de 97%, porque então apareceu o efeito " ainda não havia terminado, mas já havia saltado ".

Então, com relutância, conheci Madame Clusterization . Imagine: um polígono, um monte de pontos dentro, existem alguns "especiais", às vezes separadamente, às vezes em grupos. É necessário encontrar e designar o maior "grupo". Este é um problema matemático comum. Nenhum dos algoritmos tradicionais que encontrei surgiu por várias razões, eu tive que fazer o meu próprio. Hackear o hack, mas funcionou - e as áreas não pintadas começaram a se destacar em um belo círculo dinâmico. Para otimizar, esse algoritmo funciona a cada 3 segundos e somente depois que o usuário fica intrigado em levantar o dedo da tela no estilo "o que fazer a seguir". Parece bastante orgânico.

imagem

Após um brainstorming, criar uma “linha de coloração” variada de acordo com os requisitos dos testadores - ou seja, dar ao usuário a oportunidade de escolher em que sequência ele deseja colorir os elementos - era questão de uma noite. Tudo o que você precisa é determinar os centros geométricos de cada malha e construí-los conforme necessário: da esquerda para a direita, de cima para baixo, etc. Para maior clareza, as partículas foram implementadas contra o fundo, que mostram a direção da fila.

Ilustração de fila
imagem

A fila padrão é mostrada aqui (como o artista pretendeu). Se você ativar o modo " passo a passo ", clicando em um dos botões abaixo, a fila de cores será alterada e as partículas viajarão na direção indicada.

UX e interface do usuário


Eu geralmente gosto da idéia de automatismo controlado em aplicativos e, portanto, cada elemento é centralizado e dimensionado para que possa ser pintado com o dedo sem precisar rolar a tela . A desvantagem dessa abordagem é que nem sempre é claro qual parte da figura está agora na tela. Como se viu, os usuários até gostam de um desafio tão pequeno, pois ele treina memória de curto prazo e correlação de informações - você precisa ter em mente o quadro geral. Bem, existem duas maneiras de chegar à "vista aérea da figura" - com um gesto de pinça ou pressionando o botão de zoom.

imagem

Seguindo os preceitos das diretrizes de interface da Apple , decidiu-se reduzir ao mínimo o número de botões na tela. Além do botão de aumentar / diminuir o zoom e do óbvio botão de saída no menu, há também uma chamada na paleta - você pode pintar com a cor "padrão" definida pelo artista ou à sua escolha.

Além disso, no modo “olho de pássaro”, você pode alterar o gradiente de fundo (cada clique é gerado aleatoriamente) ou entrar no modo de “repintar”, que permite corrigir um elemento já pintado. Sim, tive que ocultar essa funcionalidade, mas é justificada - para todos os testes, ninguém nunca perguntou como fazê-lo.

Sobre a paleta


A paleta em si foi refeita duas vezes. No começo, simplesmente coloquei um certo número de quadrados com cores na tela, mas os usuários pediram mais cores. Eu não queria rolar na interface e, portanto, o esquema "tonalidade da cor" apareceu, ou seja, primeiro o usuário seleciona a cor base pressionando e depois uma de suas tonalidades. A paleta é removida com um botão ou deslizando o dedo para baixo. Além disso, quando aparece na tela, o espaço de trabalho do artista é reduzido em 1/3, o que exige um "redimensionamento" da figura atual para o tamanho alterado da janela de exibição.

imagem

Para doce


O principal elo que faltava em todo o cenário era a recompensa - um tipo de recompensa psicológica visual que o usuário recebe após a conclusão do processo de coloração. A ideia foi espionada na superfície: a figura foi pintada automaticamente e de novo, no modo acelerado, e exatamente como o usuário - em outras palavras, o intervalo de tempo de 15 a 20 segundos . Isso é implementado gravando a sequência na qual o usuário tocou nos vértices das figuras e, posteriormente, reproduzindo os dados no mecanismo de desenho com atrasos (via corotinas). Cada malha é duplicada várias vezes para obter os efeitos de "manifestação" e "atenuação".

imagem

Obviamente, o intervalo de tempo durante a reprodução é gravado no arquivo de vídeo e, após a extravagância visual, o usuário é solicitado a salvar / compartilhar uma obra-prima recém-criada. Felizmente, na primavera, um plug-in apareceu na Asset Store que permite capturar vídeos de várias plataformas na tela (depois de algumas configurações), porque escrever essa ferramenta do zero vai muito além das minhas habilidades de programação, mas em geral sou designer .

Em vez de uma conclusão
Nestas mil palavras atribuídas por mim até a primeira obra. Nas partes a seguir, está planejado contar sobre as batalhas heróicas com a Unity UI ao desenvolver a segunda parte do aplicativo - o menu para selecionar imagens, além de contar os solavancos nos negócios difíceis da ASO.

Source: https://habr.com/ru/post/pt412971/


All Articles