Passer au contenu principal
Cette rubrique présente une brève procédure pas à pas d’utilisation de l’API C++ de Game Chat 2 pour ajouter une communication vocale et textuelle à votre jeu.

Prérequis

Game Chat 2 exige que votre projet ait été configuré pour le GDK. Pour savoir comment effectuer cette configuration, consultez Prise en main du Microsoft Game Development Kit. La compilation de Game Chat 2 nécessite l’inclusion de l’en-tête principal GameChat2.h. Pour que l’édition des liens réussisse, votre projet doit également inclure GameChat2Impl.h dans au moins une unité de compilation (nous recommandons un en-tête précompilé commun, car ces implémentations de fonctions stub sont petites et faciles à générer « inline » pour le compilateur). L’interface de Game Chat 2 n’impose pas à un projet de choisir entre une compilation en C++/CX et une compilation en C++ traditionnel. Elle peut être utilisée avec l’un ou l’autre. L’implémentation ne lève pas non plus d’exceptions pour signaler les erreurs non fatales. Vous pouvez donc l’utiliser facilement dans des projets sans exceptions, si vous le souhaitez. L’implémentation lève toutefois des exceptions pour signaler les erreurs fatales. (Pour plus de détails, consultez la section Modèle de défaillance plus loin dans cette rubrique.)

Initialisation

Commencez à interagir avec la bibliothèque en initialisant l’instance singleton de Game Chat 2 avec des paramètres qui s’appliquent pendant toute la durée de l’initialisation du singleton. L’instance singleton est initialisée en appelant chat_manager::initialize, comme indiqué ci-dessous.
Vous devez vous inscrire aux événements de suspension et de reprise via RegisterAppStateChangeNotification. Lors de la suspension, vous devez nettoyer Game Chat 2 avec chat_manager::cleanup(). Lors de la reprise, vous devez réinitialiser Game Chat 2. Il risque de planter si vous tentez de l’utiliser au-delà d’un cycle de suspension/reprise.

Configuration des utilisateurs

Ajout d’utilisateurs à votre titre Microsoft Game Development Kit (GDK)

Avant d’ajouter des utilisateurs à l’instance de Game Chat 2, assurez-vous qu’ils ont été ajoutés au titre GDK. Cela s’effectue à l’aide de l’API XUserAddAsync. Pour plus d’informations sur l’utilisation de cette API, consultez Identité utilisateur et XUser. Une fois que vous disposez du XUserHandle de l’utilisateur que vous souhaitez ajouter à Game Chat 2, vous devez obtenir l’ID d’utilisateur XBOX (XUID) de l’utilisateur à l’aide de l’API XUserGetId. L’utilisateur doit être en ligne, et vous devez avoir son consentement pour cette étape. XUserGetId fournit le XUID sous la forme d’un uint64_t. Vous devez convertir le XUID en std::wstring pour l’utiliser avec Game Chat 2. Voici un exemple de code qui montre comment ajouter un utilisateur à Game Chat 2 une fois que vous disposez d’un XUserHandle.
Sachez que l’appel de XUserResolveIssueWithUiAsync affiche une boîte de dialogue système.

Ajout d’utilisateurs à Game Chat 2

