Skip to main content
Este tema proporciona un breve tutorial sobre el uso de la API de C++ de Game Chat 2 para agregar comunicación de voz y texto a su juego.

Requisitos previos

Game Chat 2 requiere que su proyecto se haya configurado para el GDK. Para obtener más información sobre cómo configurarlo, consulte Introducción al Microsoft Game Development Kit. Para compilar Game Chat 2 es necesario incluir el encabezado principal GameChat2.h. Para que la vinculación sea correcta, su proyecto también debe incluir GameChat2Impl.h en al menos una unidad de compilación (se recomienda un encabezado precompilado común, ya que estas implementaciones de funciones stub son pequeñas y fáciles de generar como “inline” para el compilador). La interfaz de Game Chat 2 no requiere que un proyecto elija entre compilar con C++/CX o con C++ tradicional. Se puede usar con cualquiera de los dos. La implementación tampoco produce excepciones como medio de notificación de errores no irrecuperables. Puede consumirla fácilmente desde proyectos sin excepciones, si lo prefiere. Sin embargo, la implementación sí produce excepciones como medio de notificación de errores irrecuperables. (Para obtener más información, consulte la sección Modelo de errores más adelante en este tema).

Inicialización

Empiece a interactuar con la biblioteca inicializando la instancia singleton de Game Chat 2 con parámetros que se aplican a la duración de la inicialización del singleton. La instancia singleton se inicializa llamando a chat_manager::initialize, como se muestra a continuación.
Debe registrarse para los eventos de suspensión y reanudación mediante RegisterAppStateChangeNotification. Al suspender, debe limpiar Game Chat 2 con chat_manager::cleanup(). Al reanudar, debe reinicializar Game Chat 2. Podría bloquearse si intenta usarlo a través de un ciclo de suspensión y reanudación.

Configuración de usuarios

Adición de usuarios a su título del Microsoft Game Development Kit (GDK)

Antes de agregar usuarios a la instancia de Game Chat 2, asegúrese de que se hayan agregado al título del GDK. Esto se hace mediante la API XUserAddAsync. Para obtener más información sobre el uso de esta API, consulte Identidad de usuario y XUser. Después de tener el XUserHandle del usuario que desea agregar a Game Chat 2, debe obtener el identificador de usuario de XBOX (XUID) del usuario mediante la API XUserGetId. El usuario debe estar en línea y debe contar con el consentimiento del usuario para este paso. XUserGetId proporciona el XUID como un uint64_t. Debe convertir el XUID en un std::wstring para usarlo con Game Chat 2. A continuación se muestra un ejemplo de código que muestra cómo agregar un usuario a Game Chat 2 después de tener un XUserHandle.
Tenga en cuenta que llamar a XUserResolveIssueWithUiAsync muestra un cuadro de diálogo del sistema.

Adición de usuarios a Game Chat 2

Una vez inicializada la instancia, debe agregar los usuarios locales a la instancia de Game Chat 2 mediante chat_manager::add_local_user. En este ejemplo, el usuario A representa un usuario local.
A continuación, agregue los usuarios remotos y los identificadores que se usan para representar el “punto de conexión” remoto en el que se encuentra el usuario. Un punto de conexión es una instancia de la aplicación que se ejecuta en un dispositivo remoto. En este ejemplo, el usuario B está en el punto de conexión X. Los usuarios C y D están en el punto de conexión Y. Al punto de conexión X se le asigna arbitrariamente el identificador “1”. Al punto de conexión Y se le asigna arbitrariamente el identificador “2”. Informe a Game Chat 2 de los usuarios remotos con las siguientes llamadas.
A continuación, configure la relación de comunicación entre cada usuario remoto y el usuario local. En este ejemplo, suponga que el usuario A y el usuario B están en el mismo equipo. Se permite la comunicación bidireccional. c_communicationRelationshipSendAndReceiveAll es una constante definida en GameChat2.h para representar la comunicación bidireccional. Establezca la relación del usuario A con el usuario B mediante chat_user_local::set_communication_relationship.
Suponga que los usuarios C y D son “espectadores” y que se les debe permitir escuchar al usuario A, pero no hablar. c_communicationRelationshipSendAll es una constante definida en GameChat2.h para representar esta comunicación unidireccional. Establezca las relaciones de la manera siguiente.
Para ver ejemplos con la configuración de relaciones desde los cuatro usuarios locales, consulte la sección de escenarios más adelante en este tema. Si en algún momento hay usuarios remotos que se hayan agregado a la instancia singleton pero que no se hayan configurado para comunicarse con ningún usuario local, no hay problema. Esto es previsible en escenarios en los que los usuarios están determinando equipos o pueden cambiar arbitrariamente de canal de voz. Game Chat 2 solo almacena en caché información (por ejemplo, relaciones de privacidad y reputación) de los usuarios que se han agregado a la instancia, por lo que resulta útil informar a Game Chat 2 de todos los usuarios posibles, aunque no puedan hablar con ningún usuario local en un momento determinado. Por último, suponga que el usuario D ha abandonado el juego y debe quitarse de la instancia local de Game Chat 2. Esto se puede hacer mediante chat_manager::remove_user, como se muestra a continuación.
Llamar a chat_manager::remove_user() puede invalidar el objeto de usuario. Si usa la manipulación de audio en tiempo real, consulte Duración de los usuarios de chat para obtener más información. De lo contrario, el objeto de usuario se invalida inmediatamente cuando se llama a chat_manager::remove_user(). Una restricción sutil sobre cuándo se pueden quitar usuarios se detalla en la sección Procesamiento de cambios de estado más adelante en este tema.

