Zu Play-Spieldiensten V2 (Unity) migrieren

In diesem Dokument wird beschrieben, wie Sie vorhandene Spiele vom Games v1-SDK zum Games v2-SDK migrieren. Für das Play Games-Plug-in für Unity, Version 10 und früher, wird das Games v1-SDK verwendet.

Hinweis

  • Sie müssen die Play Console bereits eingerichtet und den Unity-Editor installiert haben.

Google Play Games-Plug‑in für Unity herunterladen

Wenn Sie die neuesten Funktionen der Play Games-Dienste nutzen möchten, laden Sie die aktuelle Plugin-Version herunter und installieren Sie sie. Laden Sie es aus dem GitHub-Repository herunter.

Altes Plug-in entfernen

Entfernen Sie im Unity-Editor die folgenden Ordner oder Dateien.

Assets/GooglePlayGames

Assets/GeneratedLocalRepo/GooglePlayGames

Assets/Plugins/Android/GooglePlayGamesManifest.androidlib

Assets/Plugins/Android
Entfernen Sie die hervorgehobenen Ordner aus Ihrem Unity-Projekt.
Entfernen Sie die markierten Ordner in Ihrem Unity-Projekt (zum Vergrößern klicken).

Neues Plug-in in Ihr Unity-Projekt importieren

So importieren Sie das Plug-in in Ihr Unity-Projekt:

  1. Öffnen Sie Ihr Spieleprojekt.
  2. Klicken Sie im Unity-Editor auf Assets > Import Package > Custom Package, um die heruntergeladene Datei unitypackage in die Assets Ihres Projekts zu importieren.
  3. Achten Sie darauf, dass Ihre aktuelle Build-Plattform auf Android eingestellt ist.

    1. Klicken Sie im Hauptmenü auf Datei > Build-Einstellungen.

    2. Wählen Sie Android aus und klicken Sie auf Plattform wechseln.

    3. Unter Window > Google Play Games sollte ein neuer Menüpunkt angezeigt werden. Wenn nicht, aktualisieren Sie die Assets, indem Sie auf Assets > Aktualisieren klicken, und versuchen Sie dann noch einmal, die Build-Plattform festzulegen.

  4. Klicken Sie im Unity-Editor auf File > Build Settings > Player Settings > Other Settings (Datei > Build-Einstellungen > Player-Einstellungen > Weitere Einstellungen).

  5. Wählen Sie im Feld Ziel-API-Level eine Version aus.

  6. Geben Sie im Feld Scripting backend (Scripting-Backend) IL2CPP ein.

  7. Wählen Sie im Feld Zielarchitekturen einen Wert aus.

  8. Notieren Sie sich den Paketnamen package_name.Sie können diese Informationen später verwenden.

    Die Playereinstellungen in Ihrem Unity-Projekt
    Die Playereinstellungen in Ihrem Unity-Projekt.
  9. Android-Ressourcen aus der Play Console kopieren

  10. Android-Ressourcen zu Ihrem Unity-Projekt hinzufügen

Migrationspfade

Der richtige Migrationspfad für Ihr Spiel hängt davon ab, wie es Play Games Services v1 implementiert und wie es mit der Spieleridentität umgeht. Damit die Umstellung reibungslos verläuft und keine Spielerdaten verloren gehen, müssen Sie das Szenario ermitteln, das am besten zu Ihrer aktuellen Einrichtung passt, und die entsprechenden Schritte ausführen.

Option 1: Für Spiele, in denen IGA an die Play Games-Dienste-Spieler-ID gebunden ist

Dieses Szenario gilt für Spiele, in denen die Play Games-Dienste Player ID als einzige Kennung für das In-Game-Konto (IGA) eines Spielers verwendet werden und in denen zuvor keine OpenID angefordert oder gespeichert wurde. Die zentrale Herausforderung besteht darin, die vorhandene IGA mit einer primären Kennung (OpenID) zu verknüpfen, ohne die Verbindung zum Fortschritt des Spielers zu verlieren.

