Partager via


Infrastructure de liaison de données et de thématisation – MRTK3

Bienvenue dans l’infrastructure de liaison de données et de thématisation MRTK3. Cette infrastructure est conçue pour faciliter la création d’éléments visuels qui peuvent être remplis et mis à jour dynamiquement, au moment du runtime, par les données fournies à partir d’une ou plusieurs sources de données.

Définition d’une liaison de données

La liaison de données est un processus qui établit une connexion entre l’expérience utilisateur (vue) d’une application et les données présentées (modèle). Supposons que la liaison est correctement paramétrée et que les données fournissent les notifications appropriées ; lorsque les données changent de valeur, les éléments liés aux données reflètent automatiquement ces changements.

Infrastructures de liaison de données populaires :

  • Delphi
  • Windows Presentation Framework (WPF .NET)
  • Windows Forms
  • Angular
  • Backbond
  • JavaFX Bindings

Diagramme de blocs de liaison de données Windows Presentation Framework

Databinding Windows Presentation Framework (WPF) Pour plus d’informations, consultez Vue d’ensemble de la liaison de données - WPF.NET


MRTK equivalent block diagram

MRTK equivalent block diagram


Objectifs de conception

  • Multiplateforme : déployer n’importe où
  • Prendre en charge n’importe quelle structure organisationnelle et n’importe quelle origine de sources de données
  • Intégration facile à des bases de code existantes ou greenfield
  • Convivial pour le concepteur et le développeur
  • Peut être activé/désactivé à tout moment pendant le cycle de vie de l’application
  • Prendre en charge des scénarios réels d’entreprise : bases de données back-end, modèles préfabriqués d’expérience utilisateur complexes
  • Facilement applicable aux composants d’expérience utilisateur non-MRTK existants ainsi qu’aux nouveaux éléments visuels
  • Lier n’importe quel type de données, y compris les sprites, les images, les matériaux, les animations et les clips audio
  • Fonctionnalités faciles à améliorer sans toucher à la base de code existante
  • Utilisation efficace du processeur, de la RAM, du GC et du frame-time
  • Simplicité d’intégration à une grande variété de sources de données locales ou principales
  • Toute combinaison simultanée d’états incorporés, d’état d’exécution et de sources de données back-end
  • Gérer efficacement n’importe quelle collection de tailles pour une présentation sous forme de liste
  • Thématisation et liaison de données combinés pour les éléments de données dynamiques thémables
  • Valider et manipuler des données variables de manière ouverte avant leur présentation
  • Dépendances minimales aux autres fonctionnalités MRTK
  • Compatible avec MRTK v2 et MRTK3
  • Possibilité de créer facilement une étiquette blanche et/ou d’appliquer une personnalisation aux ressources du stock avec un effort minimal

Principales fonctionnalités

  • Les sources de données ouvertes prennent en charge n’importe quelle stratégie de données persistante, distante ou RAM.
  • Les consommateurs de données ouvertes prennent en charge tous les besoins en matière de liaison et de thématisation pour l’expérience utilisateur.
  • La découverte automatique entre les sources de données et les consommateurs simplifie la recherche.
  • Configuration automatique facultative à partir d’un profil de liaison
  • Le modèle de données et la vue découplés prennent en charge les modèles MVC et MVVM.
  • Collections virtualisées avec navigation via la pagination et le défilement.
  • Pré-extraction prédictive des éléments de collection pour faciliter la navigation dans la liste.
  • Les objets de collection peuvent être regroupés et réutilisés pour réduire le GC.
  • Possibilité de créer un mappage entre les différences au niveau des espaces de noms keypath des données et de la vue.

Fonctionnalités actuelles

1. Visualiser des données variables via des consommateurs de données

Actuellement pris en charge :

  • Texte TextMeshPro et TextMesh
  • Feuilles de style de texte (pour les thèmes et l’accessibilité)
  • Texture sprite
  • Déclencheur booléen
  • Texture quad
  • Icônes de police
  • Collections : listes de tailles arbitraires contenant des préfabriqués remplis avec des données variables
  • Tout autre consommateur qui prend en charge l’interface IDataConsumer (directement ou via des dérivations de classes de base)

2. Fournir des données variables via diverses sources de données :

  • Texte JSON (directement ou via l’extraction d’URL)
  • Dictionnaire d’éléments de données variables
  • Objet - Données structurées basées sur des nœuds
  • Réflexion de n’importe quel objet C#
  • Données modifiées par programmation
  • Toute autre méthode prenant en charge l’interface IDataSource

3. Lister les placeurs d’éléments pour gérer la manifestation visuelle d’une liste

4. Lister la pagination, le défilement et la virtualisation

  • Les données sont extraites uniquement lorsqu’elles sont visibles ou en cours de traitement
  • Prend en charge des jeux de données back-end arbitrairement volumineux
  • L’extraction est équilibrée sur plusieurs images

5. Répertorier le regroupement de préfabriqués

  • Les préfabriqués sont réutilisés et remplis à nouveau pour réduire le GC et le temps d’instanciation.

6. Appliquer des thèmes dynamiquement aux éléments au moment du runtime