Procesamiento de fotogramas de datos

Game Chat 2 no tiene su propia capa de transporte. La aplicación debe proporcionarla. Este complemento se administra mediante las llamadas regulares y frecuentes de la aplicación al par de métodos chat_manager::start_processing_data_frames() y chat_manager::finish_processing_data_frames(). Estos métodos son la forma en que Game Chat 2 proporciona datos salientes a la aplicación. Estos métodos están diseñados para funcionar con rapidez. Se pueden sondear con frecuencia en un subproceso de red dedicado. Esto proporciona un lugar conveniente para recuperar todos los datos en cola sin preocuparse por la imprevisibilidad de los tiempos de la red ni por la complejidad de las devoluciones de llamada multiproceso. Cuando se llama a chat_manager::start_processing_data_frames(), todos los datos en cola se notifican en una matriz de punteros a estructuras game_chat_data_frame. Las aplicaciones deben iterar por la matriz, inspeccionar los puntos de conexión de destino y usar la capa de red de la aplicación para entregar los datos a las instancias remotas adecuadas de la aplicación. Una vez que se haya terminado de usar la matriz con todas las estructuras game_chat_data_frame, la matriz debe devolverse a Game Chat 2 para liberar los recursos llamando a chat_manager:finish_processing_data_frames(). Esto se muestra en el ejemplo siguiente.
Cuanto mayor sea la frecuencia con que se procesen los fotogramas de datos, menor será la latencia de audio percibida por el usuario. El audio se agrupa en fotogramas de datos de 40 ms. Este es el período de sondeo sugerido.

Procesamiento de cambios de estado

Game Chat 2 proporciona actualizaciones a la aplicación, como los mensajes de texto recibidos, mediante las llamadas regulares y frecuentes de la aplicación al par de métodos chat_manager::start_processing_state_changes() y chat_manager::finish_processing_state_changes(). Estos métodos funcionan con rapidez, por lo que se pueden llamar en cada fotograma gráfico de su bucle de representación de la interfaz de usuario. Esto proporciona un lugar conveniente para recuperar todos los cambios en cola sin preocuparse por la imprevisibilidad de los tiempos de la red ni por la complejidad de las devoluciones de llamada multiproceso. Cuando se llama a chat_manager::start_processing_state_changes(), todas las actualizaciones en cola se notifican en una matriz de punteros a estructuras game_chat_state_change. Las aplicaciones deben iterar por la matriz, inspeccionar la estructura base para conocer su tipo más específico, convertir la estructura base al tipo más detallado correspondiente y, a continuación, controlar esa actualización según corresponda. Una vez que se haya terminado de usar la matriz con todos los objetos game_chat_state_change disponibles actualmente, la matriz debe devolverse a Game Chat 2 para liberar los recursos llamando a chat_manager::finish_processing_state_changes(). Esto se muestra en el ejemplo siguiente.
Dado que chat_manager::remove_user() invalida inmediatamente la memoria asociada a un objeto de usuario, y los cambios de estado pueden contener punteros a objetos de usuario, no se debe llamar a chat_manager::remove_user() mientras se procesan cambios de estado.

Chat de texto