Der Migrationsablauf umfasst die folgenden Schritte:

  1. Wenn das Spiel gestartet wird, authentifiziert das Play Games-Dienste v2 SDK die Plattform automatisch und im Hintergrund.
  2. Das Spiel zeigt seinen Anmeldebildschirm an. Auf diesem Bildschirm muss anstelle der Schaltfläche Google Play die Schaltfläche Mit Google anmelden (SiWG) angezeigt werden. So integrieren Sie die Funktion:

    1. Laden Sie CredManBridge.java in Ihren Ordner herunter. Diese Java-Klasse dient als Brücke zwischen Unity und der androidx.credentials-Bibliothek.

      CredManBridge.java
      
      package com.wickedcube.trivialkart;
      import android.accounts.Account;
      import android.content.Context;
      import android.util.Log;
      import android.os.CancellationSignal;
      import androidx.credentials.CredentialManager;
      import androidx.credentials.GetCredentialRequest;
      import androidx.credentials.GetCredentialResponse;
      import androidx.credentials.exceptions.GetCredentialException;
      import androidx.credentials.exceptions.NoCredentialException;
      import com.google.android.libraries.identity.googleid.GetGoogleIdOption;
      import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential;
      import com.google.android.gms.auth.api.identity.AuthorizationClient;
      import com.google.android.gms.auth.api.identity.AuthorizationRequest;
      import com.google.android.gms.auth.api.identity.AuthorizationResult;
      import com.google.android.gms.common.api.ApiException;
      import com.google.android.gms.auth.api.identity.Identity;
      import com.google.android.gms.common.api.Scope;
      import com.unity3d.player.UnityPlayer;
      import java.util.Collections;
      import java.util.List;
      import java.util.concurrent.Executor;
      import java.util.concurrent.Executors;

      public class CredManBridge {

      // --- MODE 1: SILENT SIGN-IN (Called on Awake) --- // Tries to auto-select an authorized account. If it fails, it does NOT show UI. public static void signInSilent(Context context, String webClientId) { CredentialManager credentialManager = CredentialManager.create(context); CancellationSignal cancellationSignal = new CancellationSignal(); Executor executor = Executors.newSingleThreadExecutor();

      Log.d("CredMan", "Attempting Silent Sign-In...");

      GetGoogleIdOption silentOption = new GetGoogleIdOption.Builder() .setFilterByAuthorizedAccounts(true) // Strict: Only authorized accounts .setServerClientId(webClientId) .setAutoSelectEnabled(true) // Auto-select if possible .build();

      GetCredentialRequest silentRequest = new GetCredentialRequest.Builder() .addCredentialOption(silentOption) .build();

      credentialManager.getCredentialAsync( context, silentRequest, cancellationSignal, executor, new androidx.credentials.CredentialManagerCallback<GetCredentialResponse, GetCredentialException>() { @Override public void onResult(GetCredentialResponse result) { Log.d("CredMan", "Silent Sign-In Successful!"); handleSignInResult(context, result, webClientId); }

          @Override
          public void onError(GetCredentialException e) {
              // Send a specific error code so Unity knows to just stay on the Start Screen
              Log.d("CredMan", "Silent sign-in failed. Keeping UI hidden.");
              UnityPlayer.UnitySendMessage("AuthManager", "OnSignInError", "SilentFailed");
          }
      }
      

      ); }

      // --- MODUS 2: INTERAKTIVE ANMELDUNG (wird bei Schaltflächenklick aufgerufen) --- // Erzwingt die Anzeige des Blatts zur Kontoauswahl / „Konto hinzufügen“. public static void signInInteractive(Context context, String webClientId) { CredentialManager credentialManager = CredentialManager.create(context); CancellationSignal cancellationSignal = new CancellationSignal(); Executor executor = Executors.newSingleThreadExecutor();

      Log.d("CredMan", "Starting Interactive Sign-In...");

      GetGoogleIdOption interactiveOption = new GetGoogleIdOption.Builder() .setFilterByAuthorizedAccounts(false) // Show ALL accounts (and "Add Account") .setServerClientId(webClientId) .setAutoSelectEnabled(false) // Force the UI to show .build();

      GetCredentialRequest interactiveRequest = new GetCredentialRequest.Builder() .addCredentialOption(interactiveOption) .build();

      credentialManager.getCredentialAsync( context, interactiveRequest, cancellationSignal, executor, new androidx.credentials.CredentialManagerCallback<getcredentialresponse, getcredentialexception="">() { @Override public void onResult(GetCredentialResponse result) { Log.d("CredMan", "Interactive Sign-In Successful!"); handleSignInResult(context, result, webClientId); }</getcredentialresponse,>

          @Override
          public void onError(GetCredentialException e) {
              Log.e("CredMan", "Interactive Sign-In Canceled or Failed", e);
              UnityPlayer.UnitySendMessage("AuthManager", "OnSignInError", "Canceled");
          }
      }
      

      ); }

      private static void handleSignInResult(Context context, GetCredentialResponse result, String webClientId) { try { GoogleIdTokenCredential credential = GoogleIdTokenCredential.createFrom(result.getCredential().getData()); String email = credential.getId();

      Account account = new Account(email, "com.google");
      // Requesting GAMES_LITE scope to check for pre-existing V1 grants
      List<Scope> requestedScopes = Collections.singletonList(new Scope("https://www.googleapis.com/auth/games_lite"));
      
      AuthorizationRequest authRequest = new AuthorizationRequest.Builder()
          .setRequestedScopes(requestedScopes)
          .setAccount(account)
          .requestOfflineAccess(webClientId)
          .build();
      
      AuthorizationClient authClient = Identity.getAuthorizationClient(context);
      
      authClient.authorize(authRequest)
          .addOnSuccessListener(authorizationResult -> {
              if (authorizationResult.getServerAuthCode() != null) {
                  // CASE 1: RETURNING USER (Success)
                  // The user has already granted GAMES_LITE in the past.
                  // We got the code directly without showing UI.
                  Log.i("CredMan", "PGS v1: Existing grant found. Returning user detected. Auth Code retrieved.");
                  UnityPlayer.UnitySendMessage("AuthManager", "OnSignInSuccess", authorizationResult.getServerAuthCode());
              }
              else if (authorizationResult.hasResolution()) {
                  // CASE 2: NEW USER (PendingIntent)
                  // The user has NOT granted GAMES_LITE before. The API returned a PendingIntent
                  // (authorizationResult.getPendingIntent()) to show the consent screen.
                  // As per your flow, we DISCARD this intent and do not show UI.
                  Log.i("CredMan", "PGS v1: No existing grant (PendingIntent returned). This is a NEW user or they revoked access.");
                  Log.i("CredMan", "PGS v1: Discarding PendingIntent. Proceeding as New User.");
      
                  // Notify Unity that this is a "New User" so it can trigger V2 logic instead of failing
                  UnityPlayer.UnitySendMessage("AuthManager", "OnSignInError", "NewUser_NoGrant");
              }
              else {
                  // Edge Case: No code and no resolution?
                  Log.e("CredMan", "PGS v1: Authorization success but no Auth Code or Resolution returned.");
                  UnityPlayer.UnitySendMessage("AuthManager", "OnSignInError", "No Auth Code returned");
              }
          })
          .addOnFailureListener(e -> {
              // CASE 3: GENERIC FAILURE
              Log.e("CredMan", "PGS v1: Authorization failed completely.", e);
              UnityPlayer.UnitySendMessage("AuthManager", "OnSignInError", "Authorization Failed: " + e.getMessage());
          });
      

      } catch (Exception e) { UnityPlayer.UnitySendMessage("AuthManager", "OnSignInError", "Parsing Error: " + e.getMessage()); } } }

    2. Integration des Credential Manager:

      • Verwenden Sie GetGoogleIdOption mit setFilterByAuthorizedAccounts(true) für die automatische Anmeldung, um nur Nutzer anzumelden, die die App zuvor autorisiert haben.
      • Verwenden Sie setFilterByAuthorizedAccounts(false) für interaktive Anmeldungen, damit Nutzer ein Konto auswählen oder ein neues hinzufügen können.
    3. Bereichsanfrage:

      • Nachdem die Google-Anmeldedaten abgerufen wurden, wird ein AuthorizationRequest erstellt, in dem der spezifische Legacy-Bereich https://www.googleapis.com/auth/games_lite angefordert wird.
      • Dieser Bereich ist wichtig, da er dem Server die Berechtigung erteilt, die alte PlayerID des Nutzers nachzuschlagen.
    4. Ergebnisbehandlung:

      • Wenn der Nutzer die Berechtigung erteilt (oder zuvor erteilt hat), gibt die Bridge die ServerAuthCode an Unity zurück.
      • Wenn der Nutzer keine Berechtigung erteilt hat (Szenario für neue Nutzer), gibt die API PendingIntent zurück. In diesem Beispiel wird die Intention verworfen und der Nutzer wird als neuer Nutzer behandelt, um den Ablauf zu vereinfachen.
  3. Damit der Credential Manager und die Google Identity-Dienste unterstützt werden, müssen Sie die folgenden Abhängigkeiten zu Ihrer mainTemplate.gradle-Gradle-Konfiguration hinzufügen.

    dependencies {
    // Standard Unity dependencies
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    
    // Credential Manager and Identity Libraries
    implementation 'androidx.credentials:credentials:1.3.0'
    implementation 'androidx.credentials:credentials-play-services-auth:1.3.0'
    implementation 'com.google.android.libraries.identity.googleid:googleid:1.1.1'
    
    // Play Services Auth for legacy scope handling
    implementation 'com.google.android.gms:play-services-auth:21.2.0'
    }
    • Credential Manager:Verwaltet die grundlegende Identitätsorchestrierung und Benutzeroberfläche für die Kontoauswahl.
    • GoogleID-Bibliothek:Stellt speziell GetGoogleIdOption zum Abrufen von OpenID Connect-Tokens bereit.
    • Play-Dienste Auth:Erforderlich, um die Kompatibilität aufrechtzuerhalten und den GAMES_LITE-Bereich für den Abruf von Legacy-Player ID anzufordern.
  4. Wenn der Spieler auf die Schaltfläche „Mit Google anmelden“ tippt und ein Google-Konto auswählt, muss das Spiel zwei unterschiedliche Kennungen abrufen:

    • Die OpenID ist die primäre Kennung zum Binden des IGA.
    • Die Play Games-Dienste Player ID, die mit dem Bereich GAMES_LITE abgerufen werden, um die IGA des Spielers in Ihrem Backend-System zu suchen und die Verknüpfung auszuführen.
  5. Bei nachfolgenden Spielstarts können Spieler über den SiWG-Ablauf auf ihre IGA zugreifen, ohne dass Spiele Player ID als primäre ID verwenden müssen.

