Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

How to trigger "build player content" when build unity project.

Discussion in 'Addressables' started by Favo-Yang, Jun 4, 2019.

  1. Favo-Yang

    Favo-Yang

    Joined:
    Apr 4, 2011
    Posts:
    411
    I thought "build player content" was automatically triggered when build unity project, as I remembered it was mentioned in an unity conference video. However seems it was not (for both local build and cloud build). I need to manually run build > build player content once, then my local build works.

    Should I write a build processor script for this, or I'm missing something obviously?

    AddressableAssetSettings.CleanPlayerContent(AddressableAssetSettingsDefaultObject.Settings.ActivePlayerDataBuilder);
    AddressableAssetSettings.BuildPlayerContent();​

    Addressable 0.8.6
    Unity 2019.1.4f1

    Refs https://forum.unity.com/threads/is-it-compatible-with-cloud-build.653437/

     
  2. Ziflin

    Ziflin

    Joined:
    Mar 12, 2013
    Posts:
    64
    I just ran into this as well and would like to know if it is something that should be happening automatically?
     
  3. Kerber996

    Kerber996

    Joined:
    Nov 9, 2016
    Posts:
    20
    It was automatic in the previous versions but in the new ones it was separated as you don't always need to build player content (ex. when you build for content update).
     
  4. Favo-Yang

    Favo-Yang

    Joined:
    Apr 4, 2011
    Posts:
    411
    But the default local group, which packed into streaming assets need always be built among with main build, right?

    At least we can leave an option in the addressable setting file.
     
  5. Kerber996

    Kerber996

    Joined:
    Nov 9, 2016
    Posts:
    20
    Well if you are building the app then yes, you would need to build the default local group(or anything else marked as "static"), but for content updates you don't build the app, and anything that went into the default local group can automagically be put in a new pack by analyzing the rules and applying the fixes.
     
  6. Favo-Yang

    Favo-Yang

    Joined:
    Apr 4, 2011
    Posts:
    411
    The change logs,

    [0.5.2-preview] - 2018-12-14
    IMPORTANT CHANGE TO BUILDING
    We have disabled automatic asset bundle building. That used to happen when you built the player, or entered play mode in "packed mode". This is no longer the case. You must now select "Build->Build Player Content" from the Addressables window, or call AddressableAssetSettings.BuildPlayerContent(). We did this because we determined that automatic building did not scale well at all for large projects.

    Seems the decision related to build performance for bigger project.

    Anyway my 2 cents.
    - Trigger the build button with a popup window, to build with/without addressables.
    - Or you can write a custom build pipeline script to achieve something similar. (IPreprocessBuildWithReport hook didn't work due to "cannot call WriteSerializedFile while a build is in progress" issue).
    - Put "BuildAddressablesProcessor.PreExport" as the PreExport command for cloud build.

    Update: the script can be found at https://gist.github.com/favoyang/cd2cf2ed9df7e2538f3630610c604c51

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEditor.AddressableAssets;
    3. using UnityEditor.AddressableAssets.Settings;
    4. using UnityEngine;
    5. using System.Collections;
    6.  
    7. class BuildAddressablesProcessor
    8. {
    9.     /// <summary>
    10.     /// Run a clean build before export.
    11.     /// </summary>
    12.     static public void PreExport()
    13.     {
    14.         Debug.Log("BuildAddressablesProcessor.PreExport start");
    15.         AddressableAssetSettings.CleanPlayerContent(
    16.             AddressableAssetSettingsDefaultObject.Settings.ActivePlayerDataBuilder);
    17.         AddressableAssetSettings.BuildPlayerContent();
    18.         Debug.Log("BuildAddressablesProcessor.PreExport done");
    19.     }
    20.  
    21.     [InitializeOnLoadMethod]
    22.     private static void Initialize()
    23.     {
    24.         BuildPlayerWindow.RegisterBuildPlayerHandler(BuildPlayerHandler);
    25.     }
    26.  
    27.     private static void BuildPlayerHandler(BuildPlayerOptions options)
    28.     {
    29.         if (EditorUtility.DisplayDialog("Build with Addressables",
    30.             "Do you want to build a clean addressables before export?",
    31.             "Build with Addressables", "Skip"))
    32.         {
    33.             PreExport();
    34.         }
    35.         BuildPlayerWindow.DefaultBuildMethods.BuildPlayer(options);
    36.     }
    37.  
    38. }
    39.  
    @Kerber996, see your point. If the addressables is always in the build pipeline, then we lose the tracking for content update (the .bin file in addressables folder). I guess a better approach would be,
    - Always build local group when build the app.
    - Revert the .bin file, until you prepared a content update.
     
    Last edited: Jul 19, 2019
    bguyl and RDL_Simteam_3 like this.
  7. Ziflin

    Ziflin

    Joined:
    Mar 12, 2013
    Posts:
    64
    I would personally expect that if I did a normal app build that any important changes to the addressables were part of that build process. Not doing this just seems to be asking for annoying bugs or tests that aren't accurate. So if it was disabled for performance reasons, then it seems like there needs to be some optimization work done to better track when/what things change.

    As far as doing content updates (I haven't played with it yet), but I would hope there would be a way to do something like: "Mark the current state as v1.0 and save it off". Then when v1.1 is ready have a way to build it using the saved off v1.0 file. Just relying on some previously built state seems very problematic especially for people doing simultaneous builds on multiple platforms as the "final" builds for each platform inevitably have slightly different content changes/fixes.
     
  8. ALantean

    ALantean

    Joined:
    Nov 13, 2017
    Posts:
    3
    @Favo-Yang, thank you for your script! At the moment I'm struggling with the same issue.

    I have configured my Cloud Build config to execute a Pre-Export method similar to your
    BuildAddressablesProcessor.PreExport
    and I'm actually seeing the logs of this method during builds via Cloud Build. The thing I'm having trouble with is the copying of these cached Addressables (located in the library folder) to the StreamingAssets folder. For some reason my logs do not contain any logs in the form of

    "Copying Addressables data from {0} to {1}. These copies will be deleted at the end of the build."
    (line 33 of
    AddressablesPlayerBuildProcessor
    ).

    When looking at the code of the
    OnPreprocessBuild
    method of
    AddressablesPlayerBuildProcessor
    I'm thinking that the cached Addressable library directory might not exist in my Cloud Build build instance, which contradicts the log messages I'm seeing of my Pre-Export method.

    Maybe you, @Favo-Yang, or someone else can elaborate on their experience with the building process of the Addressables. As far as I can tell
    AddressablesPlayerBuildProcessor
    is called during local builds in the Editor, since it implements the Preprocess-, PostprocessBuild interfaces, but from the logs I'm seeing of my Cloud Builds, I cannot confirm its execution (due to a missing library folder although I previously build it?).

    Note that I'm using the 'Default' profile for everything I've described above.


    Maybe there should be a second check box next to 'Include In Build' to further clarify the behaviour of the group. The second check box triggering a clean build of the Addressables, such that there exist cached assets which can be copied by
    AddressablesPlayerBuildProcessor
    .
     
  9. Favo-Yang

    Favo-Yang

    Joined:
    Apr 4, 2011
    Posts:
    411
    Checked one of the cloud builds. The full logs show that the "copy to StreamingAssets" happens almost right after my PreExport method.

    8930: [Unity] BuildAddressablesProcessor.PreExport start
    ...
    9059: [Unity] BuildAddressablesProcessor.PreExport done
    ...
    9114: [Unity] Copying Addressables data from Library/com.unity.addressables/StreamingAssetsCopy/aa/OSX to /BUILD_PATH/.../Assets/StreamingAssets/aa/OSX. These copies will be deleted at the end of the build.​

    My cloud build configs are almost default, except "Pre-Export Method" set to "BuildAddressablesProcessor.PreExport". I made one mistake that I forget to fill "Pre-Export Method" to all my build targets, caused one target build failed.

    Maybe you can try the “Clean Build" button in the dropdown of "BUILD: ALL TARGETS", see if that is relevant. Or create a empty project with one addressable asset and my processor script, see if you can reproduce the bug.
     
    ALantean likes this.
  10. ALantean

    ALantean

    Joined:
    Nov 13, 2017
    Posts:
    3
    Thank you for your detailed reply!

    After double checking everything and after further investigation it turned that my builds have some issues with the IL2CPP backend during builds of Cloud Build -- I will not go into more detail about this separate issue here.
    In any case, after clearing this up, my builds successfully triggered the
    AddressablesPlayerBuildProcessor.OnPreprocessBuild
    and now copy the cached Addressables into the Streaming Assets folder!

    Thanks again!
     
    Favo-Yang likes this.
  11. Revolter

    Revolter

    Joined:
    Mar 15, 2014
    Posts:
    151
    Thank for that! Didn't work as part of Pre or Post Build Processor
     
  12. chanon81

    chanon81

    Joined:
    Oct 6, 2015
    Posts:
    159
    There should be an option to automaticallt build player content when building, because it is very easy to forget to do the "build player content".

    I agree that there should be better optimization of the asset bundle build process so that if only a few files changed then it doesn't have to do so much.
     
  13. camel82106

    camel82106

    Joined:
    Jul 2, 2013
    Posts:
    306
    Hi,
    I have configured my Cloud Build config to execute yours Pre-Export method.

    But I cannot go through this error while building through cloud?
    Is it even working with latest addressable assets package?

    Thanks
    Peter

    [Unity] -----CompilerOutput:-stdout--exitcode: 1--compilationhadfailure: True--outfile: Temp/Assembly-CSharp.dll
    64: [Unity] Assets/Scripts/BuildAddressablesProcessor.cs(2,19): error CS0234: The type or namespace name 'AddressableAssets' does not exist in the namespace 'UnityEditor' (are you missing an assembly reference?)
    65: [Unity] Assets/Scripts/BuildAddressablesProcessor.cs(3,19): error CS0234: The type or namespace name 'AddressableAssets' does not exist in the namespace 'UnityEditor' (are you missing an assembly reference?)
    66: [Unity] Assets/Scripts/Catalog/ProblemSceneManager.cs(12,19): error CS0234: The type or namespace name 'AddressableAssets' does not exist in the namespace 'UnityEditor' (are you missing an assembly reference?)
     
  14. Favo-Yang

    Favo-Yang

    Joined:
    Apr 4, 2011
    Posts:
    411
    It's an editor script should be included in Assembly-CSharp-Editor. Have you put it into a folder named Editor?
     
  15. camel82106

    camel82106

    Joined:
    Jul 2, 2013
    Posts:
    306
    Oh yeah that makes sense. And sadly not. Your posts on Addressables forum are incredible.
    Thank you very much!
     
    Favo-Yang likes this.
  16. unity_bill

    unity_bill

    Unity Technologies

    Joined:
    Apr 11, 2017
    Posts:
    1,023
    We actually had a lot of reasons to make this change, the largest of which was the optimization. For a very large project, just checking that nothing has changed can take quite a bit of time. To make things worse, it's not uncommon for a user to have a build script that, for example, builds several different variations of Android players that would all reference the same bundles.

    But, I want to hit on one of the other reasons as there's an editor limitation we ran into, and you're going to hit it too. In your code example, you register with BuildPlayerWindow.RegisterBuildPlayerHandler(). This only registers a callback if someone builds via the build window GUI. If they build command line, you can't know about that. For your situation, that may not matter, but for us, a lot of customers use scripts to build, and we really didn't want different behavior if you clicked the build button vs doing command line.

    There are a lot of upsides to Addressables being a package, but one of the downsides is that we end up stuck with some engine/editor limitations we don't like (and can't realistically backport a fix for)
     
    Rotary-Heart likes this.
  17. Favo-Yang

    Favo-Yang

    Joined:
    Apr 4, 2011
    Posts:
    411
    Well, I know it's not perfect. But it's a pitfall many will fall the first time they build to device.

    I think it's better to have options, like a boolean in the addressable settings file to tell the system whether build player content with a game build. No matter you click the build button, or write your build script, or cloud build. That logic within addressable build processing will keep consistent. You're welcome to turn that off if you don't need it. This will benefit early development, or those mainly use addressable as an asset loader (no download via network).

    Current behaviour is that the system won't build content for you, please write a build script for it. And when it comes to cloud build, you need learn something new with build option UI (also intros inconsistent).

    For those who need the script, I've put it on Github. https://gist.github.com/favoyang/cd2cf2ed9df7e2538f3630610c604c51
     
  18. unity_bill

    unity_bill

    Unity Technologies

    Joined:
    Apr 11, 2017
    Posts:
    1,023
    I agree that would be ideal. My point is that the engine doesn't currently have a clean way for us to make that work. We could look at adding it, but at this point it'd be added to Unity 2020.1 at the earliest, and this sort of feature is one we couldn't back port to older versions. That's what I meant by us sometimes being stuck with engine features since we're doing our development in a package.
     
    tigerleapgorge likes this.
  19. Huacanacha

    Huacanacha

    Joined:
    Aug 16, 2013
    Posts:
    50
    I now see a 'Build Addressables" option in Cloud Build. Not sure how long it's been there... Does this negate the need for the PreExport method to initiate Addressables builds?

    If so I might resume my Addressables investigations - I had paused due to build inconsistencies (local vs cloud not behaving the same) and the complexity and fragility of setting up custom build hook methods.
     
  20. MartinCoatsink

    MartinCoatsink

    Joined:
    Nov 13, 2019
    Posts:
    7
    Got any updates on this issue, unity_bill?

    ---

    I feel like a decent workaround at this moment is to add a IPreprocessBuildWithReport.OnPrepreprocessBuild hook that will build the asset bundle for you.

    This should work regardless if the build was started from Build Settings Window or batchmode.

    Edit: never mind. Apparently an exception is thrown if I try to do that ...
     
    Last edited: Apr 20, 2020
  21. marwi

    marwi

    Joined:
    Aug 13, 2014
    Posts:
    116
    Id also be interested in knowing what the correct way of automatically building my content is right now. At the moment I have to think about whether or not I need to rebuild my content before building to device - Id rather have an option for the content being automatically rebuild every time rather than realizing I have outdated content after checking on device. This is especially important from an artists standpoint who edits assets and should not be bothered with having to think of multiple steps in order to get a correct build.

    is this something that could potentially be fixed with the scriptable build pipeline (havent yet to try that)
     
  22. Eldirfar

    Eldirfar

    Joined:
    Feb 9, 2014
    Posts:
    42
    I have problem with addressables.
    I'm working on local machine. Sure I can make local build addressables. But I'm not making builds on local machine. I make them on Jenkins which download project form GIT. I found that addressables doesn't work on builds made by Jenkins because he doesn't update them. I have on repository addressables_content_state.bin files form local content update but in build made by Jenkins addressables dosn't work.
    Build preprocess doesn't work because it is already in build phase.

    @unity_bill any hints how to solve that?
     
    davidrochin likes this.
  23. ProtoTerminator

    ProtoTerminator

    Joined:
    Nov 19, 2013
    Posts:
    459
    Just make a script that builds the addressables before building the engine.
    UnityEditor.AddressableAssets.Settings.AddressableAssetSettings.BuildPlayerContent();
     
  24. Eldirfar

    Eldirfar

    Joined:
    Feb 9, 2014
    Posts:
    42
    Yes we find out it too. It works for now. But would be great to be able to configure build behaviour within addressables.
     
  25. nicolasgramlich

    nicolasgramlich

    Joined:
    Sep 21, 2017
    Posts:
    182
    CC @Favo-Yang

    Did anyone find a way to hook this into the Scriptable build pipeline?

    Code (CSharp):
    1. using UnityEditor.AddressableAssets.Settings;
    2. using UnityEditor.Build;
    3. using UnityEditor.Build.Reporting;
    4. using UnityEngine;
    5.  
    6. namespace Editor.Build {
    7.     public class AddressableAssetPreBuildScript : IPreprocessBuildWithReport {
    8.         public int callbackOrder { get; } = 1;
    9.  
    10.         public void OnPreprocessBuild(BuildReport buildReport) {
    11.             Debug.Log("AddressableAssetSettings.CleanPlayerContent...");
    12.             AddressableAssetSettings.CleanPlayerContent();
    13.             Debug.Log("AddressableAssetSettings.CleanPlayerContent!");
    14.  
    15.             Debug.Log("AddressableAssetSettings.BuildPlayerContent...");
    16.             AddressableAssetSettings.BuildPlayerContent();
    17.             Debug.Log("AddressableAssetSettings.BuildPlayerContent!");
    18.         }
    19.     }
    20. }
    21.  
    I'm still getting a
    cannot call WriteSerializedFile while a build is in progress
    on the latest 2019.4.7f1 and
    com.unity.addressables: 1.13.1
    with
    com.unity.scriptablebuildpipeline: 1.10.0
    .

    :(
     
    francismoy likes this.
  26. Aurigan

    Aurigan

    Joined:
    Jun 30, 2013
    Posts:
    243
    I ... I don't understand. Why is this still necessary??? C'mon Unity ... it's been *years*! 'just make a script' shouldn't be needed in order for this to work as expected.
     
  27. francismoy

    francismoy

    Joined:
    Jul 5, 2017
    Posts:
    29
    Me too on Unity 2019.4.10f1, addressables 1.12.0 and scriptable build pipeline 1.9.0.

    Could you at least explain what this error means and why it's happening?
     
unityunity