Une fois l’instance initialisée, vous devez ajouter les utilisateurs locaux à l’instance de Game Chat 2 à l’aide de chat_manager::add_local_user. Dans cet exemple, l’utilisateur A représente un utilisateur local.
Ajoutez ensuite les utilisateurs distants ainsi que les identificateurs qui représentent le « point de terminaison » distant sur lequel se trouve chaque utilisateur. Un point de terminaison est une instance de l’application qui s’exécute sur un appareil distant. Dans cet exemple, l’utilisateur B se trouve sur le point de terminaison X. Les utilisateurs C et D se trouvent sur le point de terminaison Y. L’identificateur « 1 » est attribué arbitrairement au point de terminaison X, et l’identificateur « 2 » au point de terminaison Y. Informez Game Chat 2 des utilisateurs distants à l’aide des appels suivants.
Configurez ensuite la relation de communication entre chaque utilisateur distant et l’utilisateur local. Dans cet exemple, supposons que les utilisateurs A et B font partie de la même équipe. La communication bidirectionnelle est autorisée. c_communicationRelationshipSendAndReceiveAll est une constante définie dans GameChat2.h pour représenter la communication bidirectionnelle. Définissez la relation de l’utilisateur A avec l’utilisateur B à l’aide de chat_user_local::set_communication_relationship.
Supposons que les utilisateurs C et D sont des « spectateurs » et doivent pouvoir écouter l’utilisateur A, mais pas parler. c_communicationRelationshipSendAll est une constante définie dans GameChat2.h pour représenter cette communication unidirectionnelle. Définissez les relations comme suit.
Pour des exemples de paramètres de relation pour les quatre utilisateurs locaux, consultez la section Scénarios plus loin dans cette rubrique. Si, à un moment donné, des utilisateurs distants ont été ajoutés à l’instance singleton sans avoir été configurés pour communiquer avec des utilisateurs locaux, ce n’est pas un problème. Cela peut se produire dans les scénarios où les utilisateurs constituent des équipes ou peuvent changer librement de canal vocal. Game Chat 2 ne met en cache des informations (par exemple, les relations de confidentialité et la réputation) que pour les utilisateurs qui ont été ajoutés à l’instance; il est donc utile d’informer Game Chat 2 de tous les utilisateurs possibles, même s’ils ne peuvent parler à aucun utilisateur local à un moment donné. Enfin, supposons que l’utilisateur D a quitté la partie et doit être retiré de l’instance locale de Game Chat 2. Cela peut être effectué à l’aide de chat_manager::remove_user, comme indiqué ci-dessous.
L’appel de chat_manager::remove_user() peut invalider l’objet utilisateur. Si vous utilisez la manipulation audio en temps réel, consultez Durée de vie des utilisateurs du clavardage pour plus d’informations. Sinon, l’objet utilisateur est invalidé immédiatement lors de l’appel de chat_manager::remove_user(). Une restriction subtile concernant le moment où les utilisateurs peuvent être retirés est détaillée dans la section Traitement des changements d’état plus loin dans cette rubrique.

Traitement des trames de données

Game Chat 2 ne dispose pas de sa propre couche de transport. Celle-ci doit être fournie par l’application. Ce branchement est géré par les appels réguliers et fréquents de l’application à la paire de méthodes chat_manager::start_processing_data_frames() et chat_manager::finish_processing_data_frames(). C’est au moyen de ces méthodes que Game Chat 2 fournit les données sortantes à l’application. Ces méthodes sont conçues pour s’exécuter rapidement. Elles peuvent être interrogées fréquemment sur un thread réseau dédié. Cela offre un emplacement pratique pour récupérer toutes les données en file d’attente sans se soucier de l’imprévisibilité de la synchronisation réseau ou de la complexité des rappels multithread. Lorsque chat_manager::start_processing_data_frames() est appelée, toutes les données en file d’attente sont présentées dans un tableau de pointeurs vers des structures game_chat_data_frame. Les applications doivent parcourir le tableau, inspecter les points de terminaison cibles et utiliser leur couche réseau pour transmettre les données aux instances distantes appropriées de l’application. Une fois toutes les structures game_chat_data_frame du tableau traitées, le tableau doit être renvoyé à Game Chat 2 pour libérer les ressources en appelant chat_manager:finish_processing_data_frames(). C’est ce qu’illustre l’exemple suivant.
Plus les trames de données sont traitées fréquemment, plus la latence audio perçue par l’utilisateur est faible. L’audio est regroupé en trames de données de 40 ms. Il s’agit de la période d’interrogation suggérée.

Traitement des changements d’état

