支援應用程式內更新 (Unreal Engine)

本指南說明如何使用 Unreal Engine 支援應用程式中的應用程式內更新。針對實作使用 Kotlin 或 Java 程式設計語言,以及使用原生程式碼 (C/C++)Unity 的情況,我們也分別提供了專屬指南。

Unreal Engine SDK 總覽

Play 應用程式內更新 API 屬於 Play Core SDK 系列的一部分。Unreal Engine 的 API 提供 UInAppUpdatesManager 類別,可處理應用程式與 Play API 之間的通訊。提出要求後,應用程式就能使用 EAppUpdateErrorCode 查看要求的狀態。

支援的 Unreal Engine 版本

外掛程式支援 Unreal Engine 5.0 和後續所有版本。

設定開發環境

  1. 從 GitHub 存放區下載 Play Unreal Engine 外掛程式

  2. 複製 Unreal Engine 專案中 Plugins 資料夾內的 GooglePlay 資料夾。

  3. 開啟 Unreal Engine 專案,然後依序點選「Edit」→「Plugins」

  4. 搜尋「Google Play」,然後勾選「已啟用」核取方塊。

  5. 重新啟動遊戲專案並觸發建構作業。

  6. 開啟專案的 Build.cs 檔案,並將 PlayInAppUpdates 模組新增至 PublicDependencyModuleNames

    using UnrealBuildTool;
    
    public class MyGame : ModuleRules
    {
      public MyGame(ReadOnlyTargetRules Target) : base(Target)
      {
        // ...
    
        PublicDependencyModuleNames.Add("PlayInAppUpdates");
    
        // ...
      }
    }
    

檢查是否有可用的更新

提出更新要求前,請先檢查應用程式是否有可用的更新。請使用 UInAppUpdatesManager::RequestInfo 檢查更新:

MyClass.h

void MyClass::OnRequestInfoOperationCompleted(
  EAppUpdateErrorCode ErrorCode,
  UAppUpdateInfo* UpdateInfo)
{
  // Check the resulting error code.
  if (ErrorCode == EAppUpdateErrorCode::AppUpdate_NO_ERROR)
  {
    // Check AppUpdateInfo's UpdateAvailability, UpdatePriority,
    // IsUpdateTypeAllowed(), ... and decide whether to ask the user
    // to start an in-app update.
  }
}

MyClass.cpp

void MyClass::CheckForUpdateAvailability()
{
  // Create a delegate to bind the callback function.
  FRequestInfoOperationCompletedDelegate Delegate;

  // Bind the completion handler (OnRequestInfoOperationCompleted) to the delegate.
  Delegate.BindDynamic(this, &MyClass::OnRequestInfoOperationCompleted);

  // Initiate the request info operation, passing the delegate to handle the result.
  GetGameInstance()
    ->GetSubsystem<UInAppUpdatesManager>()
    ->RequestInfo(Delegate);
}

傳回的 UAppUpdateInfo 例項包含更新可用性狀態。如果應用程式內更新作業正在進行中,執行個體也會回報進行中的更新狀態。

檢查更新是否過時

除了檢查是否有可用的更新,建議您也同時確認自從使用者上次收到 Play 商店的更新通知後已過了多久。這可以幫助您判斷是否要啟動彈性更新還是立即更新。例如,您可以等待幾天再通知使用者進行彈性更新,接著過幾天後提出需要立即更新。

您可以利用 UAppUpdateInfo:GetClientVersionStalenessDays 查看更新在 Play 商店中推出的天數。

int32 ClientVersionStalenessDays = UpdateInfo->GetClientVersionStalenessDays();

檢查更新的優先順序

您可以使用 Google Play Developer API 設定每項更新的優先順序。這可讓應用程式決定向使用者推薦更新的強度。舉例來說,您可以運用下列策略設定更新的優先順序:

  • 使用者介面微幅調整:低度優先等級更新;不需要提出彈性更新和立即更新。
  • 效能提升:中度優先等級更新;要求彈性更新。
  • 重大安全性更新:高度優先等級更新;要求立即更新。

為了判定優先等級,Google Play 使用一個介於 0 到 5 之間的整數值,其中 0 是預設值,5 是最高優先順序。如要設定更新的優先等級,請使用 Google Play Developer API 中 Edits.tracks.releases 下的 inAppUpdatePriority 欄位。系統會將此發行版本中所有新增版本的優先等級視同此發行版本的優先等級。只能在推出新版本時才能設定優先順序,而且日後無法更改。

請按照 Play Developer API 說明文件所述,使用 Google Play Developer API 設定優先順序。應用程式內更新優先順序應在 Edit.tracks: update 方法中傳遞的 Edit.tracks 資源中指定。以下範例說明如何發布版本為 88 和 inAppUpdatePriority 5 的應用程式:

{
  "releases": [{
      "versionCodes": ["88"],
      "inAppUpdatePriority": 5,
      "status": "completed"
  }]
}

在應用程式的程式碼中,您可以使用 UAppUpdateInfo::UpdatePriority 查看特定更新的優先順序等級:

int32 Priority = UpdateInfo->GetPriority();

開始更新