Schritt 4 kann mit einer clientseitigen Implementierung des Spiels ausgeführt werden.

  1. Der Entwickler ruft die Android Credential Manager API auf, um den Nutzer mit einem Google-Konto anzumelden.
  2. Nachdem der Nutzer SiwG abgeschlossen und ein Google-Konto ausgewählt hat, erhält der Entwickler ein Ergebnisobjekt mit dem ID-Token und der E‑Mail-Adresse.
  3. Der Entwickler erstellt ein Account-Objekt aus der E-Mail-Adresse.
  4. Der Entwickler ruft die Authorization API mit dem Bereich GAMES_LITE und dem Konto auf.
  5. Wenn für das Konto bereits eine Berechtigung für den GAMES_LITE-Bereich vorhanden ist, gibt die Authorization API ein Token direkt im Antwortobjekt zurück.
    1. Verwenden Sie das Antworttoken, um die Play Games-Dienste-Server aufzurufen und Player ID der Play Games-Dienste abzurufen.
    2. Der Entwickler prüft, ob die Play Games-Dienste Player ID mit einem In-Game-Konto verknüpft war.
      1. Der Entwickler weiß, dass es sich um einen wiederkehrenden Nutzer aus den Play Games-Diensten v1 handelt.
    3. Der Entwickler kann die neue GAIA-ID mit dem vorherigen Play Games-Dienste v1-Konto verknüpfen.
  6. Wenn das Konto keine vorhandene Einwilligung für den GAMES_LITE-Bereich hat, gibt die Authorization API ein PendingIntent zurück.
    1. Der Entwickler weiß, dass der Nutzer kein Konto aus Play Games-Dienste v1 hat.
    2. Der Entwickler kann das PendingIntent gefahrlos verwerfen, ohne eine Benutzeroberfläche anzuzeigen.