Game Chat 2 fournit des mises à jour à l’application, comme les messages texte reçus, au moyen des appels réguliers et fréquents de l’application à la paire de méthodes chat_manager::start_processing_state_changes() et chat_manager::finish_processing_state_changes(). Ces méthodes s’exécutent rapidement, de sorte qu’elles peuvent être appelées à chaque trame graphique dans votre boucle de rendu de l’interface utilisateur. Cela offre un emplacement pratique pour récupérer toutes les modifications en file d’attente sans se soucier de l’imprévisibilité de la synchronisation réseau ou de la complexité des rappels multithread. Lorsque chat_manager::start_processing_state_changes() est appelée, toutes les mises à jour en file d’attente sont présentées dans un tableau de pointeurs vers des structures game_chat_state_change. Les applications doivent parcourir le tableau, inspecter la structure de base pour déterminer son type plus spécifique, convertir la structure de base vers le type détaillé correspondant, puis traiter la mise à jour de manière appropriée. Une fois tous les objets game_chat_state_change actuellement disponibles du tableau traités, le tableau doit être renvoyé à Game Chat 2 pour libérer les ressources en appelant chat_manager::finish_processing_state_changes(). C’est ce qu’illustre l’exemple suivant.
Comme chat_manager::remove_user() invalide immédiatement la mémoire associée à un objet utilisateur, et que les changements d’état peuvent contenir des pointeurs vers des objets utilisateur, chat_manager::remove_user() ne doit pas être appelée pendant le traitement des changements d’état.

Clavardage textuel

Pour envoyer un message de clavardage textuel, utilisez chat_user::chat_user_local::send_chat_text(). C’est ce qu’illustre l’exemple suivant.
Game Chat 2 génère une trame de données contenant ce message. Les points de terminaison cibles de la trame de données sont ceux associés aux utilisateurs qui ont été configurés pour recevoir du texte de l’utilisateur local. Lorsque les données sont traitées par les points de terminaison distants, le message est exposé au moyen de game_chat_text_chat_received_state_change. Comme pour le clavardage vocal, les restrictions de privilèges et de confidentialité sont respectées pour le clavardage textuel. Si une paire d’utilisateurs a été configurée pour autoriser le clavardage textuel, mais que des restrictions de privilèges ou de confidentialité interdisent cette communication, le message texte est abandonné.

Accessibilité

L’accessibilité exige la prise en charge de la saisie et de l’affichage du clavardage textuel. La saisie de texte est requise car, même sur les plateformes ou dans les genres de jeux qui n’ont historiquement pas fait un usage répandu du clavier physique, les utilisateurs peuvent configurer le système pour utiliser des technologies d’assistance de synthèse vocale. De même, l’affichage du texte est requis, car les utilisateurs peuvent configurer le système pour utiliser la reconnaissance vocale. Ces préférences peuvent être détectées sur les utilisateurs locaux en appelant respectivement les méthodes chat_user::chat_user_local::text_to_speech_conversion_preference_enabled() et chat_user::chat_user_local::speech_to_text_conversion_preference_enabled(). Nous vous recommandons d’activer le texte de manière conditionnelle, en fonction des préférences de l’utilisateur.

Synthèse vocale

Lorsqu’un utilisateur a activé la synthèse vocale, chat_user::chat_user_local::text_to_speech_conversion_preference_enabled() retourne true. Lorsque cet état est détecté, l’application doit fournir une méthode de saisie de texte. Une fois que vous disposez de la saisie de texte fournie par un clavier réel ou virtuel, transmettez la chaîne à la méthode chat_user::chat_user_local::synthesize_text_to_speech(). Game Chat 2 détecte et synthétise des données audio basées sur la chaîne et sur la préférence de voix d’accessibilité de l’utilisateur. C’est ce qu’illustre l’exemple suivant.
L’audio synthétisé dans le cadre de cette opération est transmis à tous les utilisateurs qui ont été configurés pour recevoir l’audio de cet utilisateur local. Si chat_user::chat_user_local::synthesize_text_to_speech() est appelée pour un utilisateur qui n’a pas activé la synthèse vocale, Game Chat 2 n’effectue aucune action.