Para enviar chat de texto, use chat_user::chat_user_local::send_chat_text(). Esto se muestra en el ejemplo siguiente.
Game Chat 2 genera un fotograma de datos que contiene este mensaje. Los puntos de conexión de destino del fotograma de datos son los asociados a los usuarios que se han configurado para recibir texto del usuario local. Cuando los puntos de conexión remotos procesan los datos, el mensaje se expone mediante game_chat_text_chat_received_state_change. Al igual que con el chat de voz, las restricciones de privilegios y privacidad se respetan en el chat de texto. Si un par de usuarios se ha configurado para permitir el chat de texto, pero las restricciones de privilegios o privacidad no permiten esa comunicación, el mensaje de texto se descarta.

Accesibilidad

La accesibilidad requiere admitir la entrada y la visualización de chat de texto. La entrada de texto es necesaria porque, incluso en plataformas o géneros de juego que históricamente no han tenido un uso generalizado del teclado físico, los usuarios pueden configurar el sistema para usar tecnologías de asistencia de texto a voz. Del mismo modo, la visualización de texto es necesaria porque los usuarios pueden configurar el sistema para usar voz a texto. Estas preferencias se pueden detectar en los usuarios locales llamando a los métodos chat_user::chat_user_local::text_to_speech_conversion_preference_enabled() y chat_user::chat_user_local::speech_to_text_conversion_preference_enabled(), respectivamente. Se recomienda habilitar el texto de forma condicional, en función de las preferencias del usuario.

Texto a voz

Cuando un usuario tiene habilitado el texto a voz, chat_user::chat_user_local::text_to_speech_conversion_preference_enabled() devuelve true. Cuando se detecta este estado, la aplicación debe proporcionar un método de entrada de texto. Después de obtener la entrada de texto proporcionada por un teclado real o virtual, pase la cadena al método chat_user::chat_user_local::synthesize_text_to_speech(). Game Chat 2 detecta y sintetiza datos de audio basados en la cadena y en la preferencia de voz de accesibilidad del usuario. Esto se muestra en el ejemplo siguiente.
El audio que se sintetiza como parte de esta operación se transporta a todos los usuarios que se han configurado para recibir audio de este usuario local. Si se llama a chat_user::chat_user_local::synthesize_text_to_speech() en un usuario que no tiene habilitado el texto a voz, Game Chat 2 no realiza ninguna acción.

Voz a texto

Cuando un usuario tiene habilitada la conversión de voz a texto, chat_user::chat_user_local::speech_to_text_conversion_preference_enabled() devuelve true. Cuando se detecta este estado, la aplicación debe estar preparada para proporcionar una interfaz de usuario asociada a los mensajes de chat transcritos. Game Chat 2 transcribe automáticamente el audio de cada usuario remoto y lo expone mediante una estructura game_chat_transcribed_chat_received_state_change.

Consideraciones de rendimiento de la conversión de voz a texto

Cuando la conversión de voz a texto está habilitada, la instancia de Game Chat 2 de cada dispositivo remoto inicia una conexión WebSocket con el punto de conexión de los servicios de voz. Cada cliente remoto de Game Chat 2 carga audio en el punto de conexión de los servicios de voz a través de este WebSocket. El punto de conexión de los servicios de voz devuelve ocasionalmente un mensaje de transcripción al dispositivo remoto. A continuación, el dispositivo remoto envía el mensaje de transcripción (es decir, un mensaje de texto) al dispositivo local. Game Chat 2 entrega el mensaje transcrito a la aplicación para que lo represente. Por lo tanto, el costo de rendimiento principal de la conversión de voz a texto es el uso de la red. La mayor parte del tráfico de red es la carga de audio codificado. El WebSocket carga audio que ya ha sido codificado por Game Chat 2 en la ruta “normal” del chat de voz. La aplicación tiene control sobre la velocidad de bits mediante chat_manager::set_audio_encoding_bitrate.

Interfaz de usuario

Se recomienda que, en cualquier lugar donde se muestre una interfaz de usuario a los usuarios, especialmente en una lista de gamertags como un marcador, también se muestren iconos de silenciado o hablando como comentarios para el usuario. Esto se hace llamando a chat_user::chat_indicator() para recuperar una enumeración game_chat_user_chat_indicator que representa el estado actual e instantáneo del chat de ese usuario. El siguiente ejemplo muestra cómo recuperar el valor del indicador de un objeto chat_user al que apunta la variable chatUserA para determinar un valor constante de icono concreto que asignar a una variable iconToShow.
Se espera que el valor notificado por chat_user::chat_indicator() cambie con frecuencia, por ejemplo, a medida que los jugadores empiezan y dejan de hablar. Por ello, está diseñado para permitir que las aplicaciones lo sondeen en cada fotograma de la interfaz de usuario.

