Estrutura de Temas e Vinculação de Dados – MRTK3

Boas-vindas à Estrutura de Temas e Associação de Dados MRTK3. Essa estrutura foi projetada para facilitar a criação de elementos visuais que podem ser preenchidos e atualizados de forma dinâmica no runtime por dados fornecidos de uma ou mais fontes de dados.

O que é a associação de dados

A associação de dados é o processo que estabelece uma conexão entre a UX (exibição) de um aplicativo e os dados que estão sendo apresentados (modelo). Se a associação possui configurações corretas e os dados fornecem notificações adequadas, quando os dados mudam de valor, os elementos que são associados a dados refletem as mudanças automaticamente.

Estruturas de associação de dados populares:

  • Delphi
  • Windows Presentation Framework (WPF .NET)
  • Windows Forms
  • Angular
  • Backbond
  • Associações do JavaFX

Diagrama de bloco de associação de dados da Estrutura de Apresentação do Windows

Databinding Windows Presentation Framework (WPF) Para obter mais informações, consulte visão geral da associação de dados - WPF.NET


Diagrama de bloco equivalente do MRTK

Diagrama de bloco equivalente do MRTK


Objetivos de design

  • Multiplataforma – implante em qualquer lugar
  • Suporte a qualquer estrutura organizacional e origem de fontes de dados
  • Fácil de integrar em bases de código existentes ou greenfield
  • Amigável ao designer e ao desenvolvedor
  • Pode ser habilitado/desabilitado a qualquer momento durante o ciclo de vida do aplicativo
  • Suporte a cenários empresariais do mundo real – DBs de back-end, modelos pré-fabricados de UX complexos
  • Fácil de aplicar a componentes de UX não MRTK existentes e novos elementos visuais
  • Associe qualquer tipo de dados, incluindo sprites, imagens, materiais, animações e clipes de áudio
  • Fácil de aprimorar recursos sem tocar na base de código existente
  • Uso eficiente de CPU, RAM, GC e tempo de quadro
  • Fácil integração a uma ampla variedade de fontes de dados locais ou de back-end
  • Qualquer combinação simultânea de fontes de dados inseridas, de estado de tempo de execução e de back-end
  • Manipule coleções com eficiência de qualquer tamanho para apresentação de lista
  • Temas combinados e associação de dados para elementos de dados dinâmicos temáticos
  • Valide e manipule dados variáveis de forma aberta antes da apresentação
  • Dependências mínimas em outras funcionalidades do MRTK
  • Compatível com MRTK v2 e MRTK3
  • Fácil para marcar como white label e/ou aplicar identidade visual a ativos de ações com esforço mínimo

Principais recursos

  • As fontes de dados abertas suportam qualquer estratégia de dados persistente, remota ou de RAM.
  • Os consumidores de dados abertos suportam qualquer associação de UX e necessidades de temas.
  • A descoberta automática entre fontes de dados e consumidores simplifica a conexão.
  • Configuração automática opcional de um perfil de associação
  • O modelo de dados desacoplado e a exibição suportam os padrões MVC e MVVM.
  • Coleções virtualizadas com navegação por meio de paginação e rolagem.
  • Pré-busca preditiva de itens de coleção para navegação de lista suave.
  • Objetos de coleção podem ser agrupados e reutilizados para reduzir o GC.
  • É possível mapear entre diferenças nos dados e exibir namespaces de keypath.

Funcionalidade atual

1. Visualizar dados variáveis por meio de consumidores de dados

Com suporte no momento:

  • Texto TextMeshPro e TextMesh
  • Folhas de estilos de texto (para temas e acessibilidade)
  • Textura sprite
  • Gatilho booliano
  • Textura em quadrupleto
  • Ícones de fonte
  • Coleções: listas de tamanho arbitrário contendo pré-fabricados preenchidos com os dados variáveis
  • Qualquer outro consumidor que suporte a interface IDataConsumer (diretamente ou por meio de derivações de classes base)

2. Fornecer dados variáveis por meio de uma variedade de fontes de dados:

  • Texto JSON (diretamente ou por meio de busca de URL)
  • Dicionário de elementos de dados variáveis
  • Objeto – Dados estruturados baseados em nó
  • Reflexo de qualquer objeto C#
  • Dados alterados programaticamente
  • Qualquer outro método que suporte a interface IDataSource

3. Listar o posicionador de item para gerenciar a manifestação visual de uma lista

4. Listar paginação, rolagem e virtualização

  • Os dados só são buscados quando visíveis ou em processo
  • Suporta conjuntos de dados de back-end arbitrariamente grandes
  • A busca é balanceada por carga em vários quadros

5. Listar o pool de pré-fabricados

  • Os pré-fabricados são reutilizados e repovoados para reduzir o GC e o tempo de instanciação.

6. Aplicar temas de forma dinâmica aos elementos no runtime


