FOS Localization
Version 1.0.1 · exige FOS Essentials Core 1.0.0 ou plus récent
Traduit les textes et les images d’un monde VRChat dans autant de langues que voulu, édités dans une vraie table plutôt que dans deux tableaux sans lien, avec un aller-retour CSV pour les traducteurs et la mémorisation du choix du joueur d’une visite à l’autre. Exige FOS Essentials Core 1.0.0.
Mise en place
Section intitulée « Mise en place »- Créez un GameObject vide et ajoutez Add Component > FOS Essentials > Localization > Locale Manager.
- Remplissez Language codes (
en,fr,es,de) et Language names (English,Français,Español,Deutsch). La première est la langue pivot vers laquelle toutes les autres retombent : mettez donc en premier celle dans laquelle vous écrivez le monde. - Ouvrez FOS Essentials > FOS Localization > Translation Table et ajoutez vos clés.
- Sur chaque texte de votre interface, ajoutez Add Component > FOS Essentials > Localization > Localized Text, pointez-le vers le manager et donnez-lui sa clé.
- Pour le sélecteur de langue, ajoutez Language Button à chaque bouton, un par
langue. Son inspecteur câble le
OnClickpour vous.
Composants
Section intitulée « Composants »| Composant | Rôle |
|---|---|
FOSLocaleManager |
Un par monde. Porte les langues, la table et la langue courante. |
FOSLocalizedText |
Relie une clé à un TMP_Text ou à un Text hérité. |
FOSLocalizedImage |
Remplace un sprite selon la langue. |
FOSLanguageButton |
Bascule le monde dans une langue, avec un état sélectionné optionnel. |
Tout ici est local. Aucune variable synchronisée, aucun trafic réseau, aucun ownership. Deux joueurs côte à côte n’ont aucune raison de lire la même langue, et synchroniser le choix reviendrait à ce que l’un le perde chaque fois que l’autre clique.
La table de traduction
Section intitulée « La table de traduction »FOS Essentials > FOS Localization > Translation Table, ou le bouton dans l’inspecteur du
manager. Une ligne par clé, une colonne par langue, et les cellules vides sont colorées
pour qu’un trou se voie au lieu d’être cherché.
| Couleur | Signification |
|---|---|
| Rouge | La première langue est vide. Rien vers quoi retomber : le monde affichera #cle. |
| Ambre | Une autre langue est vide. Le monde retombe sur la première langue. |
La première langue déclarée est le pivot : c’est vers elle que retombent toutes les autres. Mettez en premier celle dans laquelle vous écrivez réellement le monde.
La barre d’outils filtre par texte — la recherche regarde aussi dans les traductions, donc une phrase repérée en jeu suffit à retrouver sa clé — et Untranslated only réduit la table aux lignes qui demandent encore du travail.
Pourquoi la table n’est pas dans l’inspecteur
Section intitulée « Pourquoi la table n’est pas dans l’inspecteur »Les clés et les traductions sont stockées dans deux tableaux, volontairement masqués de
l’inspecteur. La grille est à plat : la traduction j de la clé i se trouve en
i × langues + j. Une clé ajoutée à la main dans le tableau, sans sa ligne de cellules,
décale d’un cran tous les textes suivants — sans erreur, sans rien de visible à l’écran,
et sans moyen de reconstituer l’original. La fenêtre est donc le seul chemin d’écriture,
et elle maintient les deux tableaux en phase.
Ajouter ou retirer une langue dans l’inspecteur ne pose en revanche aucun problème : le manager signale l’écart et répare la grille, en déplaçant chaque traduction à sa nouvelle position.
Export CSV écrit toute la table, une ligne par clé, une colonne par langue, avec les codes de langue en en-tête. Import CSV la relit.
L’import est une fusion, jamais un remplacement :
- Une clé présente dans le fichier mais absente de la table est ajoutée.
- Une clé de la table absente du fichier est laissée telle quelle.
- Une colonne dont l’en-tête ne correspond à aucune langue déclarée est ignorée — une colonne de commentaires ne coûte rien.
- Une cellule vide n’écrase jamais une traduction existante.
Une seule langue peut donc partir en relecture et revenir sans le moindre risque pour les autres, et un traducteur qui rend une colonne à moitié faite ne détruit rien.
Le fichier est écrit en UTF-8 avec BOM. Sans lui, Excel ouvre le fichier dans la page de codes locale et massacre tous les accents, ce qui est de loin la façon la plus courante de rater un aller-retour de traduction.
Les clés
Section intitulée « Les clés »Une clé est un identifiant, pas une phrase : menu.title, rules.adult.warning,
teleport.button.spawn. Préfixez par domaine pour qu’une famille reste groupée une fois
la table triée — le bouton Sort classe les clés par ordre alphabétique en emportant
leurs traductions, et c’est ce qui rend visible le membre manquant d’une famille.
Une clé absente s’affiche #la.cle en jeu. C’est délibéré : un trou de traduction doit se
remarquer, ce qu’une étiquette vide ne fait jamais.
Les retours à la ligne s’écrivent \n dans la table. Un champ d’inspecteur ne peut pas
recevoir un vrai retour à la ligne, et un aller-retour CSV n’y survivrait pas.
La langue du joueur
Section intitulée « La langue du joueur »VRChat ne dit pas à un monde dans quelle langue est le client d’un joueur. Il n’existe aucune API pour cela, donc aucun outil ne peut la détecter — celui-ci compris. Un joueur arrive dans la langue par défaut et change à la main.
Ce qu’on peut faire, c’est mémoriser son choix. Avec Remember the choice activé, la
langue est écrite dans les PlayerData de VRChat et restaurée à la visite suivante de ce
monde.
- Rien ne quitte le monde, et rien n’est partagé avec les autres joueurs.
- Le choix est enregistré sous le code de la langue, jamais sous son indice : réordonner ou insérer une langue ne déplace donc pas silencieusement tout le monde.
- Une langue retirée du monde depuis la dernière visite d’un joueur le laisse sur la langue par défaut plutôt que sur rien.
Les PlayerData ne sont pas lisibles au Start. La langue par défaut est appliquée
immédiatement et la langue enregistrée la remplace à OnPlayerRestored : c’est pourquoi
un joueur qui revient peut voir une image de la langue par défaut.
La recherche est résolue une seule fois, au Start : chaque FOSLocalizedText
retient l’indice de sa clé et ne cherche plus jamais. Un changement de langue devient
alors une lecture indexée par texte.
Chercher par nom à chaque changement — la façon évidente d’écrire cela — coûte textes × clés comparaisons de chaînes chaque fois que quelqu’un clique sur un drapeau. Sur une interface de tablette avec cent étiquettes et deux cents clés, cela fait vingt mille comparaisons de chaînes par clic, en Udon.
Les composants s’enregistrent eux-mêmes auprès du manager : il n’y a donc aucune liste à remplir à la main, ni rien à mettre à jour quand une page gagne une étiquette.
Scripting
Section intitulée « Scripting »| Appel | Sur | Effet |
|---|---|---|
FOSSetLanguage(int) |
FOSLocaleManager |
Change de langue et enregistre le choix |
FOSCurrentLanguage() |
FOSLocaleManager |
Indice de la langue affichée |
FOSIndexOfLanguage(string) |
FOSLocaleManager |
Indice d’un code de langue, -1 si inconnu |
FOSIndexOfKey(string) |
FOSLocaleManager |
Indice d’une clé, -1 si inconnue. À appeler une fois |
FOSTextAt(int) |
FOSLocaleManager |
Traduction d’une clé déjà résolue |
FOSText(string) |
FOSLocaleManager |
Traduction d’une clé, recherche comprise |
FOSRegister(UdonSharpBehaviour) |
FOSLocaleManager |
Suivre les changements de langue |
SelectLanguage() |
FOSLanguageButton |
L’action du contrôle |
N’importe quel UdonSharpBehaviour peut appeler FOSRegister(this) et exposer un
FOSApplyLanguage() public — il sera alors prévenu à chaque changement, exactement comme
les composants livrés ici. C’est le point d’extension pour tout ce que ce pack ne couvre
pas : une source audio par langue, un lecteur vidéo, la texture d’un panneau.
Notes et limites
Section intitulée « Notes et limites »- Un manager par monde est le montage prévu. Plusieurs fonctionnent, mais chacun a sa table et sa langue courante, et un joueur qui change l’un ne change pas l’autre.
- Les textes créés à l’exécution ne sont pas pris en compte. Appelez
FOSRegisterdessus vous-même. - La langue n’est pas synchronisée, par choix. Voir plus haut.
- Quest et PC se comportent à l’identique : il n’y a pas de code spécifique à une plateforme, et il ne pourrait pas y en avoir — Udon est compilé une seule fois pour les deux.
