Ao integrar a entrega de recursos, os jogos do Unity podem acessar pacotes de recursos usando Addressables ou AssetBundles. Os Addressables são a solução de entrega de recursos mais recente e recomendada para jogos criados com Unity 2019.4 ou mais recente, enquanto os AssetBundles dão suporte a pacotes de recursos no Unity 2017.4 e 2018.4.
Addressables do Unity
Jogos criados com Unity 2019.4 ou versões mais recentes precisam usar Addressables (link em inglês) para a entrega de recursos no Android. O Unity oferece a API Play Asset Delivery (PAD) para processar pacotes de recursos do Android usando Addressables. Para saber informações sobre como usar Addressables, consulte o estes links (em inglês):
- Endereços acionáveis para o pacote Android
- Guia da PAD para Unity
- Documentação de referência da API PAD para Unity
Usar arquivos AssetBundle
Os jogos criados com Unity 2017.4 e 2018.4 podem usar arquivos AssetBundle para entrega de recursos no Android. Os arquivos AssetBundle (link em inglês) do Unity contêm recursos serializados que podem ser carregados pelo mecanismo do Unity enquanto o app está em execução. Esses arquivos são específicos da plataforma (por exemplo, criados para Android) e podem ser usados em combinação com pacotes de recursos. Geralmente, um arquivo AssetBundle é combinado em um único pacote que usa o mesmo nome do AssetBundle. Se você quiser mais flexibilidade na criação de um pacote de recursos, configure-o usando a API.
No ambiente de execução, use a classe Play Asset Delivery para Unity para extrair um AssetBundle empacotado em um pacote de recursos.
Pré-requisitos
- Configure o ambiente de desenvolvimento:
OpenUPM-CLI
Se você tiver a CLI do OpenUPM instalada, poderá instalar o registro do OpenUPM com o seguinte comando:
openupm add com.google.play.assetdelivery
OpenUPM
Abra as configurações do gerenciador de pacotes selecionando a opção de menu do Unity Edit > Project Settings > Package Manager.
Adicione o OpenUPM como um registro de escopo à janela do Gerenciador de pacotes:
Name: package.openupm.com URL: https://package.openupm.com Scopes: com.google.external-dependency-manager com.google.play.common com.google.play.core com.google.play.assetdelivery com.google.android.appbundle
Abra o menu do gerenciador de pacotes selecionando a opção de menu do Unity Window > Package Manager.
Defina o menu suspenso "Escopo do administrador" para selecionar Meus registros.
Selecione o pacote Google Play Integrity plugin for Unity na lista de pacotes e pressione Install.
Importar do GitHub
Faça o download da versão mais recente do
.unitypackage
no GitHub.Importe o arquivo
.unitypackage
selecionando a opção de menu do Unity Assets > Import package > Custom Package e importando todos os itens.
Configurar AssetBundles usando a interface
Configure cada AssetBundle em um pacote de recursos:
- Selecione Google > Android App Bundle > Asset Delivery Settings.
- Para selecionar pastas que contenham arquivos do AssetBundle diretamente, clique em Add Folder.
Para cada pacote, mude o Delivery Mode para Install Time, Fast Follow ou On demand. Resolva erros ou dependências e feche a janela.
Selecione Google > Build Android App Bundle para criar o pacote de apps.
(Opcional) Configure seu pacote de apps para que ele seja compatível com diferentes formatos de compactação de textura.
Configurar pacotes de recursos usando a API
Você pode configurar a entrega de recursos pelos scripts de editor, que podem ser executados como parte de um sistema de compilação automatizado.
Use a classe
AssetPackConfig
para definir quais recursos incluir em uma compilação do Android App Bundle, bem
como o modo de entrega dos recursos. Esses pacotes de recursos não precisam conter um
AssetBundle.
public void ConfigureAssetPacks { // Creates an AssetPackConfig with a single asset pack, named // examplePackName, containing all the files in path/to/exampleFolder. var assetPackConfig = new AssetPackConfig(); assetPackConfig.AddAssetsFolder("examplePackName", "path/to/exampleFolder", AssetPackDeliveryMode.OnDemand); // Configures the build system to use the newly created assetPackConfig when // calling Google > Build and Run or Google > Build Android App Bundle. AssetPackConfigSerializer.SaveConfig(assetPackConfig); // Alternatively, use BundleTool.BuildBundle to build an App Bundle from script. BuildBundle(new buildPlayerOptions(), assetPackConfig); }
Você também pode usar o método estático
BuildBundle
na classe Bundletool
para gerar um Android App Bundle com pacotes
de recursos, usando
BuildPlayerOptions (link em inglês)
e
AssetPackConfig
.
Observação: para conferir um tutorial guiado, consulte o codelab Como usar a Play Asset Delivery em jogos do Unity.
Integrar com a API Play Asset Delivery Unity
A API Unity Play Asset Delivery oferece a funcionalidade de solicitar pacotes de recursos, gerenciar downloads e acessar os recursos. Primeiro, adicione o plug-in do Unity ao projeto.
As funções usadas na API dependem de como você criou os pacotes de recursos.
Se você criou pacotes de recursos usando a IU do plug-in, selecione Pacotes de recursos configurados pelo plug-in.
Se você criou pacotes de recursos usando a API (ou a interface do plug-in), selecione Pacotes de recursos configurados pela API.
A API é semelhante, independentemente do tipo de entrega do pacote de recursos que você quer acessar. Essas etapas são mostradas no fluxograma a seguir.
Recuperar um pacote de recursos
Importe a
biblioteca Play Asset Delivery
e chame o método
RetrieveAssetPackAsync()
para fazer o download de um pacote de recursos se a versão mais recente do pacote ainda não
estiver disponível no disco.
using Google.Play.AssetDelivery; // After download, the assets and/or AssetBundles contained in the asset pack // are not loaded into memory. PlayAssetPackRequest request = PlayAssetDelivery.RetrieveAssetPackAsync(assetPackName);
Entrega na instalação
Um pacote de recursos configurado como install-time
fica imediatamente disponível na inicialização
do app, mas você precisa carregar os recursos na memória. Consulte
Carregar recursos na memória.
Entrega rápida e sob demanda
Essas seções se aplicam aos pacotes de recursos fast-follow
e on-demand
.
Verificar status
Cada pacote de recursos é armazenado em uma pasta separada no armazenamento interno do app.
Use o método
isDone()
para determinar se um pacote de recursos já foi transferido por download e está
disponível, ou se ocorreu um erro.
Monitorar o download
Consulte o objeto
PlayAssetPackRequest
para monitorar o
status
da solicitação:
// Download progress of request, between 0.0f and 1.0f. The value will always be // 1.0 for assets delivered as install-time. // NOTE: A value of 1.0 does not mean that the request has completed, only that // the DOWNLOADING stage is finished. float progress = request.DownloadProgress; // Returns the status of the retrieval request. // If the request completed successfully, this value should be AssetDeliveryStatus.Available. // If an error occurred, this value should be AssetDeliveryStatus.Failed. AssetDelivery status = request.Status; switch(status) { case AssetDeliveryStatus.Pending: // Asset pack download is pending - N/A for install-time assets. case AssetDeliveryStatus.Retrieving: // Asset pack is being downloaded and transferred to app storage. // N/A for install-time assets. case AssetDeliveryStatus.Available: // Asset pack is downloaded on disk but NOT loaded into memory. // For PlayAssetPackRequest(), this indicates that the request is complete. case AssetDeliveryStatus.Failed: // Asset pack retrieval failed. case AssetDeliveryStatus.WaitingForWifi: // Asset pack retrieval paused until either the device connects via Wi-Fi, // or the user accepts the PlayAssetDelivery.ShowConfirmationDialog dialog. case AssetDeliveryStatus.RequiresUserConfirmation: // Asset pack retrieval paused until the user accepts the // PlayAssetDelivery.ShowConfirmationDialog dialog. default: break; } // Returns true if status is AssetDeliveryStatus.Available or AssetDeliveryStatus.Failed. bool done = request.IsDone; // If AssetDeliveryStatus.Failed, find more info about the error. AssetDeliveryErrorCode error = request.Error;
Downloads grandes
Os pacotes de recursos com mais de 200 MB podem ser transferidos por download automaticamente, mas somente se o dispositivo
estiver conectado a uma rede Wi-Fi. Se o usuário não estiver usando Wi-Fi, o status PlayAssetPackRequest
será definido como
AssetDeliveryStatus.WaitingForWifi
e o download será pausado. Nesse caso, aguarde até que o dispositivo se conecte
à rede Wi-Fi, retome o download ou peça ao usuário aprovação para fazer o download do
pacote em uma conexão celular.
Confirmação do usuário necessária
Se um pacote tiver o status AssetDeliveryStatus.RequiresUserConfirmation
, o
download não vai prosseguir até que o usuário aceite a caixa de diálogo mostrada com
PlayAssetDelivery.ShowConfirmationDialog()
. Esse status pode surgir se o app
não for reconhecido pelo Google Play. Chamar
PlayAssetDelivery.ShowConfirmationDialog()
nesse caso faz com que o app
seja atualizado. Após a atualização, solicite os recursos novamente.
if(request.Status == AssetDeliveryStatus.RequiresUserConfirmation || request.Status == AssetDeliveryStatus.WaitingForWifi) { var userConfirmationOperation = PlayAssetDelivery.ShowConfirmationDialog(); yield return userConfirmationOperation; switch(userConfirmationOperation.GetResult()) { case ConfirmationDialogResult.Unknown: // userConfirmationOperation finished with an error. Something went // wrong when displaying the prompt to the user, and they weren't // able to interact with the dialog. case ConfirmationDialogResult.Accepted: // User accepted the confirmation dialog--an update will start. case ConfirmationDialogResult.Declined: // User canceled or declined the dialog. It can be shown again. default: break; } }
Cancelar uma solicitação (somente sob demanda)
Se você precisar cancelar a solicitação antes do download dos pacotes de recursos ser concluído, chame
o método
AttemptCancel()
no objeto PlayAssetPackRequest
:
// Will only attempt if the status is Pending, Retrieving, or Available; otherwise // it will be a no-op. request.AttemptCancel(); // Check to see if the request was successful by checking if the error code is Canceled. if(request.Error == AssetDeliveryErrorCode.Canceled) { // Request was successfully canceled. }
Carregar recursos na memória
Quando a solicitação for concluída, use uma destas funções para carregar recursos na memória:
- Use
PlayAssetPackRequest.GetAssetLocation()
para receber um objetoAssetLocation
. Isso fornece o caminho, a compensação e o tamanho do recurso para que ele possa ser carregado do disco. - Se o recurso for um AssetBundle, você poderá usar o método de conveniência
PlayAssetPackRequest.LoadAssetBundleAsync(assetPath)
. O caminho do recurso que você transmitir precisa corresponder ao caminho para o AssetBundle de dentro do pacote de recursos. Isso retornará uma AssetBundleCreateRequest.
Solicitar pacotes de recursos de forma assíncrona
Na maioria dos casos, é preciso usar Corrotinas para solicitar pacotes de recursos de forma assíncrona e monitorar o progresso, como mostrado a seguir:
private IEnumerator LoadAssetPackCoroutine(string assetPackName) { PlayAssetPackRequest request = PlayAssetDelivery.RetrieveAssetPackAsync(assetPackName); while (!request.IsDone) { if(request.Status == AssetDeliveryStatus.WaitingForWifi) { var userConfirmationOperation = PlayAssetDelivery.ShowConfirmationDialog(); // Wait for confirmation dialog action. yield return userConfirmationOperation; if((userConfirmationOperation.Error != AssetDeliveryErrorCode.NoError) || (userConfirmationOperation.GetResult() != ConfirmationDialogResult.Accepted)) { // The user did not accept the confirmation. Handle as needed. } // Wait for Wi-Fi connection OR confirmation dialog acceptance before moving on. yield return new WaitUntil(() => request.Status != AssetDeliveryStatus.WaitingForWifi); } // Use request.DownloadProgress to track download progress. // Use request.Status to track the status of request. yield return null; } if (request.Error != AssetDeliveryErrorCode.NoError) { // There was an error retrieving the pack. For error codes NetworkError // and InsufficientStorage, you may prompt the user to check their // connection settings or check their storage space, respectively, then // try again. yield return null; } // Request was successful. Load the asset pack into memory. AssetBundleCreateRequest assetBundleCreateRequest = request.LoadAssetBundleAsync(path/to/exampleBundle); yield return assetBundleCreateRequest; AssetBundle assetBundle = assetBundleCreateRequest.assetBundle;
Para ver mais informações sobre como lidar com erros, consulte a lista de códigos de erro.
Outros métodos da API Play Core
Veja a seguir alguns métodos adicionais de API que podem ser usados no seu app.
Recuperar vários pacotes de recursos
Para recuperar vários pacotes de recursos de uma só vez, use a seguinte função:
// assetPackNames is an array of strings corresponding to asset packs. PlayAssetPackBatchRequest batchRequest = PlayAssetDelivery.RetrieveAssetPackBatchAsync(<IListstring> assetPackNames);
Monitore os status de cada solicitação inspecionando o Dictionary
de estados:
// Dictionary of AssetPackStates, with the asset pack name as the key. Dictionary<string, PlayAssetPackRequest> requests = batchRequest.Requests; // Returns true if all requests are complete. bool requestComplete = batchRequest.IsDone;
Verificar o tamanho do download
Verifique o tamanho de um pacote de recursos fazendo uma chamada assíncrona ao Google Play e definindo um método de callback para quando a operação for concluída:
public IEnumerator GetDownloadSize() { PlayAsyncOperation<long> getSizeOperation = PlayAssetDelivery.GetDownloadSize(assetPackName); yield return getSizeOperation; if(operation.Error != AssetDeliveryErrorCode.NoError) { // Error while retrieving download size. } else { // Download size is given in bytes. long downloadSize = operation.GetResult(); } }
Remover AssetBundles
É possível remover pacotes de recursos rápidos e sob demanda que não estão carregados na memória no momento. Faça a chamada assíncrona a seguir e defina um método de callback para conclusão:
PlayAsyncOperation<string> removeOperation = PlayAssetDelivery.RemoveAssetPack(assetBundleName); removeOperation.Completed += (operation) => { if(operation.Error != AssetDeliveryErrorCode.NoError) { // Error while attempting to remove AssetBundles. } else { // Files were deleted OR files did not exist to begin with. } };
Próximas etapas
Teste a entrega de recursos localmente e no Google Play.