Funcionalidade no roteiro

Além do que já está disponível, as principais prioridades para mais funcionalidades incluem:

1. Pipelines do Manipulador de Dados

  • Conversão entre os valores do lado dos dados e do lado da exibição
  • Localização (integração perfeita com a localização do Unity)
  • Formatação
  • Validação

2. Pré-busca de item de lista preditiva para rolagem/paginação mais rápida/suave

3. Mais Consumidores de Dados

  • Definir qualquer propriedade pública em um Componente
  • Definir o estado de ativação/desativação da caixa de seleção
  • Definir valor do controle deslizante
  • Definir um botão de opção em um grupo
  • Propriedades materiais individuais, como a cor do conjunto

4. Temas

  • Veja os temas aplicados no Editor mesmo quando o aplicativo não estiver em execução
  • Atualize os pré-fabricados para refletir um tema aplicado, de modo a se tornar o tema padrão
  • Herança de tema/estilo

Terminologia

  • Fonte de dados – qualquer provedor de dados, seja o estado de runtime, persistido localmente ou buscado de um servidor.
  • Provedor de Fonte de Dados – Um MonoBehaviour simples que fornece acesso a uma fonte de dados que pode não ser exposta no grafo de cena do Unity.
  • Tipo de Fonte de Dados – Um nome exclusivo atribuído à Fonte de Dados, de modo que os Consumidores de Dados possam especificar suas fontes de dados desejadas pelo nome.
  • Consumidor de Dados – Qualquer consumidor de dados que deseje agir sobre alterações de dados, normalmente um elemento visual, mas que não é necessário. Por exemplo, sua finalidade pode ser disparar ações com base em alterações de valor de dados.
  • Controlador de Dados – Um mecanismo para invocar uma ação com o valor associado a dados atualmente associado fornecido como um parâmetro.
  • Keypath – Um seletor de dados que faz referência a um objeto específico em uma Fonte de Dados. Como implementado atualmente, o formato keypath é modelado de acessadores de dados JSON para decifrar qualquer combinação aninhada de mapas, listas e elementos atômicos.
  • Keypath local – um keypath do lado do consumidor de dados que pode ser incorporado de forma permanente a um pré-fabricado reutilizável. Por meio de uma resolução de entidades de coleção e Mapeadores do Keypath, isso será convertido automaticamente em um keypath totalmente resolvido para um item específico em uma coleção. Quando não associados a uma coleção, eles podem ser mapeados diretamente para uma referência na fonte de dados ou podem primeiro ser modificados por meio de um Mapeador do Keypath.
  • Keypath totalmente resolvido – um keypath completo e absoluto que mapeia para um objeto específico em uma Fonte de Dados. Para itens em uma coleção, essa é uma combinação do keypath totalmente resolvido para uma entidade de coleção e um keypath relativo (local) para um elemento de dados dessa entidade de coleção.

  • Mapeador do Keypath – mapeador de namespace opcional entre keypaths locais e nomes de campo da Fonte de Dados (por exemplo, "link" <–> "URL").

  • Tema – Uma fonte de dados que fornece um conjunto de vários ativos e estilos necessários para alcançar uma estética visual específica.

  • Posicionador do item – Um companheiro do DataConsumerCollection responsável por colocar itens visíveis em uma cena.

  • Pool de Objetos de Dados – Pré-fabricados instanciados e em espera prontos para serem preenchidos com dados para navegação de lista de baixo GC.

  • Listar Virtualização – Capacidade de popular, apresentar e navegar por listas de tamanho arbitrariamente grande.

  • Pré-busca preditiva – Pré-busca de dados e preenchimento de pré-fabricados de coleção para itens que podem ser vistos em breve por meio da rolagem/paginação.

  • Prefetch preditivo – Pré-busca de dados e preenchimento de pré-fabricados de coleção para itens que podem ser vistos em breve por meio da rolagem/paginação.

Conceitos Principais

fonte de dados

Uma fonte de dados é qualquer conjunto gerenciado de dados de tipos arbitrários e complexidade que podem ser usados para preencher exibições de dados por meio de consumidores de dados. Os dados gerenciados por uma fonte de dados podem ser estáticos ou dinâmicos. Todas as alterações nos itens de dados serão relatadas a todos os consumidores de dados que se registraram para receber notificações de alteração.

Provedor de fonte de dados

Uma interface simples que tem um único método para recuperar uma fonte de dados. Isso foi projetado para permitir que um componente de script MonoBehavior seja descoberto automaticamente na hierarquia de objetos do jogo por componentes de consumidor de dados. Não é necessário implementar uma fonte de dados diretamente no próprio objeto do jogo. Isso é útil quando um MonoBehaviour existente deve derivar de outra classe e várias heranças impedem a derivação de DataSourceGOBase. Ele também permite que mais código não tenha dependências do Unity.