Fonctionnalités de la feuille de route

Outre les options disponibles, les principales priorités pour les fonctionnalités supplémentaires sont les suivantes :

1. Pipelines de manipulateur de données

  • Conversion entre les valeurs côté données et côté vue
  • Localisation (intégration transparente avec la localisation Unity)
  • Mise en forme
  • Validation

2. Pré-extraction d’élément de liste prédictive pour un défilement/une pagination plus rapide/plus fluide

3. Plus de consommateurs de données

  • Définir une propriété publique sur un composant
  • Définir l’état activé/désactivé
  • Définir la valeur du curseur
  • Définir une case d’option dans un groupe
  • Propriétés de matériau individuelles telles que la couleur définie

4. Thématisation

  • Afficher les thèmes appliqués dans l’Éditeur même si l’application n’est pas en cours d’exécution
  • Mettre à jour les préfabriqués pour refléter un thème appliqué, afin qu’il devienne le thème par défaut
  • Héritage de thème/style

Terminologie

  • Source de données : fournisseur de données, qu’il s’agisse de l’état d’exécution, de la persistance locale ou de l’extraction à partir d’un serveur.
  • Fournisseur de sources de données : MonoBehavior simple qui fournit l’accès à une source de données qui peut ne pas être exposée dans le graphique de scène Unity.
  • Type de source de données : nom unique attribué à la source de données afin que les consommateurs de données puissent spécifier la ou les sources de données qu’ils recherchent par leur nom.
  • Consommateur de données : tout consommateur de données qui souhaite agir sur les modifications de données, généralement un élément visuel, mais qui n’est pas obligatoire. Par exemple, son objectif peut être de déclencher des actions basées sur des modifications de valeur de données.
  • Contrôleur de données : mécanisme permettant d’appeler une action avec la valeur liée aux données actuellement associée et fournie en tant que paramètre.
  • Chemin de clé : sélecteur de données qui référence un objet spécifique dans une source de données. Dans l’implémentation actuelle, le format du chemin de clé est modélisé après les accesseurs de données JSON pour déchiffrer toute combinaison imbriquée de cartes, de listes et d’éléments atomiques.
  • Chemin de clé local : chemin de clé côté consommateur de données qui peut être incorporé définitivement dans un préfabriqué réutilisable. Par une combinaison d’entités de collection et de mappers Keypath, ce chemin est automatiquement converti en un chemin de clé entièrement résolu pour un élément spécifique d’une collection. Lorsqu’il n’est pas associé à une collection, celui-ci peut être mappé directement à une référence dans la source de données ou peut d’abord être modifiée via un mapper Keypath.
  • Chemin de clé entièrement résolu : chemin de clé complet et absolu qui est mappé à un objet spécifique dans une source de données. Pour les éléments d’une collection, il s’agit d’une combinaison du chemin de clé entièrement résolu pour une entité de collection et d’un chemin de clé relatif (local) pour un élément de données de cette entité de collection.

  • Mapper Keypath : mapper d’espace de noms facultatif entre les chemins de clés locaux et les noms de champs Source de données (par exemple , « lien » <-> « URL »).

  • Thème : source de données qui fournit un ensemble de différents éléments et styles nécessaires pour obtenir une esthétique visuelle spécifique.

  • Placeur d’élément : compagnon DataConsumerCollection chargé de placer des éléments visibles dans une scène.

  • Pool d’objets de données : préfabriqués de secours instanciés, prêts à remplir les données pour la navigation de liste à faible GC.

  • Virtualisation de liste : possibilité de remplir, de présenter et de parcourir des listes de taille arbitrairement volumineuse.

  • Pré-extraction prédictive : pré-extraction des données et remplissage des préfabriqués de collection pour les éléments qui pourront prochainement être visualisés via le défilement/la pagination.

  • Pré-extraction prédictive : pré-extraction des données et remplissage des préfabriqués de collection pour les éléments qui pourront prochainement être visualisés via le défilement/la pagination.

Concepts clés

source de données

Une source de données est un ensemble managé de données de type(s) et de complexité arbitraires, qui peut être utilisé pour remplir des vues de données via des consommateurs de données. Les données gérées par une source de données peuvent être statiques ou dynamiques. Toutes les modifications apportées aux éléments de données sont signalées à tous les consommateurs de données inscrits pour recevoir des notifications de modification.

Fournisseur de source de données

Interface simple qui utilise une méthode unique pour récupérer une source de données. Elle est conçue pour permettre à un composant de script MonoBehavior d’être découvert automatiquement dans la hiérarchie des objets de jeu par les composants du consommateur de données, mais sans avoir à implémenter une source de données directement sur l’objet de jeu lui-même. Il n’est pas nécessaire d’implémenter une source de données directement sur l’objet de jeu lui-même. Cela est utile lorsqu’un MonoBehavior existant doit dériver d’une autre classe et que plusieurs héritages empêchent de dériver de DataSourceGOBase. Ce fournisseur permet également de créer plus de code sans aucune dépendance Unity.

Fournisseur de sources de données Singleton