Option 2: Spiele, in denen IGA bereits an OpenID gebunden ist

Entwickler in dieser Gruppe haben den einfachsten Migrationspfad. Wenn das In‑Game-Konto Ihres Spiels bereits hauptsächlich an die OpenID gebunden ist, müssen Sie nur die standardmäßige technische SDK-Migration von Version 1 zu Version 2 durchführen, wie in den Schritten beschrieben.

Code für die automatische Anmeldung aktualisieren

Ersetzen Sie die Initialisierungsklasse PlayGamesClientConfiguration durch die Klasse PlayGamesPlatform.Instance.Authenticate(). Die Initialisierung und Aktivierung von PlayGamesPlatform ist nicht erforderlich. Durch Aufrufen von PlayGamesPlatform.Instance.Authenticate() wird das Ergebnis der automatischen Anmeldung abgerufen. Weitere Informationen zum empfohlenen Authentifizierungsablauf mit der Integration von Play Games-Diensten v2 finden Sie unter Richtlinie zur Nutzererfahrung für den idealen Authentifizierungsablauf.

C#

Suchen Sie im Unity-Editor nach den Dateien mit der Klasse PlayGamesClientConfiguration.

using GooglePlayGames;
using GooglePlayGames.BasicApi;
using UnityEngine.SocialPlatforms;