Singleton do Provedor de Fonte de Dados

O MonoBehaviour DataSourceProviderSingleton possibilita especificar uma fonte de dados que pode ser descoberta automaticamente mesmo que não esteja na mesma hierarquia GameObject que os DataConsumers que desejam escutá-la. Basta colocar DataSourceProviderSingleton em qualquer lugar na cena e preencher a propriedade Data Sources com quaisquer fontes de dados que devem ser descobertas pelos consumidores de dados. Como alternativa, os consumidores de dados orientarão seus pais a encontrar uma fonte de dados apropriada, o que implica que você pode colocar uma fonte de dados que forneça os dados desejados em qualquer lugar da cadeia responsável desses consumidores de dados.

Caminho da chave (cadeia de caracteres)

Um caminho da chave é o mecanismo para identificar de forma exclusiva qualquer informação em uma fonte de dados.

Embora um caminho da chave possa ser qualquer identificador exclusivo por item de dados, todas as implementações atuais usam um especificador legível do usuário lógico que indica a posição de navegação dos dados de interesse em relação a todo o conjunto de dados estruturados. Ele é modelado no conceito de listas, dicionários e primitivos do Javascript. Os caminhos de chave são instruções Javascript sintaticamente corretas para acessar dados que podem ser representados no JSON. A vantagem dessa abordagem é que ela se correlaciona bem com ambos o JSON e o XML. Esses são os dois meios mais prevalentes de transferir informações de serviços de back-end.

Exemplo de caminhos de chave:

  • temperatura
  • contacts[10].firstName
  • contatos
  • contacts[10].addresses[3].city
  • [10].title
  • kingdom.animal.mammal.aardvark.diet.foodtypes.termites

Considerando que um caminho de chave é uma cadeia de caracteres arbitrária sem taxonomia necessária, os especificadores de dados reais podem ser qualquer método de descrição de quais dados recuperar. O XPath do XML é um exemplo de um esquema de caminho de chave viável que funcionaria com fontes de dados. Desde que os principais caminhos fornecidos pelo consumidor de dados sejam consistentes com os caminhos de chave esperados pela fonte de dados, tudo funcionará. Além disso, Mapeadores de Caminho de Chave podem ser implementados para traduzir entre esquemas diferentes.

Como resolver um caminho de chave

Resolver um caminho de chave significa combinar dois keypaths:

  1. Um keypath absoluto que descreve como acessar um subconjunto específico de um conjunto de dados maior, como uma entrada em uma lista de muitas entradas.
  2. Um keypath parcial (relativo) que representa uma referência específica nessa lista ou entrada de mapa.

Isso possibilita tratar um subconjunto de dados de maneira que não importe em qual lugar de uma hierarquia de conjunto de dados maior, ele realmente exista. O uso mais importante desse recurso é descrever os dados de uma única entrada em uma lista sem se preocupar com qual entrada nessa lista a instância atual está referenciando.

Como um Caminho de chave "totalmente resolvido" é sempre gerado e consumido por um DataSource e nunca, ou pelo menos raramente, deve ser modificado por um DataConsumer ou outro componente externo, ele pode ter qualquer estrutura que faça sentido para o DataSource. Por exemplo, se um pré-fabricado mostrar uma entrada de lista para uma foto e o título, data tirada e outros atributos dela, o caminho de chave local no pré-fabricado poderá ter esta aparência:

  • "photo_url"
  • "title"
  • "date_taken"
  • "description"

Os caminhos de chave totalmente resolvidos para uma entrada de pré-fabricado em uma lista podem ter esta aparência:

  • "f3cb1906-d8b3-489d-9f74-725e5542b55d/photo_url"
  • "f3cb1906-d8b3-489d-9f74-725e5542b55d/title"
  • "f3cb1906-d8b3-489d-9f74-725e5542b55d/date_taken"
  • "f3cb1906-d8b3-489d-9f74-725e5542b55d/description"

Mapeador de caminho de chave (IDataKeyPathMapper)

Um Mapeador de Caminho de Chave permite que fontes de dados e consumidores de dados usem namespaces e convenções diferentes para caminhos de chave e ainda trabalhem juntos.

Um pré-fabricado para um elemento comumente usado, como uma imagem fixa para mostrar informações de contato de uma pessoa, pode conter campos variáveis gerenciados por consumidores de dados. Para tornar isso possível, o identificador usado para qualquer aspecto variável do pré-fabricado precisa de uma forma de mapear para o identificador para a referência correta na fonte de dados que, em cada uso do pré-fabricado, determinará o conteúdo desse elemento variável. O Mapeador de Caminho de Chave possibilita isso.

O pré-fabricado pode ser usado com diferentes fontes de dados em que os dados são armazenados em uma estrutura organizacional diferente e usa nomes de campo. Para usar um modelo de pré-fabricado com cada fonte de dados, um Mapeador de Caminho de Chave pode resolver quaisquer diferenças na forma como os dados são organizados.