Le MonoBehaviour DataSourceProviderSingleton permet de spécifier une source de données qui peut être découverte automatiquement même si elle ne se trouve pas dans la même hiérarchie GameObject que les DataConsumers qui souhaitent l’écouter. Il suffit de placer DataSourceProviderSingleton n’importe où dans la scène et de remplir la propriété Data Sources avec toutes les sources de données qui doivent être découvertes par les consommateurs de données. Par ailleurs, les consommateurs de données aideront leurs parents à trouver une source de données appropriée, ce qui implique que vous pouvez placer une source de données qui fournit les données souhaitées n’importe où dans la chaîne parente de ces consommateurs de données.

Chemin de clé (string)

Un chemin de clé est un mécanisme permettant d’identifier de manière unique toutes les informations d’une source de données.

Bien qu’un chemin de clé puisse prendre la forme de n’importe quel identificateur unique par élément de données, toutes les implémentations actuelles utilisent le concept d’un spécificateur lisible par l’utilisateur logique qui indique la position de navigation des données d’intérêt par rapport à l’ensemble du jeu de données structuré. Il est modélisé sur le concept de listes, de dictionnaires et de primitives JavaScript. Les chemins d’accès clés sont des instructions Javascript correctes sur le plan syntaxique qui permettent d’accéder aux données qui peuvent être représentées dans JSON. Cette approche présente l’avantage d’être bien corrélée à la fois avec JSON et XML. Ce sont les deux moyens les plus courants de transférer des informations à partir de services principaux.

Exemple de chemins de clé :

  • température
  • contacts[10].firstName
  • contacts
  • contacts[10].addresses[3].city
  • [10].title
  • kingdom.animal.mammal.aardvark.diet.foodtypes.termites

Étant donné qu’un chemin de clé est une chaîne arbitraire sans taxonomie requise, les spécificateurs de données réels peuvent être n’importe quelle méthode de description des données à récupérer. L’élément XPath de XML est un exemple de schéma de chemin de clé viable qui fonctionnerait avec des sources de données. Tant que les chemins de clé fournis par le consommateur de données sont cohérents avec les chemins de clé attendus par la source de données, tout fonctionnera. En outre, des mappeurs de chemins de clé peuvent être implémentés pour effectuer la traduction entre différents schémas.

Résolution d’un chemin de clé

La résolution d’un chemin de clé suppose de combiner deux chemins de clé :

  1. Un chemin de clé absolu qui décrit comment accéder à un sous-ensemble spécifique d’un jeu de données plus volumineux, tel qu’une entrée dans une liste constituée de nombreuses entrées.
  2. Un chemin de clé partiel (relatif) qui représente une référence spécifique dans cette liste ou entrée de carte.

Cela permet de traiter un sous-ensemble des données de telle façon que son emplacement réel dans une hiérarchie de jeu de données plus volumineuse importe peu. L’utilisation la plus critique de cette capacité consiste à décrire les données d’une seule entrée dans une liste sans se soucier de l’entrée dans cette liste à laquelle l’instance actuelle fait référence.

Étant donné qu’un chemin de clé « entièrement résolu » est toujours généré et consommé par une DataSource et ne doit jamais (ou au moins rarement) être modifié par un DataConsumer ou un autre composant externe, il peut être structuré de la manière qui convient à DataSource. Par exemple, si un préfabriqué affiche une entrée de liste pour une photo et qu’il s’agit d’un titre, d’une date de prise de vue et d’autres attributs, le chemin de clé local dans le préfabriqué peut ressembler à ceci :

  • « photo_url »
  • « title »
  • « date_taken »
  • « description »

Les chemins de clé entièrement résolus pour une entrée de préfabriqué dans une liste peuvent ressembler à ceci :

  • « 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 »

Mappeur de chemin de clé (IDataKeyPathMapper)

Un mappeur de chemin de clé permet aux sources de données et aux consommateurs de données d’utiliser différents espaces de noms et conventions pour les chemins de clé et de travailler ensemble.

Un préfabriqué pour un élément couramment utilisé, comme une ardoise permettant d’afficher des coordonnées d’une personne, peut inclure des champs variables gérés par les consommateurs de données. Pour rendre cela possible, l’identificateur utilisé pour tout aspect variable du préfabriqué nécessite un moyen de mapper à l’identificateur de la source de données correcte qui, dans chaque utilisation du préfabriqué, détermine le contenu de cet élément variable. Le mappeur de chemin de clé permet de le faire.

Le préfabriqué peut être utilisé avec différentes sources de données où les données sont stockées dans une structure organisationnelle différente et utilisent des noms de champs. Pour utiliser un préfabriqué de modèle avec chaque source de données, un mappeur de chemin de clé peut résoudre toutes les différences au niveau du mode d’organisation des données.

Consommateur de données (IDataConsumer)

Objet qui sait comment consommer des informations gérées par une source de données et comment utiliser ces données pour remplir les vues de données.

Les consommateurs de données peuvent s’inscrire auprès d’une source de données pour être avertis des modifications apportées à un élément de données qui existe sur un chemin de clé spécifié dans un jeu de données. Chaque fois que les données spécifiées ont changé (ou qu’on soupçonne d’avoir changé), le(s) consommateur(s) de données en sont avertis.