Silenciado

El método chat_user::chat_user_local::set_microphone_muted() se puede usar para cambiar el estado de silencio del micrófono de un usuario local. Cuando el micrófono está silenciado, no se captura audio de ese micrófono. Si el usuario está en un dispositivo compartido, como Kinect, el estado de silencio se aplica a todos los usuarios. El método chat_user::chat_user_local::microphone_muted() se puede usar para recuperar el estado de silencio del micrófono de un usuario local. Este método solo refleja si el micrófono del usuario local se ha silenciado por software mediante una llamada a chat_user::chat_user_local::set_microphone_muted(). Este método no refleja un silencio controlado por hardware, por ejemplo, mediante un botón de los auriculares del usuario. No existe ningún método para recuperar el estado de silencio de hardware del dispositivo de audio de un usuario a través de Game Chat 2. El método chat_user::chat_user_local::set_remote_user_muted() se puede usar para cambiar el estado de silencio de un usuario remoto en relación con un usuario local concreto. Cuando el usuario remoto está silenciado, el usuario local no oirá ningún audio ni recibirá ningún mensaje de texto del usuario remoto.

Silencio automático por mala reputación

Normalmente, los usuarios remotos comienzan sin silenciar. Game Chat 2 inicia a los usuarios en estado silenciado cuando:
  1. El usuario remoto no es amigo del usuario local.
  2. El usuario remoto tiene una marca de mala reputación.
Cuando los usuarios están silenciados debido a esta operación, chat_user::chat_indicator() devuelve game_chat_user_chat_indicator::reputation_restricted. Este estado se invalida con la primera llamada a chat_user::chat_user_local::set_remote_user_muted() que incluya al usuario remoto como usuario de destino.

Privilegios y privacidad

Además de la relación de comunicación configurada por el juego, Game Chat 2 aplica restricciones de privilegios y privacidad. Game Chat 2 realiza búsquedas de restricciones de privilegios y privacidad cuando se agrega un usuario por primera vez. El chat_user::chat_indicator() del usuario siempre devuelve game_chat_user_chat_indicator::silent hasta que se hayan completado esas operaciones. Si la comunicación con un usuario se ve afectada por una restricción de privilegios o privacidad, el chat_user::chat_indicator() del usuario devuelve game_chat_user_chat_indicator::platform_restricted. Las restricciones de comunicación de la plataforma se aplican tanto al chat de voz como al de texto. Nunca se dará el caso de que el chat de texto esté bloqueado por una restricción de plataforma pero el chat de voz no, ni viceversa. chat_user::chat_user_local::get_effective_communication_relationship() se puede usar para ayudar a distinguir cuándo los usuarios no pueden comunicarse debido a operaciones de privilegios y privacidad incompletas. Devuelve la relación de comunicación aplicada por Game Chat 2 en forma de game_chat_communication_relationship_flags y el motivo por el que la relación puede no ser igual a la relación configurada en forma de una enumeración game_chat_communication_relationship_adjuster. Por ejemplo, si las operaciones de búsqueda siguen en curso, el game_chat_communication_relationship_adjuster será game_chat_communication_relationship_adjuster::initializing. Este método no debe usarse para influir en la interfaz de usuario. (Para obtener más información, consulte la sección Interfaz de usuario anteriormente en este tema). Si Game Chat 2 encuentra un problema de privilegios, se notificará en el cambio de estado communication_relationship_adjuster_changed. Si Game Chat 2 no puede recuperar el privilegio del usuario por un motivo irrecuperable, se notificará como un ajustador game_chat_communication_relationship_adjuster::privilege_check_failure. Si Game Chat 2 no puede recuperar el privilegio del usuario por un motivo que el usuario podría resolver, se notificará como un ajustador game_chat_communication_relationship_adjuster::resolve_user_issue. Si al usuario le faltan privilegios que podrían resolverse con la interfaz de usuario, se notificará como un ajustador game_chat_communication_relationship_adjuster::privilege. En estos casos, la comunicación estará restringida. A continuación se muestra un ejemplo de cómo comprobar si un usuario tiene uno de los siguientes problemas comunes.
  1. Los usuarios deben dar su consentimiento a los servicios de XBOX para que Game Chat 2 compruebe los privilegios.
  2. La cuenta del usuario está configurada para denegar privilegios (por ejemplo, por ser una cuenta infantil y, por tanto, no poder usar el chat).