public void Start() {
    PlayGamesClientConfiguration config =
        new PlayGamesClientConfiguration.Builder()
    // Enables saving game progress
    .EnableSavedGames()
    // Requests the email address of the player be available
    // will bring up a prompt for consent
    .RequestEmail()
    // Requests a server auth code be generated so it can be passed to an
    // associated backend server application and exchanged for an OAuth token
    .RequestServerAuthCode(false)
    // Requests an ID token be generated. This OAuth token can be used to
    // identify the player to other services such as Firebase.
    .RequestIdToken()
    .Build();

    PlayGamesPlatform.InitializeInstance(config);
    // recommended for debugging:
    PlayGamesPlatform.DebugLogEnabled = true;
    // Activate the Google Play Games platform
    PlayGamesPlatform.Activate();
}

Aktualisieren Sie ihn auf Folgendes:

using GooglePlayGames;

public void Start() {
    PlayGamesPlatform.Instance.Authenticate(ProcessAuthentication);
}

internal void ProcessAuthentication(SignInStatus status) {
    if (status == SignInStatus.Success) {
        // Continue with Play Games Services
    } else {
        // Disable your integration with Play Games Services or show a login
        // button to ask users to sign-in. Clicking it should call
        // PlayGamesPlatform.Instance.ManuallyAuthenticate(ProcessAuthentication).
    }
}

Plattform für soziale Medien auswählen

Informationen zum Auswählen einer Social-Media-Plattform finden Sie unter Social-Media-Plattform auswählen.

