Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Triggering a build via BuildPipeline.BuildPlayer doesn't build asset bundles

Discussion in 'Addressables' started by arvzg, Nov 1, 2018.

  1. arvzg

    arvzg

    Joined:
    Jun 28, 2009
    Posts:
    619
    Hello,

    I have a build script that I use in conjunction with Jenkins build server which uses a Build Script that calls BuildPipeline.BuildPlayer(..) to trigger builds. I'm noticing that the Addressables system doesn't build any asset bundles when making a build in this way.

    If I use the standard Build settings window and do builds that way, then the asset bundles do get built.

    Is this a missing feature still to come, or do I need to use another API call to trigger the builds?
     
    King-Klong and taptpci like this.
  2. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,554
    Look at scripts in AddressablesBuildScriptHook.cs

    In short I think you need

    Code (CSharp):
    1. AddressableAssetSettingsDefaultObject.Settings.ActivePlayerDataBuilder.BuildData<AddressablesPlayerBuildResult>(AddressablesBuildDataBuilderContext)
    before BuildPipeline.BuildPlayer


    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.ResourceManagement;
    3. using UnityEngine.AddressableAssets;
    4. using System;
    5. using UnityEngine.Experimental.UIElements;
    6. using System.Collections.Generic;
    7. using System.IO;
    8.  
    9. namespace UnityEditor.AddressableAssets
    10. {
    11.     /// <summary>
    12.     /// Entry point to set callbacks for builds.
    13.     /// </summary>
    14.     public static class BuildScript
    15.     {
    16.         /// <summary>
    17.         /// Global delegate for handling the result of AddressableAssets builds.  This will get called for player builds and when entering play mode.
    18.         /// </summary>
    19.         public static Action<AddressableAssetBuildResult> buildCompleted;
    20.     }
    21.  
    22.     internal static class AddressablesBuildScriptHooks
    23.     {
    24.         [InitializeOnLoadMethod]
    25.         static void Init()
    26.         {
    27.             BuildPlayerWindow.RegisterBuildPlayerHandler(BuildPlayer);
    28.             EditorApplication.playModeStateChanged += OnEditorPlayModeChanged;
    29.         }
    30.  
    31.         static void BuildPlayer(BuildPlayerOptions ops)
    32.         {
    33.             var settings = AddressableAssetSettingsDefaultObject.Settings;
    34.             if (settings == null)
    35.             {
    36.                 if (BuildScript.buildCompleted != null)
    37.                     BuildScript.buildCompleted(new AddressableAssetBuildResult() { Duration = 0, Error = "AddressableAssetSettings not found." });
    38.                 BuildPipeline.BuildPlayer(ops);
    39.             }
    40.             else
    41.             {
    42.                 if (settings.ActivePlayerDataBuilder == null)
    43.                 {
    44.                     var err = "Active build script is null.";
    45.                     Debug.LogError(err);
    46.  
    47.                     if (BuildScript.buildCompleted != null)
    48.                         BuildScript.buildCompleted(new AddressableAssetBuildResult() { Duration = 0, Error = err });
    49.                     return;
    50.                 }
    51.  
    52.                 if (!settings.ActivePlayerDataBuilder.CanBuildData<AddressablesPlayerBuildResult>())
    53.                 {
    54.                     var err = string.Format("Active build script {0} cannot build AddressablesPlayerBuildResult.", settings.ActivePlayerDataBuilder);
    55.                     Debug.LogError(err);
    56.                     if (BuildScript.buildCompleted != null)
    57.                         BuildScript.buildCompleted(new AddressableAssetBuildResult() { Duration = 0, Error = err });
    58.                     return;
    59.                 }
    60.  
    61.                 var context = new AddressablesBuildDataBuilderContext(settings, ops.targetGroup, ops.target, (ops.options & BuildOptions.Development) != BuildOptions.None, ((ops.options & BuildOptions.ConnectWithProfiler) != BuildOptions.None) && ProjectConfigData.postProfilerEvents, settings.PlayerBuildVersion);
    62.                 var res = settings.ActivePlayerDataBuilder.BuildData<AddressablesPlayerBuildResult>(context);
    63.                 BuildPipeline.BuildPlayer(ops);
    64.                 if (!string.IsNullOrEmpty(res.ContentStateDataPath))
    65.                 {    
    66.                     var newPath = ContentUpdateScript.GetContentStateDataPath(false);
    67.                     if (File.Exists(newPath))
    68.                           File.Delete(newPath);
    69.                     File.Copy(res.ContentStateDataPath, newPath);
    70.                 }
    71.  
    72.                 if (BuildScript.buildCompleted != null)
    73.                     BuildScript.buildCompleted(res);
    74.                 settings.DataBuilderCompleted(settings.ActivePlayerDataBuilder, res);
    75.             }
    76.         }
    77.  
    78.         private static void OnEditorPlayModeChanged(PlayModeStateChange state)
    79.         {
    80.             if (state == PlayModeStateChange.ExitingEditMode)
    81.             {
    82.                 var settings = AddressableAssetSettingsDefaultObject.Settings;
    83.                 if (settings == null)
    84.                     return;
    85.                 if (settings.ActivePlayModeDataBuilder == null)
    86.                 {
    87.                     var err = "Active play mode build script is null.";
    88.                     Debug.LogError(err);
    89.  
    90.                     if (BuildScript.buildCompleted != null)
    91.                         BuildScript.buildCompleted(new AddressableAssetBuildResult() { Duration = 0, Error = err });
    92.                     return;
    93.                 }
    94.  
    95.                 if (!settings.ActivePlayerDataBuilder.CanBuildData<AddressablesPlayModeBuildResult>())
    96.                 {
    97.                     var err = string.Format("Active build script {0} cannot build AddressablesPlayModeBuildResult.", settings.ActivePlayModeDataBuilder);
    98.                     Debug.LogError(err);
    99.                     if (BuildScript.buildCompleted != null)
    100.                         BuildScript.buildCompleted(new AddressableAssetBuildResult() { Duration = 0, Error = err });
    101.                     return;
    102.                 }
    103.  
    104.                 SceneManagerState.Record();
    105.                 var res = settings.ActivePlayModeDataBuilder.BuildData<AddressablesPlayModeBuildResult>(new AddressablesBuildDataBuilderContext(settings));
    106.                 SceneManagerState.AddScenesForPlayMode(res.ScenesToAdd);
    107.                 if (BuildScript.buildCompleted != null)
    108.                     BuildScript.buildCompleted(res);
    109.                 settings.DataBuilderCompleted(settings.ActivePlayerDataBuilder, res);
    110.             }
    111.             else if (state == PlayModeStateChange.EnteredEditMode)
    112.             {
    113.                 var settings = AddressableAssetSettingsDefaultObject.Settings;
    114.                 if(settings != null && settings.ActivePlayerDataBuilder != null && settings.ActivePlayerDataBuilder.CanBuildData<AddressablesPlayModeBuildResult>())
    115.                     SceneManagerState.Restore();
    116.             }
    117.         }
    118.     }
    119. }
     
    gawoon and arvzg like this.
  3. hexaust_

    hexaust_

    Joined:
    Mar 7, 2015
    Posts:
    23
    @5argon that doesn't work for me. Anyone managed to get this working?
     
  4. GilesCoopeAkelius

    GilesCoopeAkelius

    Joined:
    Oct 2, 2018
    Posts:
    7
    The script above works for me, except that sprites contained in SpriteAtlases don't work for me when I build from script rather than from the menu. Is there a way of seeing the exact steps unity is taking when we click "Build"?
     
  5. GilesCoopeAkelius

    GilesCoopeAkelius

    Joined:
    Oct 2, 2018
    Posts:
    7
    Anyone have an idea about this?

    To reproduce from an empty project simply create a prefab with a Sprite Renderer component that contains a reference to a sprite that is contained in a Sprite Atlas.

    Now add this prefab to an addressable group and instantiate it from a script.

    When you build the game for WebGL from batch mode using the script above the sprite atlas won't be built into the addressables correctly and the sprite won't load in game.
     
  6. PaulBurslem

    PaulBurslem

    Unity Technologies

    Joined:
    Oct 7, 2016
    Posts:
    79
    In the next release, you can call AddressableAssetSettingsDefaultObject.Settings.BuildPlayerContent(). This will use the build target and group and the development flag from EditorUserBuildSettings. I will look into why there may be issues with Sprites. Also, the automatic building of bundles when a player is built (or entering play mode) has been removed. We determined that it makes more sense to have that as a separate step since it can take a long time. In the editor play mode, Fast & Virtual build scripts will still do some processing but the PackMode will rely on already built bundles.
     
    gawoon likes this.
  7. Murrrly

    Murrrly

    Joined:
    Apr 25, 2013
    Posts:
    16
    I'm trying to get this working now with TeamCity. Just like arvzg, if I build from the editor, everything works. As soon as I use BuildPipeline.BuildPlayer nothing works.

    I have tried to manually get it to build addressables before I build the player and am able to get it to populate the StreamingAssets folder, but I must still be missing something.

    Any ideas?

    EDIT: I have tried using the same script I am using for Android with StandaloneWindows64 as the target and it actually works. I'm not sure what I'm doing wrong
     
    Last edited: Mar 13, 2019
  8. gawoon

    gawoon

    Joined:
    Dec 11, 2017
    Posts:
    7
    Hi, I'm new in Addressables. I want to do build with TeamCity and i wonder about the problems mentioned above all? are they solved now?