Reconnaissance vocale

Lorsqu’un utilisateur a activé la reconnaissance vocale, chat_user::chat_user_local::speech_to_text_conversion_preference_enabled() retourne true. Lorsque cet état est détecté, l’application doit être prête à fournir une interface utilisateur associée aux messages de clavardage transcrits. Game Chat 2 transcrit automatiquement l’audio de chaque utilisateur distant et l’expose au moyen d’une structure game_chat_transcribed_chat_received_state_change.

Considérations relatives aux performances de la reconnaissance vocale

Lorsque la reconnaissance vocale est activée, l’instance de Game Chat 2 de chaque appareil distant établit une connexion WebSocket avec le point de terminaison des services vocaux. Chaque client Game Chat 2 distant charge l’audio vers le point de terminaison des services vocaux au moyen de ce WebSocket. Le point de terminaison des services vocaux retourne de temps à autre un message de transcription à l’appareil distant. L’appareil distant envoie ensuite le message de transcription (c’est-à-dire un message texte) à l’appareil local. Le message transcrit est transmis par Game Chat 2 à l’application pour qu’elle l’affiche. Par conséquent, le principal coût en performances de la reconnaissance vocale est l’utilisation du réseau. La majeure partie du trafic réseau correspond au chargement de l’audio encodé. Le WebSocket charge l’audio déjà encodé par Game Chat 2 dans le chemin de clavardage vocal « normal ». L’application contrôle le débit binaire au moyen de chat_manager::set_audio_encoding_bitrate.

Interface utilisateur

Partout où une interface utilisateur est présentée aux utilisateurs, en particulier dans une liste de gamertags comme un tableau des scores, nous vous recommandons d’afficher également des icônes de micro coupé ou de prise de parole pour informer l’utilisateur. Pour ce faire, appelez chat_user::chat_indicator() afin de récupérer une énumération game_chat_user_chat_indicator qui représente l’état instantané actuel du clavardage pour cet utilisateur. L’exemple suivant montre comment récupérer la valeur de l’indicateur d’un objet chat_user pointé par la variable chatUserA afin de déterminer une valeur de constante d’icône particulière à affecter à une variable iconToShow.
La valeur signalée par chat_user::chat_indicator() est appelée à changer fréquemment, par exemple lorsque les joueurs commencent et arrêtent de parler. Elle est donc conçue pour permettre aux applications de l’interroger à chaque trame d’interface utilisateur.

Coupure du son

La méthode chat_user::chat_user_local::set_microphone_muted() permet de modifier l’état de coupure du microphone d’un utilisateur local. Lorsque le microphone est coupé, aucun audio n’est capturé à partir de ce microphone. Si l’utilisateur se trouve sur un appareil partagé, comme Kinect, l’état de coupure s’applique à tous les utilisateurs. La méthode chat_user::chat_user_local::microphone_muted() permet de récupérer l’état de coupure du microphone d’un utilisateur local. Cette méthode indique uniquement si le microphone de l’utilisateur local a été coupé de manière logicielle au moyen d’un appel à chat_user::chat_user_local::set_microphone_muted(). Elle ne reflète pas une coupure contrôlée par le matériel, par exemple au moyen d’un bouton du casque de l’utilisateur. Il n’existe aucune méthode permettant de récupérer l’état de coupure matérielle de l’appareil audio d’un utilisateur au moyen de Game Chat 2. La méthode chat_user::chat_user_local::set_remote_user_muted() permet de modifier l’état de coupure d’un utilisateur distant vis-à-vis d’un utilisateur local particulier. Lorsque l’utilisateur distant est rendu muet, l’utilisateur local n’entend aucun audio et ne reçoit aucun message texte de sa part.

Coupure automatique en cas de mauvaise réputation

En règle générale, les utilisateurs distants ne sont pas rendus muets au départ. Game Chat 2 démarre les utilisateurs à l’état muet lorsque :
  1. L’utilisateur distant n’est pas ami avec l’utilisateur local.
  2. L’utilisateur distant présente un indicateur de mauvaise réputation.