Para los problemas notificados con el ajustador game_chat_communication_relationship_adjuster::privilege, puede llamar a XUserResolvePrivilegeWithUiAsync con XUserPrivilegeOptions::None y XUserPrivilege::Communications para intentar resolver el problema. Para los problemas notificados con el ajustador game_chat_communication_relationship_adjuster::resolve_user_issue, puede llamar a XUserResolveIssueWithUiAsync con nullptr como dirección URL para intentar resolver el problema. Se recomienda mostrar una interfaz de usuario que indique que hay un problema de privilegios. Permita que el usuario decida si desea intentar resolver el problema, ya sea presionando un botón o mediante una opción de menú. Es posible que el usuario no pueda o no quiera resolver el problema. Si el usuario resuelve el problema, se aplicará la próxima vez que se agregue el usuario a Game Chat 2.
No se debe llamar a chat_manager::remove_user() mientras se procesan cambios de estado (es decir, después de llamar a chat_manager::start_processing_state_changes() y antes de la llamada correspondiente a chat_manager::finish_processing_state_changes()). Llamar a chat_manager::remove_user() mientras se procesan cambios de estado puede invalidar la memoria asociada al usuario quitado. Si ve un ajustador game_chat_communication_relationship_adjuster::privilege y desea intentar resolver los privilegios del usuario, debe esperar hasta después de procesar los cambios de estado para intentarlo.
Para obtener el XUserHandle a partir de un XUID, que es necesario para llamar a XUserResolvePrivilegeWithUiAsync, puede usar la API XUserFindUserById para obtener un nuevo XUserHandle. Como alternativa, puede conservar el que adquirió con XUserAddAsync y realizar un seguimiento de a qué XUID se asigna. A continuación se muestra un ejemplo de cómo resolver estos problemas.

Limpieza

Cuando la aplicación ya no necesite las comunicaciones a través de Game Chat 2, debe llamar a chat_manager::cleanup(). Esto permite que Game Chat 2 recupere los recursos que se asignaron para administrar las comunicaciones.

Modelo de errores

La implementación de Game Chat 2 no produce excepciones como medio de notificación de errores no irrecuperables. Puede consumirla fácilmente desde proyectos sin excepciones, si lo prefiere. Sin embargo, Game Chat 2 sí produce excepciones para informarle de errores irrecuperables. Estos errores son el resultado de un uso incorrecto de la API, como agregar un usuario a la instancia de Game Chat antes de inicializar la instancia o acceder a un objeto de usuario después de que se haya quitado de la instancia de Game Chat 2. Se espera que estos errores se detecten al principio del desarrollo y se puedan corregir modificando el patrón que se usa para interactuar con Game Chat 2. Cuando se produce un error de este tipo, se imprime en el depurador una sugerencia sobre la causa del error antes de que se genere la excepción.

Cómo configurar escenarios populares

Pulsar para hablar

La funcionalidad de pulsar para hablar debe implementarse con chat_user::chat_user_local::set_microphone_muted(). Llame a set_microphone_muted(false) para permitir la voz y a set_microphone_muted(true) para restringirla. Este método proporciona la respuesta de menor latencia de Game Chat 2.

Equipos

Suponga que el usuario A y el usuario B están en el equipo azul, y que el usuario C y el usuario D están en el equipo rojo. Cada usuario está en una instancia única de la aplicación. En el dispositivo del usuario A:
En el dispositivo del usuario B:
En el dispositivo del usuario C:
En el dispositivo del usuario D:

Difusión

Suponga que el usuario A es el líder y da órdenes. Los usuarios B, C y D solo pueden escuchar. Cada jugador está en un dispositivo único. En el dispositivo del usuario A:
En el dispositivo del usuario B:
En el dispositivo del usuario C:
En el dispositivo del usuario D:

Documentación de referencia de la API

Consulte también

Introducción a Game Chat 2 Manipulación de audio en tiempo real Contenido de la API (GameChat2) Microsoft Game Development Kit
Última modificación el 28 de agosto de 2026