Documentation

Démarrage rapide Unity

Le SDK Unity, ce sont deux paquets UPM pour Unity 6000.2 et plus : le même moteur que les têtes .NET, et une tête Unity avec un transport UnityWebRequest, un stockage de fichiers sous Application.persistentDataPath, les invites d'évaluation natives et un panneau UI Toolkit.

1. Ajouter les paquets

Les deux paquets sont livrés en archives. Téléchargez les deux (version 0.3.4) :

Ajoutez les deux fichiers .tgz au dépôt de votre projet (par exemple sous Packages/vendor/) et référencez-les par file: dans Packages/manifest.json. Les chemins sont relatifs au dossier Packages.

{
  "dependencies": {
    "com.mubold.wordsareflowing.core": "file:vendor/com.mubold.wordsareflowing.core-0.3.4.tgz",
    "com.mubold.wordsareflowing": "file:vendor/com.mubold.wordsareflowing-0.3.4.tgz"
  }
}

2. Créer la boucle et le panneau

WordsAreFlowingUnity.Create construit un IFeedbackLoop à partir d'un WordsAreFlowingUnityOptions (la ApiKey est obligatoire). Il n'y a pas de conteneur : vous gardez la boucle vous-même. Appelez-le depuis Start, pas depuis Awake ni un constructeur — il crée un GameObject caché.

using UnityEngine;
using UnityEngine.UIElements;
using WordsAreFlowing.Sdk.Core.Engine;
using WordsAreFlowing.Unity;
using WordsAreFlowing.Unity.Platform;
using WordsAreFlowing.Unity.Ui;

public class Feedback : MonoBehaviour
{
    [SerializeField] UIDocument document;
    IFeedbackLoop loop;
    FeedbackAskPanel panel;

    async void Start()
    {
        loop = WordsAreFlowingUnity.Create(new WordsAreFlowingUnityOptions
        {
            ApiKey = "waf_live_…",
            AppVersion = Application.version
        });
        panel = new FeedbackAskPanel(loop, CoroutineRunner.Create());
        document.rootVisualElement.Add(panel.Root);
        await loop.InitializeAsync();
    }

    public async void OnLevelCompleted()
    {
        await loop.TrackAsync("level_completed");
    }

    void OnDestroy() => panel?.Dispose();
}

Create remplit Platform à partir de Application.platform et indique lui-même la version du SDK. InitializeAsync charge les règles en cache, puis va chercher les nouvelles si le réseau le permet. TrackAsync fonctionne comme sur la page .NET et retourne une décision de la même façon.

3. La demande privée : FeedbackAskPanel

FeedbackAskPanel est une simple classe C#, pas un MonoBehaviour. Ajoutez son élément Root où vous voulez ; il se cache lui-même et s'abonne à DecisionMade, et s'ouvre quand une décision le demande. Il affiche le même texte que le composant Blazor, en anglais ou en français selon la culture d'interface courante, ou un FeedbackAskTexts que vous lui passez. Si un envoi échoue, le texte du joueur est conservé et une ligne d'erreur s'affiche ; rien n'est renvoyé pour vous.

Pour votre propre porte « Envoyer un commentaire », appelez Open avec un nom de déclencheur. Le panneau n'appelle jamais TrackAsync, donc aucun des deux chemins ne peut causer d'invite d'évaluation. Closed est émis chaque fois qu'il se ferme. Appelez Dispose quand vous en avez fini, sinon son gestionnaire reste attaché à la boucle.

Invites d'évaluation natives

iOS : le SDK appelle UnityEngine.iOS.Device.RequestStoreReview de Unity. Apple affiche la fenêtre au plus trois fois en 365 jours, toujours dans les versions de développement, et jamais depuis TestFlight.

Android : l'invite exige le module Play In-App Review de Google pour Unity (com.google.play.review). Il est facultatif : l'assemblage d'évaluation Android du SDK ne se compile que si ce module est installé. Sans lui, le SDK ne peut pas afficher d'invite sur Android : une décision d'invite s'y termine par None avec la raison prompter_declined. Dans l'éditeur et sur les lecteurs de bureau, la raison est prompter_unavailable, comme sur le Web.

Pour tester le chemin sur une version qui n'est sur aucune piste de magasin, passez votre propre flux comme reviewFlowOverride à Create ; DefaultFlowFor est ce qu'il utilise sinon.

Rester sur le fil principal

Ni le moteur ni la tête Unity n'utilisent ConfigureAwait(false), donc quand vous appelez la boucle depuis le fil principal de Unity, ses continuations — les écritures de compteurs, et votre gestionnaire DecisionMade — reviennent sur le fil principal. Gardez-le ainsi dans votre propre code : n'ajoutez pas ConfigureAwait(false) à un await dont la continuation touche un objet Unity.