確認有可用的更新後,您可以使用 UInAppUpdatesManager::StartUpdate 要求更新。提出更新要求前,請確認您已經取得最新的 UAppUpdateInfo 物件。您也必須建立 UAppUpdateOptions 物件,才能設定更新流程。

以下範例針對即時更新流程建立 UAppUpdateOptions 物件:

// Creates an UAppUpdateOptions defining an immediate in-app
// update flow and its parameters.
UAppUpdateOptions* Options = NewObject<UAppUpdateOptions>();
Options->CreateOptions(EAppUpdateType::AppUpdate_TYPE_IMMEDIATE);

以下範例針對彈性更新流程建立 UAppUpdateOptions 物件:

// Creates an UAppUpdateOptions defining a flexible in-app
// update flow and its parameters.
UAppUpdateOptions* Options = NewObject<UAppUpdateOptions>();
Options->CreateOptions(EAppUpdateType::AppUpdate_TYPE_FLEXIBLE);

UAppUpdateOptions 物件也包含 IsAssetPackDeletionAllowed 函式,可用於定義是否允許更新在裝置儲存空間有限的情況下清除資產包。這個欄位預設為 false,但您可以使用 UAppUpdateOptions::SetAssetPackDeletionAllowed 將欄位改設為 true

// Sets the AssetPackDeletionAllowed field to true.
Options->SetAssetPackDeletionAllowed(true);

後續步驟取決於您要求的是彈性更新,還是立即更新

處理彈性更新

取得最新的 UAppUpdateInfo 物件和正確設定的 UAppUpdateOptions 物件後,您可以呼叫 UInAppUpdatesManager::StartUpdate 來要求更新流程。

MyClass.h

void MyClass::OnStartUpdateOperationCompleted(EAppUpdateErrorCode ErrorCode)
{
  // ...
}

MyClass.cpp

// .cpp
void MyClass::StartUpdate()
{
  // Create a delegate to bind the callback function.
  FUpdateOperationCompletedDelegate Delegate;

  // Bind the completion handler (OnStartUpdateOperationCompleted) to the delegate.
  Delegate.BindDynamic(this, &MyClass::OnStartUpdateOperationCompleted);

  // Initiate the start update operation, passing the delegate to handle the result.
  GetGameInstance()
    ->GetSubsystem<UInAppUpdatesManager>()
    ->StartUpdate(UpdateInfo, UpdateOptions, Delegate);
}

為提供彈性更新流程,您必須在下載完成後成功觸發應用程式安裝更新。方法是呼叫 InAppUpdatesManager::CompleteUpdate,如以下範例所示:

MyClass.h

void MyClass::OnCompleteUpdateOperationCompleted(EAppUpdateErrorCode ErrorCode)
{
  // ...
}

MyClass.cpp

void MyClass::CompleteFlexibleUpdate()
{
  // Create a delegate to bind the callback function.
  FUpdateOperationCompletedDelegate Delegate;

  // Bind the completion handler (OnCompleteUpdateOperationCompleted) to the delegate.
  Delegate.BindDynamic(this, &MyClass::OnCompleteUpdateOperationCompleted);

  // Initiate the complete update operation, passing the delegate to handle the result.
  GetGameInstance()
    ->GetSubsystem<UInAppUpdatesManager>()
    ->CompleteUpdate(UpdateInfo, UpdateOptions, Delegate);
}

處理立即更新

取得最新的 UAppUpdateInfo 物件和正確設定的 UAppUpdateOptions 物件後,您可以呼叫 InAppUpdatesManager::StartUpdate 來要求更新流程。

MyClass.h

void MyClass::OnStartUpdateOperationCompleted(EAppUpdateErrorCode ErrorCode)
{
  // ...
}

MyClass.cpp

void MyClass::StartUpdate()
{
  // Create a delegate to bind the callback function.
  FUpdateOperationCompletedDelegate Delegate;

  // Bind the completion handler (OnStartUpdateOperationCompleted) to the delegate.
  Delegate.BindDynamic(this, &MyClass::OnStartUpdateOperationCompleted);

  // Initiate the start update operation, passing the delegate to handle the result.
  GetGameInstance()
    ->GetSubsystem<UInAppUpdatesManager>()
    ->StartUpdate(UpdateInfo, UpdateOptions, Delegate);
}

針對立即更新流程,Google Play 會顯示使用者確認對話方塊。使用者接受要求後,Google Play 會自動下載並安裝更新,並在安裝成功後重新啟動更新版的應用程式。

處理錯誤

本節將說明常見錯誤的解決方法。

  • 如果 UInAppUpdatesManager::StartUpdate 傳回 AppUpdate_INVALID_REQUEST 錯誤,表示 UAppUpdateInfo 無效。請先確認從 UInAppUpdatesManager::RequestInfo 傳回的 UAppUpdateInfo 物件並非空值,再開始更新流程。
  • 如果 UInAppUpdatesManager::StartUpdate 傳回 AppUpdate_NOT_ALLOWED 錯誤,表示 UAppUpdateOptions 物件指示的更新類型不允許使用可用的更新。啟動更新流程之前,請檢查 UAppUpdateInfo 物件是否指示允許所選更新類型。

後續步驟

測試應用程式的應用程式內更新,以確認整合是否正常運作。