Consumidor de Dados (IDataConsumer)

Um objeto que sabe como consumir informações que estão sendo gerenciadas por uma fonte de dados e usar esses dados para preencher exibições de dados.

Os consumidores de dados podem se registrar com uma fonte de dados para serem notificados de quaisquer alterações em um item de dados existente em um caminho de chave especificado em um conjunto de dados. Sempre que os dados especificados forem alterados (ou houver a suspeita de terem sido alterados), os Consumidores de Dados serão notificados.

Coleta de consumidores de dados

Uma Coleção de Consumidores de dados tem a capacidade adicional de gerenciar uma lista de itens semelhantes. Essa lista pode ser todo o conjunto de dados gerenciado por uma fonte de dados ou apenas um subconjunto. Normalmente, os dados de cada item na lista contêm tipos semelhantes de informações, mas isso não é um requisito. Fontes de dados e consumidores de dados podem dar suporte a listas aninhadas, como uma lista de palavras-chave associadas a cada foto em uma lista de fotos associadas a cada pessoa em uma lista de contatos. O caminho de chave para as palavras-chave seria relativo à foto, e o caminho de chave para as fotos seria relativo à pessoa, e o caminho-chave da pessoa seria relativo à lista responsável mais próxima ou à raiz do conjunto de dados.

Ao processar coleções, o keypath resolvido correto para a entrada específica na coleção é atribuído a cada consumidor de dados encontrado no pré-fabricado que é instanciado para cada item da coleção. Em seguida, isso é usado para resolver completamente o caminho da chave para qualquer dado de exibição relativo (local) dentro desse pré-fabricado.

Posicionador de Item de Coleta de Dados

Um consumidor de dados de coleção precisa de um meio para popular experiências do usuário com listas de elementos visuais repetíveis, como o que pode ser encontrado em uma lista rolável de produtos, fotos ou contatos. Isso é feito atribuindo um posicionador de item ao consumidor de dados de coleta. Esse posicionador de itens é a lógica que sabe como solicitar itens de lista, aceitar pré-fabricados que foram preenchidos com os dados variáveis e, em seguida, apresentá-los ao usuário, normalmente inserindo-os em uma lista gerenciada por um componente de layout de UX para listas.

Temas

O tema usa todo o encanamento de fontes de dados e consumidores de dados. É possível criar um tema em qualquer hierarquia de GameObjects se eles são estáticos ou são dinamicamente associados a outras fontes de dados. Isso permite que a associação de dados e o tema sejam aplicados em combinação. É possível até mesmo criar o tema dos dados provenientes de outra fonte de dados.

Bloquear diagrama e fluxo de dados

Fluxo de dados de temas do MRTK

Temas do MRTK

O tema é a capacidade de alterar a estética visual de vários elementos de UX ao mesmo tempo. Normalmente, todos os dados necessários para especificar um tema são fornecidos por uma única Fonte de Dados, como um Objeto Passível de Script. Também é possível que os dados de temas sejam fornecidos conforme necessário ou divididos em grupos lógicos com base na finalidade deles.

Temas do MRTK3

Temas do MRTK3 combinados com associação de dados

A associação de dados e o tema podem coexistir para um único elemento UX. Qualquer elemento UX individual pode ser simultaneamente temático e associado a dados. Nesse cenário, o fluxo típico é que a referência proveniente de um DataSource seja usada para derivar o keypath de tema correto. Esse keypath é usado para recuperar um objeto do tema Fonte de Dados, normalmente um perfil ScriptableObject, mas potencialmente qualquer fonte de dados que possa resolver um keypath.

Para simplificar a configuração de temas e associação de dados, é possível criar perfis de associação que são processados por um BindingConfigurator no momento da instanciação.

  • Um BindingConfigurator processa um Perfil de Associação para determinar os ativos dentro de um pré-fabricado que devem ser temáticos e associa elementos de dados associados e elementos temáticos a Keypaths. Em seguida, ele também adiciona o DataConsumers apropriado para associar esses elementos visuais aos seletores de Keypaths corretos que serão usados para referenciar dados específicos em um ou mais DataSources, que normalmente são externos ao próprio pré-fabricado.
  • Os dados do tema são fornecidos por um DataSource que contém dados para cada Keypath identificado no Perfil de Associação.
  • Um script auxiliar ThemeProvider facilita o uso de um ScriptableObject como um DataSource para temas.
  • O tema padrão de UX é fornecido pelo MRTK_UX_ThemeProfileScriptableObject que está associado a um DataSourceReflection no ThemeProvider.

Diagrama de fluxo datasource do perfil de tema

Fonte de dados inserida

