Building a Player - documentation update: feedback welcome!

Hi all,

I’m a Technical Writer at Unity, and I’ve recently worked on updating the Building and Publishing section of the Unity User Manual.

I’ve created a few new pages which might be of interest if you’ve ever wanted to understand Unity’s build process:

In general the whole section has had a bit of a makeover, so I’d appreciate any feedback you have, and if there’s anything else you’d like to see on this topic.

Thanks!

3 Likes

One issue I think would be important to highlight in the build documentation is the pitfall of building for a build target that is not the active build target.

This can work fine for many cases but can then break when build-related code is using platform-specific conditional compilation. Some editor code will not run or code for the wrong platform will run, leading to features silently breaking or compile errors.

There are Unity packages that have this issue, so I basically consider it a requirement for the active build target and the target of BuildPipeline.BuildPlayer() to match.

All the examples should either check the active build target and fail, if the active and desired targets don’t match, or switch the active build target before starting the build. The latter is pretty complicated, as it involves a domain reload, so an example of how to do that would be great as well.

Background:

When calling BuildPipeline.BuildPlayer(), the editor code cannot be reloaded, as it’s executing the build. If some editor code is using #if UNITY_XYZ platform-specific conditional compilation, which code is active and will run during the build depends on the active build target and not the target passed to BuildPlayer. If the build is done for a different target than the active one, the platform-dependent conditionally compiled code can either run for the wrong platform or be incorrectly skipped.

e.g.

using UnityEditor;

#if UNITY_IOS
// iOS-specific build code here
#elif UNITY_ANDROID
// Android-specific build code here
#endif

// Assuming this prints "BuildTarget.Android", meaning the Android code
// block above is active and the iOS block skipped.
Debug.Log(EditorUserBuildSettings.activeBuildTarget);
// Doing an iOS build in this case will not change this, the iOS block
// will be skipped and the Android block executed instead.
BuildPipeline.BuildPlayer(null, "Build/iOS", BuildTarget.iOS, BuildOptions.None);

The two options are to either never use target-dependent conditional compilation for editor code or to always switch the active build target before a build. Since you can’t control third-party code and even Unity’s own code breaks the first rule, the only viable option is to always do the active build target switch.

(Note that if you use the editor UI, Unity already forces you to switch the active build target first. This problem only applies to script builds.)

2 Likes

Also regarding the Build Callbacks:

Build callbacks during incremental builds

[…]

To ensure that Unity runs a modified callback implementation, perform a clean build, or modify the content of one of the scenes or assets in the build.

Is it enough to modify any asset, for all build callbacks to be run again?

From the documentation on IProcessSceneWithReport, I was under the impression that you’d have to modify the specific scene/asset that you want the build processor to run for:

Note that if the scene or related content in the project is unchanged from the previous player build, the scene will not be built and instead cached player build data will be used. In this case the callback will not be called.

Hi @Adrian, thanks for all the feedback!

Regarding the callbacks - the player build is currently “all or nothing” so if any asset changes content from the previous build everything gets rebuilt, and all callbacks invoked.

For AssetBundles the decision to rebuild is bundle by bundle (based on comparing the input hash stored in the .manifest files). So it would only call the callback if the scene is inside an AssetBundle that is being rebuilt.

We can probably tighten up the docs on that to be more clear, although probably the best guidance still is to change the scene, or a direct dependency of the scene, if you want to be very certain that the callback is called and the scene rebuilt.

1 Like

And @Adrian, thanks for the feedback about making it much clearer about the limitations/restriction on changing target. We will add more detail about that. I agree that it needs to be heavily discouraged to try to build a different target than the currently active target and we can add more details about that now that we have new topics focusing on command line builds and build scripts.