Consommateur de données de collection

Un consommateur de données de collection a la possibilité de gérer une liste d’éléments similaires. Cette liste peut être l’ensemble du jeu de données géré par une source de données, ou simplement un sous-ensemble. En règle générale, les données de chaque élément de la liste contiennent des types d’informations similaires, mais cela n’a rien d’obligatoire. Les sources de données et les consommateurs de données peuvent prendre en charge les listes imbriquées, telles qu’une liste de mots clés associés à chaque photo dans une liste de photos associées à chaque personne dans une liste de contacts. Le chemin de clé des mots clés serait relatif à la photo, le chemin de clé des photos serait relatif à la personne et le chemin clé de la personne serait relatif à la liste parente la plus proche ou à la racine du jeu de données.

Lors du traitement des collections, le chemin de clé résolu correct pour l’entrée spécifique de la collection est affecté à chaque consommateur de données (instancié pour chaque élément de collection) trouvé dans le préfabriqué. Il est ensuite utilisé pour résoudre le chemin de clé pour toutes les données relatives (locales) de vue dans ce préfabriqué.

Placeur d’élément de collection de données

Un consommateur de données de collection a besoin d’un moyen de remplir des expériences utilisateur avec des listes d’éléments visuels répétitifs, que l’on peut trouver par exemple dans une liste déroulante de produits, de photos ou de contacts. Cela s’effectue en affectant un placeur d’élément au consommateur de données de collection. Ce placeur d’élément est la logique qui sait comment demander des éléments de liste, accepter des préfabriqués qui ont été remplis avec des données variables, puis les présenter à l’utilisateur, généralement en les insérant dans une liste gérée par un composant de disposition d’expérience utilisateur pour les listes.

Création de thèmes

La thématisation utilise l’intégralité des sources de données et des consommateurs de données. Il est possible de thématiser n’importe quelle hiérarchie de GameObjects s’ils sont statiques ou s’il s’agit de données liées dynamiquement à d’autres sources de données. Cela permet d’appliquer à la fois la liaison de données et la thématisation de façon combinée. Il est même possible de thématiser les données provenant d’une autre source de données.

Diagramme de blocs et flux de données

Flux de données de thèmes MRTK

Thématisation MRTK

Le thématisation désigne la possibilité de changer complètement l’esthétique visuelle de nombreux éléments d’expérience utilisateur à la fois. En règle générale, toutes les données nécessaires pour spécifier un thème sont fournies par une seule source de données, comme un objet scriptable. Il est également possible de fournir des données en fonction des besoins ou de les diviser en groupes logiques selon leur objectif.

Thème MRTK3

Thématisation MRTK3 combinée à la liaison de données

La liaison de données et la thématisation peuvent coexister pour un seul élément de l’expérience utilisateur. Il est possible d’appliquer simultanément la thématisation et la liaison de données à chaque élément individuel de l’expérience utilisateur. Dans ce scénario, le flux classique est que la référence provenant d’une DataSource est utilisée pour dériver le chemin de clé de thème correct. Ce chemin de clé est ensuite utilisé pour récupérer un objet à partir de la source de données de thème, généralement un profil ScriptableObject, mais aussi potentiellement n’importe quelle source de données pouvant résoudre un chemin de clé.

Pour simplifier la configuration de la thématisation et de la liaison de données, il est possible de créer des profils de liaison traités par un BindingConfigurator au moment de l’instanciation.

  • Un BindingConfigurator traite un profil de liaison pour déterminer les ressources au sein d’un préfabriqué auxquelles doivent être appliqués des thèmes; et associe aux chemins de clé à la fois des éléments de données liés et des éléments thémables. Il ajoute ensuite les DataConsumers appropriés pour lier ces éléments visuels aux sélecteurs de chemins de clé corrects, qui seront utilisés pour référencer des données spécifiques dans une ou plusieurs DataSources, lesquelles sont généralement externes au préfabriqué lui-même.
  • Les données de thème sont fournies par une DataSource qui contient des données pour chaque chemin de clé identifié dans le profil de liaison.
  • Un script d’application auxiliaireThemeProvider facilite l’utilisation d’un ScriptableObject en tant que DataSource pour la thématisation.
  • Le thème d’expérience utilisateur standard est fourni par le MRTK_UX_ThemeProfileScriptableObject lié à une DataSourceReflection dans le ThemeProvider.

Diagramme de flux de source de données de profil de thème

Source de données incorporée

Une source de données incorporée est appropriée dans deux situations :

  1. Lorsque chaque instance du préfabriqué peut avoir des paramètres de thème différents et nécessite sa propre source de données distincte.
  2. Lorsque toutes les instances de ce préfabriqué sont régies par un profil de thème persistant commun (par exemple, ScriptableObject) et que vous pouvez fournir via la source de données incorporée afin qu’il n’y ait aucune dépendance externe à établir.

DataSourceReflection