Uma fonte de dados inserida é apropriada em duas situações:

  1. Quando cada instância do pré-fabricado pode ter configurações de tema diferentes e requer sua própria fonte de dados separada.
  2. Quando todas as instâncias desse pré-fabricado são regidas por um perfil de tema persistente comum (por exemplo, ScriptableObject) e que podem ser fornecidas por meio da fonte de dados inserida para que não haja dependências externas a serem estabelecidas.

DataSourceReflection

Isso pode transformar qualquer struct ou classe C# em um DataSource usando reflexão para mapear caminhos de chave para campos, propriedades, classes aninhadas, matrizes, listas ou dicionários. Ele pode ser associado a um ScriptableObject do Unity ou a qualquer outro struct C# ou classe em que os dados do tema existam. O objeto instanciado que contém os dados pode ser injetado por dependência e alterado em runtime.

  1. Objeto Passível de Script: útil para temas estáticos compartilhados em muitos pré-fabricados.
  2. Struct ou classe C# não persistente: útil para modificações dinâmicas de tempo de execução do tema.

DataSourceJson

Se os dados existirem como texto json, isso gerenciará o mapeamento de keypaths para o DOM json. Os ativos binários podem ser recuperados dos recursos do Unity, StreamingAssets ou até mesmo de uma URL buscada.

DataSourceDictionary

Essa é uma opção simples quando uma lista puramente simples é boa o suficiente para atender à necessidade e para uma prototipagem rápida. Todos os ativos de temas têm suporte, incluindo texto, ativos do Unity (por exemplo, Materiais, Sprites, Imagens), Recursos, StreamingAssets ou até mesmo busca externa por meio de uma URL.

Personalizado

Qualquer fonte de dados personalizada que implementa a interface direta IDataSource ou deriva deDataSourceBase ou DataSourceGOBase pode ser usada para atender às necessidades personalizadas.

Temas de UXComponents

Os controles UXComponents padrão fornecidos no pacote UXComponents estão configurados para dar suporte a temas. Eles estão desligados por padrão, mas é fácil habilitá-los.

Cada controle, normalmente no GameObject mais alto do pré-fabricado raiz, tem um script chamado UXBindingConfigurator. Esse script, se habilitado, efetuará pull dos scripts de associação de dados necessários para ativar o tema. Certifique-se de importar o pacote de Associação de Dados e Temas também.

Observação sobre TextMeshPro StyleSheets: atualmente não é possível usar StyleSheets para estilizar o estilo TextMeshPro Normal. Qualquer outro estilo incluído na Folha de Estilos Padrão do TextMeshPro pode ser usado. Os exemplos usam Corpo para contornar essa limitação.

DataSourceThemeProvider

O MonoBehaviour DataSourceThemeProvider pode ser usado para tornar facilmente um ScriptableObject contendo todas as referências a todos os ativos de temas que funcionam como uma fonte de dados. Isso é demonstrado na cena UXThemingExample.

ThemeSelector

O MonoBehaviour ThemeSelector possibilita especificar e alternar facilmente entre vários perfis ScriptableObject. Um exemplo disso seria facilitar a alternância entre um tema "Escuro" e "Claro". Adicione o ScriptableObjects ao Theme Profiles, normalmente em tempo de design. Em seguida, no tempo de execução, altere a propriedade Current Theme para alterar o tema.

Temas do consumidor de dados

O tema é realizado pelos Consumidores de Dados, particularmente os que herdam das classes DataConsumerThemeBase<T>, DataConsumerTextStyle e DataConsumer personalizadas que qualquer desenvolvedor pode implementar para aprimorar o suporte a temas.

A classe base DataConsumerThemeBase<T> fornece lógica para usar um inteiro ou uma referência de chave de uma fonte de dados primária para pesquisar o valor final desejado de um banco de dados de tema secundário. Isso é feito mapeando os dados de entrada para um keypath de tema e, em seguida, usando esse keypath de tema para recuperar o valor final. Isso permite que qualquer elemento seja associado a dados e temático ao mesmo tempo. Por exemplo, imagine um campo de status em um banco de dados com status de Novo, Iniciado e Concluído representado pelos valores 0, 1 e 2. Cada um deles pode ser representado por um ícone sprite. Para a vinculação de dados, um valor de 0 a 2 é usado para pesquisar o sprite desejado. Com temas e vinculação de dados, o perfil de tema aponta para a lista correta de três sprites no perfil de tema e, em seguida, o valor de 0 a 2 é usado para selecionar o sprite correto nessa lista. Isso permite que o estilo desses ícones seja diferente por tema.

Quando o tema do runtime e a vinculação dinâmica de dados são usados juntos, uma classe DataConsumerThemeHelper pode ser especificada em qualquer classe derivada DataConsumerThemeBase para notificar quando um tema foi alterado.