Lorsque des utilisateurs sont rendus muets en raison de cette opération, chat_user::chat_indicator() retourne game_chat_user_chat_indicator::reputation_restricted. Cet état est remplacé par le premier appel à chat_user::chat_user_local::set_remote_user_muted() qui inclut l’utilisateur distant comme utilisateur cible.

Privilèges et confidentialité

En plus de la relation de communication configurée par le jeu, Game Chat 2 applique les restrictions de privilèges et de confidentialité. Game Chat 2 effectue les recherches de restrictions de privilèges et de confidentialité lors du premier ajout d’un utilisateur. La méthode chat_user::chat_indicator() de l’utilisateur retourne toujours game_chat_user_chat_indicator::silent jusqu’à ce que ces opérations soient terminées. Si la communication avec un utilisateur est affectée par une restriction de privilèges ou de confidentialité, la méthode chat_user::chat_indicator() de l’utilisateur retourne game_chat_user_chat_indicator::platform_restricted. Les restrictions de communication de la plateforme s’appliquent à la fois au clavardage vocal et au clavardage textuel. Il n’existe aucun cas où le clavardage textuel serait bloqué par une restriction de la plateforme sans que le clavardage vocal le soit, ou inversement. chat_user::chat_user_local::get_effective_communication_relationship() permet de déterminer si des utilisateurs ne peuvent pas communiquer parce que les opérations de privilèges et de confidentialité ne sont pas terminées. Elle retourne la relation de communication appliquée par Game Chat 2 sous la forme de game_chat_communication_relationship_flags, ainsi que la raison pour laquelle cette relation peut différer de la relation configurée, sous la forme d’une énumération game_chat_communication_relationship_adjuster. Par exemple, si les opérations de recherche sont toujours en cours, la valeur de game_chat_communication_relationship_adjuster sera game_chat_communication_relationship_adjuster::initializing. Cette méthode ne doit pas être utilisée pour influencer l’interface utilisateur. (Pour plus d’informations, consultez la section Interface utilisateur plus haut dans cette rubrique.) Si Game Chat 2 rencontre un problème de privilèges, celui-ci est signalé dans le changement d’état communication_relationship_adjuster_changed. Si Game Chat 2 ne parvient pas à récupérer les privilèges de l’utilisateur pour une raison irrémédiable, cela est signalé sous la forme d’un ajusteur game_chat_communication_relationship_adjuster::privilege_check_failure. Si Game Chat 2 ne parvient pas à récupérer les privilèges de l’utilisateur pour une raison que l’utilisateur pourrait résoudre, cela est signalé sous la forme d’un ajusteur game_chat_communication_relationship_adjuster::resolve_user_issue. S’il manque à l’utilisateur des privilèges qui pourraient être résolus au moyen d’une interface utilisateur, cela est signalé sous la forme d’un ajusteur game_chat_communication_relationship_adjuster::privilege. Dans ces cas, la communication est restreinte. Voici un exemple montrant comment vérifier si un utilisateur rencontre l’un des problèmes courants suivants.
  1. Les utilisateurs doivent donner leur consentement aux services XBOX pour que Game Chat 2 puisse vérifier les privilèges.
  2. Le compte de l’utilisateur est configuré pour refuser des privilèges (par exemple, s’il s’agit d’un compte enfant qui ne peut donc pas utiliser le clavardage).