Cet élément peut transformer n’importe quelle structure ou classe C# en DataSource en utilisant la réflexion pour mapper des chemins de clés aux champs et propriétés, et même à des classes, des tableaux, des listes et des dictionnaires imbriqués. Il peut être associé à un ScriptableObject Unity, ou à toute autre structure ou classe C# où l’on trouve des données de thème. Il est possible d’injecter des dépendances et de modifier l’objet instancié contenant les données au moment de l’exécution.

  1. Objet scriptable : utile pour les thèmes statiques partagés entre de nombreux préfabriqués.
  2. Structure ou classe C# non persistante : utile pour les modifications dynamiques au moment de l’exécution du thème.

DataSourceJson

Si les données existent en tant que texte json, cela permet de gérer les chemins de clés de mappage vers le DOM json. Les ressources binaires peuvent être récupérées à partir des ressources Unity, de StreamingAssets ou même d’une URL extraite.

DataSourceDictionary

Il s’agit d’une option simple lorsqu’une liste ordinaire est suffisante pour répondre au besoin, ainsi que pour un prototypage rapide. Toutes les ressources de thématisation sont prises en charge, notamment le texte, les ressources Unity (par exemple, Materials, Sprites, Images), Resources, StreamingAssets, ou même des ressources récupérables en externe via une URL.

Custom

Toute source de données personnalisée qui implémente l’interface IDataSource simple ou qui est dérivée de DataSourceBase ou DataSourceGOBase peut être utilisée pour répondre à des besoins personnalisés.

UXComponents de thématisation

Les contrôles UXComponents standard fournis dans le package UXComponents sont tous configurés pour prendre en charge la thématisation. Cette fonctionnalité est désactivée par défaut, mais elle peut être réactivée facilement.

Chaque contrôle, généralement sur le plus haut gameObject du préfabriqué racine, possède un script appelé UXBindingConfigurator. Ce script, s’il est activé, extrait les scripts de liaison de données nécessaires pour activer la thématisation. Veillez également à importer le package de liaison de données et de thématisation.

Remarque sur les feuilles de style TextMeshPro : il n’est actuellement pas possible d’utiliser les feuilles de style pour styler le style TextMeshPro Normal. Tout autre style inclus dans la feuille de style par défaut de TextMeshPro peut être utilisé. Les exemples utilisent Body pour contourner cette restriction.

DataSourceThemeProvider

Le MonoBehaviour DataSourceThemeProvider peut être utilisé pour permettre facilement à un ScriptableObject contenant toutes les références à toutes les ressources de thématisation de fonctionner en tant que source de données. Ceci est illustré dans la scène UXThemingExample.

ThemeSelector

Le MonoBehaviour ThemeSelector permet de spécifier et de basculer facilement entre plusieurs profils ScriptableObject. Il peut être utilisé, par exemple, pour faciliter le basculement entre un thème « Foncé » et un thème « Clair ». Ajoutez les ScriptableObjects aux Theme Profiles, généralement au moment de la conception. Ensuite, au moment de l’exécution, modifiez la propriété Current Theme pour modifier le thème.

Thématisation des consommateurs de données

La thématisation est accomplie par des consommateurs de données, en particulier ceux qui héritent de DataConsumerThemeBase<T>, DataConsumerTextStyle et des classes DataConsumer personnalisées que tout développeur peut implémenter pour améliorer la prise en charge de la thématisation.

La classe de base DataConsumerThemeBase<T> fournit une logique permettant d’utiliser un entier ou une référence de clé à partir d’une source de données primaire pour rechercher ensuite la valeur finale souhaitée à partir d’une base de données de thèmes secondaire. Ceci est effectué en mappant les données d’entrée à un chemin de clé de thème, puis en utilisant ce chemin de clé de thème pour récupérer la valeur finale. Ainsi, il est possible d’appliquer simultanément la liaison de données et la thématisation à n’importe quel élément. Par exemple, imaginez un champ d’état dans une base de données contenant les états Nouveau, Démarré et Terminé, représentés par les valeurs 0, 1 et 2. Chacune de ces valeurs peut être représentée par une icône Sprite. Pour la liaison de données, une valeur comprise entre 0 et 2 est utilisée pour rechercher le sprite souhaité. Avec la thématisation et la liaison de données, le profil de thème pointe vers la liste correcte de trois sprites dans le profil de thème, puis la valeur comprise entre 0 et 2 est utilisée pour sélectionner le sprite correct dans cette liste. Cela permet de moduler le style de ces icônes en fonction du thème.

Lorsque la thématisation de runtime et la liaison de données dynamique sont utilisées ensemble, une classe DataConsumerThemeHelper peut être spécifiée dans n’importe quelle classe dérivée DataConsumerThemeBase pour avertir de la modification d’un thème.

L’échange de thèmes au moment du runtime est effectué en remplaçant les données au niveau de la source de données du thème par un nouveau jeu de données défini dans la même topologie de modèle d’objet de données. DataSourceReflection peut être utilisé avec des ScriptableObjects où chaque profil représente un thème. Pour tous les contrôles d’expérience utilisateur MRTK Core, le profil de thème est un ScriptableObject nommé MRTK_UXComponents_ThemeProfile. Le script d’application auxiliaire ThemeProvider.cs permet d’utiliser facilement ce profil ou n’importe quel profil ScriptableObject en tant que source de données.