A troca de temas no runtime é realizada substituindo os dados na fonte de dados do tema por um novo conjunto de dados disposto na mesma topologia do modelo de objeto de dados. DataSourceReflection pode ser usado com ScriptableObjects em que cada perfil representa um tema. Para todos os controles de UX do MRTK Core, o perfil de tema é um ScriptableObject chamado MRTK_UXComponents_ThemeProfile. O script auxiliar ThemeProvider.cs facilita o uso deste ou de qualquer perfil ScriptableObject como fonte de dados.

O método de aplicação de um tema a dados dinâmicos pode ser detectado automaticamente na maioria dos casos ou pode ser especificado explicitamente.

Quando a referência é usada para selecionar o item correto na fonte de dados do tema, o processo é:

  • uma referência da fonte de dados primária é usada para selecionar ou construir o keypath de tema correto
  • o keypath de tema é usado para recuperar um valor da fonte de dados do tema especificada no DataConsumerThemeHelper
  • o valor do tema recuperado é analisado para detectar automaticamente o método de recuperação correto
  • o item de dados final do tipo correto (por exemplo. Material, Sprite ou Imagem) é recuperado usando o método detectado automaticamente.

Tipos de dados

O tipo de dados esperado da referência usada para recuperar o objeto desejado pode ser um dos seguintes:

Tipo de Dados Descrição
AutoDetect A referência é analisada e a interpretação correta é detectada automaticamente. Consulte "Tipo de Dados de Detecção Automática" abaixo para obter mais informações.
DirectValue Espera-se que a referência seja do tipo T desejado (por exemplo, Material, Sprite, Imagem) e usada diretamente.
DirectLookup Um índice integral ou uma chave de cadeia de caracteres usada para pesquisar o valor desejado de uma tabela de pesquisa local.
StaticThemedValue O objeto temático estático do tipo correto é recuperado da fonte de dados do tema no keypath de tema especificado.
ThemeKeypathLookup Um índice integral ou uma chave de cadeia de caracteres é usado para pesquisar o keypath de tema desejado.
ThemeKeypathProperty Um nome de propriedade de cadeia de caracteres que será acrescentada ao keypath base do tema fornecido no Tema.
ResourcePath Um caminho de recurso para recuperar o valor de um recurso do Unity (pode começar com "recurso://").
FilePath Um caminho de arquivo para recuperar um ativo de streaming do Unity (pode começar com "arquivo://").

Detecção Automática de Tipo de Dados

A detecção automática analisa os dados recebidos e decide o método de recuperação automaticamente. Na tabela abaixo, T representa o tipo desejado, como Material, Sprite, Imagem. A detecção automática pode ocorrer em dois locais no processo:

  • No próprio valor da referência primária.
  • No valor temático recuperado por meio da referência primária.
Tipo de referência Considerações Tem Auxiliar de Tema Comportamento
T n/d S/N Usada diretamente sem temas
INT qualquer cadeia de caracteres integral primitiva ou passível de análise Int32 Não Passada como índice para GetObjectByIndex(n) derivado para recuperar o objeto Nth do tipo T.
INT qualquer cadeia de caracteres integral primitiva ou passível de análise Int32 Yes Indexe para buscar o keypath de tema Nth da pesquisa local e, em seguida, recupere o objeto temático por meio da detecção automática.
string Formato: "resource://{resourcePath}" S/N resourcePath é usado para recuperar o recurso do Unity
string Format: "file://{filePath} S/N filePath é usado para recuperar um ativo de streaming
string Outro Não Passada como chave para GetObjectByKey() derivado para recuperar o objeto correspondente do tipo T.
string Outro Yes Chave para buscar o keypath de tema correspondente da pesquisa local e, em seguida, recuperar o objeto temático por meio da detecção automática.

Um exemplo para recuperação de um ícone de status temático de um banco de dados que contém um valor de status numérico:

  1. O keypath para um ícone de status no banco de dados é status.sprite_index.
  2. O valor recuperado para status.sprite_index é 2, o que significa status "cancelado".
  3. A entrada N=2 (ou seja, a 3ª) na pesquisa DataConsumerSprite está definida como "Status.Icons.Cancelled".
  4. Esse é o keypath usado para recuperar um valor da fonte de dados "tema".
  5. O valor do keypath "Status.Icons.Cancelled" é "resource://Sprites/sprite_cancelled".
  6. A detecção automática determina que ele deve recuperar o ícone por meio de um recurso localizado em "Recursos/Sprites/sprite_cancelled"

TextMeshPro StyleSheets

O tema é capaz de ativar folhas de estilos TMPro. O ScriptableObject "Configurações de TMP" determina onde se espera que as folhas de estilos estejam nos Recursos. É a propriedade "Ativo de Fonte Padrão => Caminho".

Certifique-se de colocar qualquer StyleSheets específico do aplicativo no mesmo sub-caminho fora de Recursos. Se você quiser organizá-las de forma diferente, atualize as "Configurações do TMP" para corresponder.