Serverauthentifizierungscodes abrufen

Informationen zum Abrufen von serverseitigen Zugriffscodes finden Sie unter Serverauthentifizierungscodes abrufen.

Abmeldecode entfernen

Entfernen Sie den Code für die Abmeldung. Für die Play Games-Dienste ist keine Abmeldeschaltfläche im Spiel mehr erforderlich.

Entfernen Sie den im folgenden Beispiel gezeigten Code:

C#

// sign out
PlayGamesPlatform.Instance.SignOut();

Spiel testen

Testen Sie Ihr Spiel, um sicherzustellen, dass es wie vorgesehen funktioniert. Welche Tests Sie durchführen hängt von den Funktionen Ihres Spiels ab.

Im Folgenden finden Sie eine Liste mit häufig durchgeführten Tests.

  1. Erfolgreiche Anmeldung

    1. Die automatische Anmeldung funktioniert. Der Nutzer sollte beim Starten des Spiels in den Play-Spieldiensten angemeldet werden.

    2. Das Begrüßungs-Pop-up wird angezeigt.

      Beispiel für ein Begrüßungs-Pop-up
      Beispiel für ein Begrüßungs-Pop-up (zum Vergrößern klicken)

    3. Meldungen über eine erfolgreiche Anmeldung werden angezeigt. Führen Sie im Terminal den folgenden Befehl aus:

      adb logcat | grep com.google.android.

      Im folgenden Beispiel sehen Sie eine Meldung über eine erfolgreiche Anmeldung:

      [$PlaylogGamesSignInAction$SignInPerformerSource@e1cdecc
      number=1 name=GAMES_SERVICE_BROKER>], returning true for shouldShowWelcomePopup.
      [CONTEXT service_id=1 ]
  2. Einheitlichkeit der UI-Komponenten sicherstellen

    1. Pop-ups, Bestenlisten und Erfolge werden in der Benutzeroberfläche der Play Games-Dienste auf verschiedenen Bildschirmgrößen und in verschiedenen Ausrichtungen korrekt und einheitlich angezeigt.

    2. Die Abmeldeoption ist in der Benutzeroberfläche der Play Games-Dienste nicht sichtbar.

    3. Prüfen Sie, ob Sie die Spieler-ID abrufen können und ob die serverseitigen Funktionen wie erwartet funktionieren.

    4. Wenn das Spiel die serverseitige Authentifizierung verwendet, testen Sie den requestServerSideAccess-Ablauf gründlich. Achten Sie darauf, dass der Server den Authentifizierungscode empfängt und ihn gegen ein Zugriffstoken eintauschen kann. Testen Sie sowohl Erfolgs- als auch Fehlerszenarien für Netzwerkfehler und ungültige client ID-Szenarien.

Wenn Ihr Spiel eine der folgenden Funktionen verwendet hat, testen Sie sie, um sicherzustellen, dass sie wie vor der Migration funktionieren:

  • Bestenlisten: Punktzahlen senden und Bestenlisten ansehen. Prüfen Sie, ob die Namen der Spieler, die Rangfolge und die Punkte richtig angezeigt werden.
  • Erfolge: Schalten Sie Erfolge frei und prüfen Sie, ob sie in der Play Games-Benutzeroberfläche richtig aufgezeichnet und angezeigt werden.
  • Gespeicherte Spiele: Wenn das Spiel gespeicherte Spiele verwendet, muss das Speichern und Laden des Spielstands einwandfrei funktionieren. Das ist besonders wichtig, wenn Sie das Spiel auf mehreren Geräten und nach App-Updates testen.

Aufgaben nach der Migration

Führen Sie die folgenden Schritte aus, nachdem Sie zu Games v2 SDK migriert haben.

  1. Play App-Signatur verwenden

  2. AAB-Datei erstellen

  3. Internen Testrelease erstellen

  4. Anmeldedaten für das App-Signieren bestätigen