Tài liệu này mô tả cách di chuyển các trò chơi hiện có từ SDK games v1 sang SDK games v2. Trình bổ trợ Play Games cho Unity (phiên bản 10 trở về trước) sử dụng SDK của phiên bản 1.
Trước khi bắt đầu
- Đảm bảo rằng bạn đã thiết lập Play Console và cài đặt Unity Editor.
Tải trình bổ trợ Google Play Games cho Unity xuống
Để tận dụng các tính năng mới nhất trong dịch vụ trò chơi của Play, hãy tải xuống và cài đặt phiên bản trình bổ trợ mới nhất. Tải phiên bản này xuống từ kho lưu trữ GitHub.
Xoá trình bổ trợ cũ
Trong Unity Editor, hãy xoá các thư mục hoặc tệp sau.
Assets/GooglePlayGames Assets/GeneratedLocalRepo/GooglePlayGames Assets/Plugins/Android/GooglePlayGamesManifest.androidlib Assets/Plugins/Android
Nhập trình bổ trợ mới vào dự án Unity
Để nhập trình bổ trợ vào dự án Unity, hãy làm theo các bước sau:
- Mở dự án trò chơi của bạn.
- Trong Trình chỉnh sửa Unity, hãy nhấp vào Assets > Import Package > Custom Package (Nội dung > Nhập gói > Gói tuỳ chỉnh) để nhập tệp
unitypackageđã tải xuống vào nội dung của dự án. Đảm bảo rằng nền tảng bản dựng hiện tại của bạn được đặt là Android.
Trong trình đơn chính, hãy nhấp vào File > Build Settings (Tệp > Cài đặt bản dựng).
Chọn Android rồi nhấp vào Switch Platform (Chuyển nền tảng).
Sẽ có một mục mới trong trình đơn tại Window > Google Play Games (Cửa sổ > Google Play Games). Nếu không có, hãy làm mới nội dung bằng cách nhấp vào Assets > Refresh (Nội dung > Làm mới), sau đó thử đặt lại nền tảng bản dựng.
Trong Trình chỉnh sửa Unity, hãy nhấp vào File > Build Settings > Player Settings > Other Settings (Tệp > Cài đặt bản dựng > Cài đặt trình phát > Cài đặt khác).
Trong hộp cấp độ API mục tiêu, hãy chọn một phiên bản.
Trong hộp Scripting backend, hãy nhập
IL2CPP.Trong hộp Target architectures (Kiến trúc mục tiêu), hãy chọn một giá trị.
Ghi lại tên gói package_name.Bạn có thể sử dụng thông tin này sau.
Phần cài đặt trình phát trong dự án Unity.
Phương pháp di chuyển
Đường dẫn di chuyển phù hợp cho trò chơi của bạn phụ thuộc vào cách trò chơi đó triển khai Dịch vụ trò chơi của Play phiên bản 1 và xử lý danh tính người chơi. Để đảm bảo quá trình chuyển đổi diễn ra suôn sẻ và tránh mất dữ liệu người chơi, hãy xác định kịch bản phù hợp nhất với chế độ thiết lập hiện tại của bạn và làm theo các bước tương ứng.
Lựa chọn 1: Đối với những trò chơi có IGA được liên kết với mã nhận dạng người chơi trong Dịch vụ trò chơi của Play
Trường hợp này áp dụng cho những trò chơi đã sử dụng Player ID Dịch vụ trò chơi của Play làm mã nhận dạng duy nhất cho Tài khoản trong trò chơi (IGA) của người chơi và trước đây chưa từng yêu cầu hoặc lưu trữ OpenID. Thách thức chính là liên kết IGA hiện có với một giá trị nhận dạng chính (OpenID) mà không làm mất kết nối với tiến trình của người chơi.
Quy trình di chuyển bao gồm các bước sau:
- Khi trò chơi khởi chạy, SDK Dịch vụ trò chơi của Play phiên bản 2 sẽ tự động và âm thầm xác thực nền tảng.
Trò chơi sẽ hiện màn hình đăng nhập. Màn hình này phải có nút Đăng nhập bằng Google (SiWG), thay thế nút Google Play. Cách tích hợp:
Tải CredManBridge.java xuống thư mục của bạn. Lớp Java này đóng vai trò là cầu nối giữa Unity và thư viện
androidx.credentials.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"); } }); }
// --- MODE 2: INTERACTIVE SIGN-IN (Called on Button Click) --- // Forces the Account Selection / "Add Account" sheet to appear. 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()); } } }
Tích hợp Trình quản lý thông tin xác thực:
- Sử dụng
GetGoogleIdOptionvớisetFilterByAuthorizedAccounts(true)để đăng nhập thầm lặng, chỉ đăng nhập những người dùng đã uỷ quyền cho ứng dụng trước đó. - Sử dụng
setFilterByAuthorizedAccounts(false)để đăng nhập tương tác, cho phép người dùng chọn một tài khoản hoặc thêm một tài khoản mới.
- Sử dụng
Yêu cầu về phạm vi:
- Sau khi nhận được thông tin xác thực cơ bản của Google, thông tin này sẽ tạo một
AuthorizationRequestyêu cầu phạm vi cũ cụ thể: https://www.googleapis.com/auth/games_lite. - Phạm vi này rất quan trọng vì nó cấp cho máy chủ quyền tra cứu PlayerID cũ của người dùng.
- Sau khi nhận được thông tin xác thực cơ bản của Google, thông tin này sẽ tạo một
Xử lý kết quả:
- Nếu người dùng cấp quyền (hoặc đã cấp quyền trước đó), cầu nối sẽ trả về
ServerAuthCodecho Unity. - Nếu người dùng chưa cấp quyền (trường hợp Người dùng mới), API sẽ trả về
PendingIntent. Trong mẫu này, ý định sẽ bị loại bỏ và người dùng được coi là người dùng mới để đơn giản hoá quy trình.
- Nếu người dùng cấp quyền (hoặc đã cấp quyền trước đó), cầu nối sẽ trả về
Để hỗ trợ Trình quản lý thông tin xác thực và Dịch vụ nhận dạng của Google, hãy đảm bảo bạn đã thêm các phần phụ thuộc sau vào cấu hình gradle
mainTemplate.gradle.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' }
- Trình quản lý thông tin xác thực: Xử lý hoạt động điều phối danh tính cốt lõi và giao diện người dùng để chọn tài khoản.
- Thư viện GoogleID: Cụ thể là cung cấp
GetGoogleIdOptionđể truy xuất mã thông báoOpenIDConnect. - Xác thực Dịch vụ Play: Bắt buộc để duy trì khả năng tương thích và yêu cầu phạm vi
GAMES_LITEđể truy xuấtPlayer IDcũ.
Khi người chơi nhấn vào nút SiWG và chọn một Tài khoản Google, trò chơi phải truy xuất 2 giá trị nhận dạng riêng biệt:
OpenID, giá trị nhận dạng chính để liên kết IGA.Player IDcủa Dịch vụ trò chơi của Play, được truy xuất bằng cách sử dụng phạm viGAMES_LITE, để tra cứu IGA của người chơi trong hệ thống phụ trợ của bạn và thực hiện việc liên kết.
Trong những lần khởi chạy trò chơi tiếp theo, người chơi có thể truy cập vào IGA của họ bằng quy trình SiWG mà không yêu cầu trò chơi sử dụng
Player IDlàm giá trị nhận dạng chính.
Bạn có thể thực hiện bước 4 bằng cách triển khai phía máy khách của trò chơi.
- Nhà phát triển gọi Android Credential Manager API để đăng nhập người dùng bằng Tài khoản Google.
- Sau khi người dùng hoàn tất quy trình SiwG và chọn một Tài khoản Google, nhà phát triển sẽ nhận được một đối tượng kết quả, trong đó có mã thông báo nhận dạng và địa chỉ email.
- Nhà phát triển tạo một đối tượng Tài khoản từ địa chỉ email.
- Nhà phát triển gọi Authorization API bằng phạm vi
GAMES_LITEvà Tài khoản. - Nếu tài khoản có một quyền cấp trước trên phạm vi
GAMES_LITE, thì Authorization API sẽ trả về trực tiếp một mã thông báo trong đối tượng phản hồi.- Sử dụng mã thông báo phản hồi để gọi các máy chủ của Dịch vụ trò chơi của Play và truy xuất
Player IDcủa Dịch vụ trò chơi của Play. - Nhà phát triển xác minh xem Dịch vụ trò chơi của Play
Player IDcó được liên kết với một tài khoản trong trò chơi hay không.- Lập trình viên biết rằng đây là người dùng cũ từ Dịch vụ trò chơi của Play phiên bản 1.
- Nhà phát triển có thể liên kết mã nhận dạng gaia mới với tài khoản Dịch vụ trò chơi của Play v1 trước đó.
- Sử dụng mã thông báo phản hồi để gọi các máy chủ của Dịch vụ trò chơi của Play và truy xuất
- Hoặc, nếu tài khoản không có quyền truy cập được cấp trước trên phạm vi
GAMES_LITE, thì Authorization API sẽ trả về một PendingIntent.- Nhà phát triển biết rằng người dùng không có tài khoản hiện có trên Dịch vụ trò chơi của Play phiên bản 1.
- Nhà phát triển có thể loại bỏ PendingIntent một cách an toàn mà không hiển thị bất kỳ giao diện người dùng nào.
Cách 2: Đối với những trò chơi đã liên kết IGA với OpenID
Nhà phát triển trong nhóm này có lộ trình di chuyển đơn giản nhất. Nếu tài khoản trong trò chơi của bạn đã được liên kết chủ yếu với OpenID, thì bạn chỉ cần thực hiện quy trình di chuyển SDK kỹ thuật tiêu chuẩn từ phiên bản 1 sang phiên bản 2 như được nêu trong các bước.
Cập nhật mã tự động đăng nhập
Thay thế lớp khởi tạo PlayGamesClientConfiguration bằng lớp PlayGamesPlatform.Instance.Authenticate().
Bạn không cần khởi chạy và kích hoạt PlayGamesPlatform. Khi gọi PlayGamesPlatform.Instance.Authenticate(), hệ thống sẽ tìm nạp kết quả của tính năng tự động đăng nhập.
Để biết thêm thông tin về quy trình xác thực được đề xuất khi tích hợp Dịch vụ trò chơi của Play phiên bản 2, hãy xem Nguyên tắc về trải nghiệm người dùng cho quy trình xác thực lý tưởng.
C#
Trong Trình chỉnh sửa Unity, hãy tìm các tệp có lớp 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();
}
Và cập nhật nó như sau:
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).
}
}
Chọn một nền tảng mạng xã hội
Để chọn một nền tảng mạng xã hội, hãy xem phần chọn một nền tảng mạng xã hội.
Truy xuất mã xác thực máy chủ
Để lấy mã truy cập phía máy chủ, hãy xem phần truy xuất mã xác thực máy chủ.
Xoá mã đăng xuất
Xoá mã để đăng xuất. Dịch vụ trò chơi của Play không còn yêu cầu nút đăng xuất trong trò chơi nữa.
Xoá mã xuất hiện trong ví dụ sau:
C#
// sign out
PlayGamesPlatform.Instance.SignOut();
Kiểm thử trò chơi
Đảm bảo trò chơi của bạn hoạt động như thiết kế bằng cách kiểm thử. Các kiểm thử mà bạn thực hiện sẽ phụ thuộc vào các tính năng của trò chơi.
Sau đây là danh sách các kiểm thử thường gặp cần chạy.
Đăng nhập thành công.
Tính năng tự động đăng nhập hoạt động. Người dùng phải đăng nhập vào Dịch vụ trò chơi của Play khi khởi chạy trò chơi.
Cửa sổ bật lên chào mừng sẽ xuất hiện.
Ví dụ về cửa sổ chào mừng bật lên (nhấp để phóng to). Thông báo nhật ký thành công sẽ xuất hiện. Chạy lệnh sau trong dòng lệnh:
adb logcat | grep com.google.android.
Thông điệp nhật ký thành công sẽ xuất hiện trong ví dụ sau:
[
$PlaylogGamesSignInAction$SignInPerformerSource@e1cdecc number=1 name=GAMES_SERVICE_BROKER>], returning true for shouldShowWelcomePopup. [CONTEXT service_id=1 ]
Đảm bảo tính nhất quán của thành phần giao diện người dùng.
Cửa sổ bật lên, bảng xếp hạng và thành tích hiển thị chính xác và nhất quán trên nhiều kích thước màn hình và hướng trong giao diện người dùng (UI) của Dịch vụ trò chơi của Play.
Lựa chọn đăng xuất không xuất hiện trong giao diện người dùng của Dịch vụ trò chơi Play.
Đảm bảo bạn có thể truy xuất Mã nhận dạng người chơi thành công và nếu có, các chức năng phía máy chủ hoạt động như dự kiến.
Nếu trò chơi sử dụng phương thức xác thực phía máy chủ, hãy kiểm thử kỹ quy trình
requestServerSideAccess. Đảm bảo máy chủ nhận được mã uỷ quyền và có thể trao đổi mã đó để lấy mã truy cập. Kiểm thử cả trường hợp thành công và không thành công đối với lỗi mạng, trường hợpclient IDkhông hợp lệ.
Nếu trò chơi của bạn đang sử dụng bất kỳ tính năng nào sau đây, hãy kiểm thử các tính năng đó để đảm bảo chúng hoạt động giống như trước khi di chuyển:
- Bảng xếp hạng: Gửi điểm số và xem bảng xếp hạng. Kiểm tra thứ hạng và cách hiển thị tên và điểm số của người chơi sao cho chính xác.
- Thành tích: Mở khoá thành tích và xác minh rằng thành tích được ghi lại và hiển thị chính xác trong giao diện người dùng Play Games.
- Trò chơi đã lưu: Nếu trò chơi sử dụng tính năng trò chơi đã lưu, hãy đảm bảo rằng việc lưu và tải tiến trình trò chơi diễn ra suôn sẻ. Điều này đặc biệt quan trọng khi kiểm thử trên nhiều thiết bị và sau khi cập nhật ứng dụng.
Các việc cần làm sau khi di chuyển
Hãy hoàn tất các bước sau khi bạn đã di chuyển sang SDK trò chơi phiên bản 2.