Como tornar os novos controles de UX temáticos

Se você estiver desenvolvendo novos controles de UX, é relativamente fácil torná-los temáticos. Na medida em que o controle usa Materiais, Sprites e outros ativos já em uso por outros controles de UX, geralmente é uma questão de nomear os vários objetos de jogo de maneira detectável.

É possível herdar do MRTK_UXCore_ThemeProfile e adicionar campos mais temáticos ou apontar seus controles para seu próprio ScriptableObject. Não há nada de mais nos que são fornecidos além da organização do ScriptableObject que determinará os caminhos de chave necessários para acessar itens de dados individuais, por meio de Reflexão em C#.

Ao adicionar um script BindingConfigurator.cs ao nível superior do novo controle, você pode especificar seu próprio ScriptableObject BindingProfile serializado. Isso fornecerá o nome de GameObject necessário aos mapeamentos de KeyPath necessários para associar seus elementos temáticos com os dados fornecidos no perfil do tema. Esse script adicionará automaticamente todos os componentes necessários do DataConsumerXXX no runtime para dar suporte ao tema que você deseja usar.

Introdução

Requisitos

  • Unity 2020.3 LTS ou posterior
  • TextMeshPro 2.1.4 ou posterior

Cenas de exemplo

Para uma primeira etapa, examine de perto as várias cenas de exemplo de associação de dados no pacote exemplos do MRTK e examine como os vários MonoBehaviours da fonte de dados são configurados. Em geral, os scripts de associação de dados só precisam ser colocados no GameObject de nível mais alto de um pré-fabricado ou um conjunto relacionado de elementos UX.

Além disso, para a maioria dos casos de uso, os valores padrão funcionam "fora da caixa", mas as propriedades expostas fornecem muita flexibilidade para os casos mais avançados.

Observação

Para habilitar o tema para os componentes padrão do MRTK UX, o símbolo MRTK_UX_DATABINDING_THEMING_ENABLED deve ser definido nas Configurações do Player. Esse símbolo garante zero impacto no desempenho quando o tema não é necessário.

Assets/DataBinding Example/Scenes/DataBindingExamples.scene

Esta cena que demonstra uma variedade de cenários de dados variáveis. Basta carregar a cena e reproduzir. Algumas observações:

  • O campo Entrada de Texto dos componentes TextMeshPro contém variáveis semelhantes a esta: {{ firstName }}. Esses marcadores são usados diretamente como keypaths locais.

  • Objetos de jogo para sprites e texto têm alguma forma de componente Consumidor de Dados que gerencia o recebimento de dados e a atualização de exibições.

  • Um único Consumidor de Dados pode ser compartilhado por vários componentes do mesmo tipo ao ser colocado mais alto na hierarquia GO.

  • Um Consumidor de Dados pode encontrar a própria Fonte de Dados, desde que esteja no mesmo objeto de jogo ou superior na hierarquia GO.

  • Um objeto de jogo pai tem um componente de Fonte de Dados que fornece dados para todos os objetos de jogo filho que apresentam um conjunto relacionado de informações variáveis.

  • Uma coleção Consumidor de Dados especifica um pré-fabricado que contém os consumidores de dados que serão usados para preencher esse pré-fabricado com dados variáveis.

Assets/UX Theming Example/Scenes/AudioTheming

Este exemplo usa temas para alternar AudioClips entre um conjunto para Piano e outro para Xylophone.

Assets/UX Theming Example/Scenes/BatteryLevelExample

Este exemplo combina temas e associação de dados para mostrar um nível de bateria como um valor numérico e como um ícone. O tema é usado para selecionar entre um "tema de carregamento" e "não de carregamento". Ele foi projetado para atender aos seguintes objetivos:

  • Todos os ativos visuais podem existir em uma única atuação ScriptableObject como um perfil de tema.
  • O número de sprites para estados de "carregamento" pode ser diferente do número para estados de "não carregamento".
  • O algoritmo para mapear o nível de bateria relatado para um sprite em particular pode ser não linear e diferir entre os estados de "carregamento" e de "não carregamento".
  • Todos os ativos visuais podem existir em uma única atuação ScriptableObject como um perfil de tema.
  • O número de sprites para estados de carregamento pode ser diferente do número para estados de não carregamento.
  • O algoritmo para mapear o nível de bateria relatado para o qual o sprite pode ser não linear e diferir entre os estados de carregamento e de não carregamento.

Observação

A estrutura dessa demonstração não é um bom exemplo de combinação de temas e vinculação de dados. Em um aplicativo de produção para a separação adequada do modelo e da exibição, o estado real da bateria (nível e carregamento) seria fornecido em uma fonte de dados separada dos localizadores de recursos para os próprios sprites.

Assets/UX Theming Example/Scenes/UXThemingExample