La méthode d’application d’un thème aux données dynamiques peut être automatiquement détectée dans la plupart des cas, mais elle peut aussi être spécifiée explicitement.

Lorsque la référence est utilisée pour sélectionner l’élément approprié à partir de la source de données du thème, le processus est le suivant :

  • une référence à partir de la source de données primaire est utilisée pour sélectionner ou construire le chemin de clé de thème correct ;
  • le chemin de clé de thème est utilisé pour récupérer une valeur à partir de la source de données de thème spécifiée sur dataConsumerThemeHelper ;
  • la valeur de thème récupérée est analysée pour détecter automatiquement la méthode de récupération correcte ;
  • l’élément de données final du type correct (par exemple. Material, Sprite, Image) est ensuite récupéré à l’aide de la méthode de détection automatique.

Types de données

Le type de données attendu de la référence utilisée pour récupérer l’objet souhaité peut être l’un des éléments suivants :

Type de données Description
AutoDetect La référence est analysée et l’interprétation correcte est automatiquement détectée. Pour plus d’informations, consultez la section « Détection automatique du type de données » ci-dessous.
DirectValue La référence doit être du type T souhaité (par exemple. Material, Sprite, Image) et être utilisée directement.
DirectLookup Index intégral ou clé de chaîne utilisé(e) pour rechercher la valeur souhaitée à partir d’une table de recherche locale.
StaticThemedValue L’objet thématisé statique du type correct est récupéré à partir de la source de données de thème au niveau du chemin de clé de thème spécifié.
ThemeKeypathLookup Un index intégral ou une clé de chaîne est utilisé(e) pour rechercher le chemin de clé de thème souhaité.
ThemeKeypathProperty Nom de propriété de chaîne qui sera ajouté au chemin de clé de base du thème fourni dans le thème.
ResourcePath Chemin d’accès aux ressources pour récupérer la valeur à partir d’une ressource Unity.
FilePath Chemin d’accès au fichier pour la récupération d’une ressource de diffusion en continu Unity (peut commencer par « file:// »).

Détection automatique du type de données

La fonction Autodetect analyse automatiquement les données reçues et décide automatiquement de la méthode de récupération. Dans le tableau ci-dessous, T représente le type souhaité, tel que Material, Sprite, Image. La fonction Autodetect peut intervenir à deux emplacements dans le processus :

  • Sur la valeur de référence primaire elle-même.
  • Sur la valeur thématisée récupérée par le biais de la référence principale.
Type de référence Considérations Contient l’application auxiliaire Thème Comportement
T n/a O/N Utilisé directement sans thématisation
int n’importe quelle primitive intégrale ou chaîne analysable Int32 No Passé en tant qu’index au GetObjectByIndex(n) dérivé pour récupérer l’objet Nth de type T.
int n’importe quelle primitive intégrale ou chaîne analysable Int32 Yes Index pour extraire le chemin de clé de thème Nth à partir de la recherche locale, puis pour récupérer l’objet thématisé via la détection automatique.
string Format : « resource://{resourcePath} » O/N resourcePath est utilisé pour récupérer la ressource Unity
string Format : « file://{filePath} » O/N filePath est utilisé pour récupérer une ressource de diffusion en continu
string Autre No Passé en tant que clé au GetObjectByKey() dérivé pour récupérer l’objet correspondant de type T.
string Autre Yes Clé pour extraire le chemin de clé de thème correspondant à partir de la recherche locale, puis pour récupérer l’objet thématisé via la détection automatique.

Exemple de récupération d’une icône d’état thématisée à partir d’une base de données contenant une valeur d’état numérique :

  1. Le chemin de clé d’une icône d’état dans la base de données est status.sprite_index.
  2. La valeur récupérée pour status.sprite_index est 2, ce qui signifie « annulé ».
  3. L’entrée N=2 (par exemple, 3e) dans la recherche DataConsumerSprite est définie sur « Status.Icons.Cancelled ».
  4. Il s’agit du chemin de clé utilisé pour récupérer une valeur à partir de la source de données « thème ».
  5. La valeur du chemin de clé « Status.Icons.Cancelled » est « resource://Sprites/sprite_cancelled ».
  6. La détection automatique détermine qu’elle doit récupérer l’icône via une ressource située dans « Ressources/Sprites/sprite_cancelled ».

Feuilles de style TextMeshPro

La thématisation est capable d’activer les feuilles de style TMPro. Le ScriptableObject « Paramètres TMP » dicte l’emplacement où les feuilles de style sont censées se trouver dans les ressources. Il s’agit de la propriété « Default Font Asset => Path ».

Veillez à placer n’importe quelle feuille de style spécifique à l’application dans le même sous-chemin d’accès aux ressources. Si vous souhaitez les organiser différemment, veillez à mettre à jour les « paramètres TMP » pour qu’ils correspondent.

Comment créer des contrôles d’expérience utilisateur thématisables

Si vous développez de nouveaux contrôles d’expérience utilisateur, il est relativement facile de les rendre thématisables. Dans la mesure où le contrôle utilise des Materials, des Sprites et d’autres ressources déjà utilisées par d’autres contrôles d’expérience utilisateur, il s’agit généralement de nommer les différents objets de jeu d’une manière détectable.

Il est possible d’hériter de MRTK_UXCore_ThemeProfile et d’ajouter d’autres champs thématisables ou de pointer vos contrôles vers votre propre ScriptableObject. Il n’y a rien de magique sur ceux fournis, si ce n’est que l’organisation du ScriptableObject détermine les chemins de clé nécessaires pour accéder à des éléments de données individuels, via une réflexion C#.

En ajoutant un script BindingConfigurator.cs au niveau supérieur du nouveau contrôle, vous pouvez ensuite spécifier votre propre ScriptableObject BindingProfile sérialisé. Cela fournira les correspondances nécessaires entre le nom du GameObject et le KeyPath afin d’associer vos éléments thématiques aux données fournies dans le profil du thème. Ce script ajoute automatiquement tous les composants DataConsumerXXX nécessaires au moment de l’exécution pour prendre en charge la thématisation que vous souhaitez utiliser.

Mise en route

Configuration requise

  • Unity 2020.3 LTS ou version ultérieure
  • TextMeshPro 2.1.4 ou version ultérieure

Exemples de scènes

Pour commencer, examinez de près les différents exemples de scènes de liaison de données dans le package MRTK Examples et observez de quelle manière les différents MonoBehaviours des sources de données sont configurés. En général, les scripts de liaison de données doivent uniquement être placés au plus haut niveau de GameObject d’un préfabriqué ou d’un ensemble d’éléments d’expérience utilisateur connexes.

En outre, pour la plupart des cas d’usage, les valeurs par défaut fonctionnent clé en main, mais les propriétés exposées offrent beaucoup de flexibilité pour les cas plus avancés.

Notes

Pour activer la thématisation pour les composants d’expérience utilisateur MRTK standard, le symbole MRTK_UX_DATABINDING_THEMING_ENABLED doit être défini dans les paramètres du lecteur. Ce symbole évite tout impact sur les performances lorsque la thématisation n’est pas nécessaire.

Assets/DataBinding Example/Scenes/DataBindingExamples.scene

Cette scène illustre divers scénarios de données variables. Chargez et lisez simplement la scène. Quelques points à noter :

  • Le champ Text Input des composants TextMeshPro contient des variables qui ressemblent à ceci : {{ firstName }}. Ces marqueurs sont utilisés directement en tant que chemins de clés locaux.

  • Les objets de jeu pour les sprites et le texte ont une forme quelconque de composant DataConsumer qui gère la réception des données et la mise à jour des vues.

  • Un consommateur de données unique peut être partagé par plusieurs composants du même type en étant placés plus haut dans la hiérarchie GO.

  • Un consommateur de données peut trouver sa propre source de données tant qu’il se trouve sur le même objet de jeu ou qu’il est placé plus haut dans la hiérarchie GO.

  • Un objet de jeu parent possède un composant Data Source qui fournit des données pour tous les objets de jeu enfant qui présentent un ensemble d’informations variables associé.

  • Un consommateur de données de collecte spécifie un préfabriqué qui contient lui-même des consommateurs de données qui seront utilisés pour remplir ce préfabriqué avec des données variables.

Assets/UX Theming Example/Scenes/AudioTheming

Cet exemple utilise la thématisation pour basculer AudioClips entre un ensemble Piano et un ensemble Xylophone.

Assets/UX Theming Example/Scenes/BatteryLevelExample

Cet exemple combine la thématisation et la liaison de données pour afficher un niveau de batterie à la fois sous forme de valeur numérique et sous forme d’icône. La thématisation est utilisée pour faire un choix entre un thème « charge » et un thème « pas de charge ». Elle est conçue pour répondre aux objectifs suivants :

  • Toutes les ressources visuelles peuvent exister dans un ScriptableObject unique agissant comme un profil de thème.
  • Le nombre de sprites utilisés pour les états « charge » peut différer du nombre appliqué pour l’état « pas de charge ».
  • L’algorithme de mappage du niveau de batterie signalé au sprite peut être non linéaire et différer entre les états « charge » et « pas de charge ».
  • Toutes les ressources visuelles peuvent exister dans un ScriptableObject unique agissant comme un profil de thème.
  • Le nombre de sprites utilisés pour les états « charge » peut différer du nombre appliqué pour l’état « pas de charge ».
  • L’algorithme de mappage du niveau de batterie signalé au sprite peut être non linéaire et différer entre les états « charge » et « pas de charge ».

Notes

La façon dont cette démo est structurée n’est pas un bon exemple de combinaison de la thématisation et de la liaison de données. Dans une application de production pour une séparation appropriée du modèle et de la vue, l’état réel de la batterie (niveau et charge) serait fourni dans une source de données distincte des localisateurs de ressources pour les sprites eux-mêmes.

Assets/UX Theming Example/Scenes/UXThemingExample

Cet exemple illustre la modification du thème d’une application entière et montre également comment utiliser une source de données DataSourceGODictionary pour gérer une variété de contenu textuel à afficher dans l’expérience utilisateur. Dans un scénario plus complet, les autres types de sources de données plus flexibles sont susceptibles de fournir la flexibilité nécessaire, par exemple DataSourceReflection ou DataSourceGOJson.

Premier projet de liaison de données

Voici un exemple simple pour vous aider à commencer rapidement :

  1. Créez une scène.
  2. Dans le menu Mixed Reality Toolkit, sélectionnez l’option Add to Scene and Configure (Ajouter à la scène et configurer).
  3. Créez un objet de jeu vide et renommez-le « Liaison de données ». Ajoutez un composant DataSourceJsonTest.
  4. Dans l’inspecteur, remplacez l’URL par : https://www.boredapi.com/api/activity
  5. Ajoutez une interface utilisateur -> Texte - Objet TextMeshPro à l’objet de jeu Liaison de données. Un canevas, puis un objet « Texte (TMP) » sont alors ajoutés.
  6. Sélectionnez l’objet Texte (TMP) puis, dans l’inspecteur, remplacez l’entrée de texte par :

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

  1. Sélectionnez l’objet canevas et ajoutez lui un composant Texte consommateur de données.
  2. Exécutez le projet. Toutes les 15 secondes, une activité différente s’affiche.

Félicitations. Vous avez créé votre premier projet de liaison de données avec MRTK !

Écriture d’une nouvelle source de données

Une source de données fournit des données à un ou plusieurs consommateurs de données. Il peut s’agir de données générées par un algorithme, dans la RAM, sur disque ou extraites d’une base de données centrale.

Toutes les sources de données doivent fournir l’interface IDataSource. Certaines fonctionnalités de base sont proposées dans une classe de base appelée DataSourceBase. Vous souhaiterez probablement dériver de cette classe pour ajouter les fonctionnalités de gestion des données spécifiques à vos besoins.

Pour pouvoir supprimer une source de données en tant que composant sur un objet de jeu, il existe un autre objet de base appelé DataSourceGOBase, où GO signifie GameObject. Il s’agit d’un MonoBehavior qui peut être déposé sur un GameObject en tant que composant. Ce proxy léger est conçu pour déléguer le travail à une source de données principale non Unity.

Une source de données peut exposer la possibilité de manipuler des données dans l’éditeur Unity. Le cas échéant, la classe dérivée peut contenir toute la logique de source de données, ou elle peut tirer parti d’une source de données « stock », mais également ajouter des champs d’inspecteur ou d’autres moyens de configuration des données.

Écriture d’un nouveau consommateur de données

Un consommateur de données reçoit des notifications lorsque les données ont changé, puis met à jour certains aspects de l’expérience utilisateur, comme le texte affiché dans un composant TextMeshPro.

Tous les consommateurs de données doivent fournir l’interface IDataConsumer. Certaines des fonctionnalités de base sont proposées dans une classe de base appelée DataConsumerGOBase, où GO signifie GameObject.

La majorité du travail d’un consommateur de données consiste à accepter de nouvelles données, puis à les préparer pour la présentation. Cela peut être aussi simple que de sélectionner le préfabriqué approprié, ou bien impliquer d’extraire plus de données à partir d’un service cloud tel qu’un système de gestion de contenu.

Écriture d’un placeur d’élément de collection de données

Un placeur d’élément de collection de données est chargé de gérer les parties d’une collection qui sont actuellement visibles et la façon de présenter cette collection visible, qu’il s’agisse d’une petite liste statique ou d’une base de données géante comptant des millions d’enregistrements.

Tous les placeurs d’élément doivent fournir l’interface IDataCollectionItemPlacer. Certaines fonctionnalités de base sont proposées dans une classe de base appelée DataColletionItemPlacerGOBase. Tous les placeurs d’éléments doivent dériver de cette classe.

Limitations connues et fonctionnalités manquantes

  • Pas encore intégré aux contrôles et aux listes déroulantes basés sur le canevas d’Unity.
  • L’intégration de .NET INotifyPropertyChanged n’est pas encore implémentée.
  • L’exemple de scène qui extrait des images à partir de Flickr et trymrtk.com ne fonctionne pas sur HoloLens en raison d’un bogue HTTPS SSL dans les dernières versions d’Unity.
  • Ajustement supplémentaire des performances.
  • Cette version se concentre sur la présentation des données, et non sur la capture de données. Les contrôles d’expérience utilisateur MRTK ne sont pas encore conçus pour définir l’état dans une DataSource.
  • Les modifications dynamiques apportées aux données de liste actualisent entièrement la liste au lieu d’appliquer une mise à jour incrémentielle.
  • Le pipeline de manipulation des données n’a pas encore été implémenté
  • Le remplissage de tous les composants d’expérience utilisateur sur une ardoise n’est pas encore entièrement pris en charge.
  • Les nœuds DataSourceJson doivent implémenter l’interface IDataNode pour être interopérables avec DataSourceObjects.