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?
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).
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.
[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.
using UnityEditor;
using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Settings;
using UnityEngine;
using System.Collections;
class BuildAddressablesProcessor
{
/// <summary>
/// Run a clean build before export.
/// </summary>
static public void PreExport()
{
Debug.Log("BuildAddressablesProcessor.PreExport start");
AddressableAssetSettings.CleanPlayerContent(
AddressableAssetSettingsDefaultObject.Settings.ActivePlayerDataBuilder);
AddressableAssetSettings.BuildPlayerContent();
Debug.Log("BuildAddressablesProcessor.PreExport done");
}
[InitializeOnLoadMethod]
private static void Initialize()
{
BuildPlayerWindow.RegisterBuildPlayerHandler(BuildPlayerHandler);
}
private static void BuildPlayerHandler(BuildPlayerOptions options)
{
if (EditorUtility.DisplayDialog("Build with Addressables",
"Do you want to build a clean addressables before export?",
"Build with Addressables", "Skip"))
{
PreExport();
}
BuildPlayerWindow.DefaultBuildMethods.BuildPlayer(options);
}
}
@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.
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.
@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.
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.
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!
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.
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?)
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)
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).
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.
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.
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 …