Este exemplo demonstra a alteração do tema de um aplicativo inteiro e também demonstra o uso de uma fonte de dados DataSourceGODictionary para gerenciar uma variedade de conteúdo textual a ser exibido na UX. Em um cenário mais abrangente, os outros tipos de fonte de dados mais flexíveis provavelmente fornecerão a flexibilidade necessária, como DataSourceReflection ou DataSourceGOJson.

Primeiro projeto de associação de dados

Aqui está um exemplo simples para ajudá-lo a começar de forma rápida:

  1. Crie uma cena.
  2. No menu Kit de Ferramentas de Realidade Misturada, selecione a opção Adicionar à Cena e Configurar.
  3. Crie um objeto de jogo vazio e renomeie-o como "Vinculação de Dados". Adicione um componente DataSourceJsonTest.
  4. No inspetor, altere a URL para: https://www.boredapi.com/api/activity
  5. Adicione uma interface do usuário –> Texto – objeto TextMeshPro ao objeto de jogo Associação de Dados. Ele adicionará uma tela e, em seguida, um objeto "Texto (TMP)".
  6. Selecione o objeto TMP (Texto) e, no inspetor, altere a Entrada de Texto para:

{{ activity }}. It's {{ type }}.

  1. Selecione o objeto de Tela e adicione um componente de Texto do Consumidor de Dados a ele.
  2. Execute o projeto. A cada 15 segundos, uma atividade diferente será mostrada.

Parabéns. Você criou seu primeiro projeto de Associação de Dados com o MRTK!

Como criar uma nova fonte de dados

Uma fonte de dados fornece dados para um ou mais consumidores de dados. Seus dados podem ser qualquer coisa: gerados de algoritmos, em RAM, em disco ou recuperados de um banco de dados central.

Todas as fontes de dados precisam fornecer a interface IDataSource. Algumas das funcionalidades básicas são oferecidas em uma classe base chamada DataSourceBase. Você provavelmente vai querer derivar dessa classe para adicionar a funcionalidade de gerenciamento de dados específica correspondente à sua necessidade.

Para tornar possível remover uma fonte de dados como um componente em um objeto de jogo, existe outro objeto base chamado DataSourceGOBase, em que GO significa GameObject. Este é um MonoBehavior que pode ser descartado em um GameObject como um Componente. É um proxy fino que foi projetado para delegar o trabalho a uma fonte de dados principal não específica do Unity.

Uma fonte de dados pode expor a capacidade de manipular dados no Editor do Unity. Se esse for o caso, a classe derivada poderá conter toda a lógica da fonte de dados ou poderá aproveitar uma fonte de dados "stock", mas também adicionar campos de inspetor ou outros meios de configurar os dados.

Como criar um novo consumidor de dados

Um consumidor de dados recebe notificações de alterações de dados e atualiza alguns aspectos da experiência do usuário, como o texto mostrado em um componente TextMeshPro.

Todos os consumidores de dados devem fornecer a interface IDataConsumer. Algumas das funcionalidades básicas são oferecidas em uma classe base chamada DataConsumerGOBase, em que GO significa GameObject.

A maior parte do trabalho de um consumidor de dados é aceitar novos dados e prepará-los para apresentação. Isso pode ser tão simples quanto selecionar o pré-fabricado certo ou pode significar buscar mais dados de um serviço de nuvem, como um sistema de gerenciamento de conteúdo.

Como criar um posicionador de item de coleta de dados

Um posicionador de item de coleta de dados é responsável por gerenciar quais partes de uma coleção estão visíveis no momento e como apresentar essa coleção visível, seja uma pequena lista estática ou um banco de dados gigante com milhões de registros.

Todos os posicionadores de item devem fornecer a interface IDataCollectionItemPlacer. Algumas das funcionalidades básicas são oferecidas em uma classe base chamada DataColletionItemPlacerGOBase. Todos os posicionadores de item devem derivar dessa classe.

Limitações conhecidas e recursos ausentes

  • Ainda não integrado aos controles baseados em Tela do Unity e às listas roláveis.
  • A integração do .NET INotifyPropertyChanged ainda não foi implementada.
  • A cena de exemplo que busca imagens do Flickr e trymrtk.com não funciona no HoloLens devido a um bug do HTTPS SSL em versões posteriores do Unity.
  • Ajuste de desempenho adicional.
  • Esta versão se concentra na apresentação de dados, e não na captura de dados. Os controles de UX do MRTK ainda não estão conectados para definir o estado em um DataSource.
  • Alterações dinâmicas para listar dados atualizam completamente a lista inteira em vez de atualizar incrementalmente.
  • O pipeline de manipulação de dados ainda não foi implementado
  • O preenchimento de todos os componentes de UX em uma imagem fixa ainda não tem suporte total.
  • Os nós DataSourceJson devem implementar a interface IDataNode para serem interoperáveis com DataSourceObjects.