Pour les problèmes signalés avec l’ajusteur game_chat_communication_relationship_adjuster::privilege, vous pouvez appeler XUserResolvePrivilegeWithUiAsync avec XUserPrivilegeOptions::None et XUserPrivilege::Communications pour tenter de résoudre le problème. Pour les problèmes signalés avec l’ajusteur game_chat_communication_relationship_adjuster::resolve_user_issue, vous pouvez appeler XUserResolveIssueWithUiAsync avec nullptr comme URL pour tenter de résoudre le problème. Nous vous recommandons d’afficher une interface utilisateur indiquant l’existence d’un problème de privilèges. Laissez l’utilisateur décider s’il souhaite tenter de résoudre le problème, au moyen d’un bouton ou d’une option de menu. L’utilisateur peut ne pas être en mesure ou ne pas souhaiter résoudre le problème. Si l’utilisateur résout le problème, la résolution prendra effet la prochaine fois que l’utilisateur sera ajouté à Game Chat 2.
chat_manager::remove_user() ne doit pas être appelée pendant le traitement des changements d’état (c’est-à-dire après l’appel de chat_manager::start_processing_state_changes() et avant l’appel correspondant de chat_manager::finish_processing_state_changes()). L’appel de chat_manager::remove_user() pendant le traitement des changements d’état peut invalider la mémoire associée à l’utilisateur retiré. Si vous voyez un ajusteur game_chat_communication_relationship_adjuster::privilege et souhaitez essayer de résoudre les privilèges de l’utilisateur, vous devez attendre la fin du traitement des changements d’état pour le faire.
Pour obtenir le XUserHandle à partir d’un XUID, ce qui est nécessaire pour appeler XUserResolvePrivilegeWithUiAsync, vous pouvez utiliser l’API XUserFindUserById pour obtenir un nouveau XUserHandle. Vous pouvez également conserver celui que vous avez obtenu avec XUserAddAsync et suivre le XUID qui lui correspond. Voici un exemple montrant comment résoudre ces problèmes.

Nettoyage

Lorsque l’application n’a plus besoin des communications au moyen de Game Chat 2, vous devez appeler chat_manager::cleanup(). Cela permet à Game Chat 2 de récupérer les ressources qui ont été allouées à la gestion des communications.

Modèle de défaillance

L’implémentation de Game Chat 2 ne lève pas d’exceptions pour signaler les erreurs non fatales. Vous pouvez donc l’utiliser facilement dans des projets sans exceptions, si vous le souhaitez. Game Chat 2 lève toutefois des exceptions pour vous informer des erreurs fatales. Ces erreurs résultent d’une mauvaise utilisation de l’API, comme l’ajout d’un utilisateur à l’instance de Game Chat avant l’initialisation de celle-ci ou l’accès à un objet utilisateur après son retrait de l’instance de Game Chat 2. Ces erreurs sont censées être détectées tôt dans le développement et peuvent être corrigées en modifiant le modèle utilisé pour interagir avec Game Chat 2. Lorsqu’une telle erreur se produit, une indication de sa cause est affichée dans le débogueur avant que l’exception soit levée.

Configuration des scénarios courants

Appuyer pour parler

La fonctionnalité Appuyer pour parler doit être implémentée à l’aide de chat_user::chat_user_local::set_microphone_muted(). Appelez set_microphone_muted(false) pour autoriser la parole et set_microphone_muted(true) pour la restreindre. Cette méthode offre la réponse la plus rapide de Game Chat 2.

Équipes

Supposons que les utilisateurs A et B font partie de l’équipe bleue, et les utilisateurs C et D de l’équipe rouge. Chaque utilisateur se trouve dans une instance distincte de l’application. Sur l’appareil de l’utilisateur A :
Sur l’appareil de l’utilisateur B :
Sur l’appareil de l’utilisateur C :
Sur l’appareil de l’utilisateur D :

Diffusion

Supposons que l’utilisateur A est le chef et donne des ordres. Les utilisateurs B, C et D peuvent uniquement écouter. Chaque joueur se trouve sur un appareil distinct. Sur l’appareil de l’utilisateur A :
Sur l’appareil de l’utilisateur B :
Sur l’appareil de l’utilisateur C :
Sur l’appareil de l’utilisateur D :

Documentation de référence de l’API

Voir aussi

Présentation de Game Chat 2 Manipulation audio en temps réel Sommaire de l’API (GameChat2) Microsoft Game Development Kit
Dernière modification le 8 octobre 2026