The way play modes works is this (honestly, we don’t love it. it worked well with our initial design for builders, but our reality has drifted)…
we have one list of build scripts in the AddressableAssetSettings object.
/// <summary>
/// List of ScriptableObjects that implement the IDataBuilder interface. These are used to create data for editor play mode and for player builds.
/// </summary>
public List<ScriptableObject> DataBuilders { get { return m_DataBuilders; } }
Each builder implements CanBuildData. For play mode, the T is AddressablesPlayModeBuildResult, for building for player, T is AddressablesPlayerBuildResult. As you’ll notice, this does mean a builder could build for both modes, if you happened to create a script to handle that. Alternatively, it could build for neither, if you were extending addressables in some way that needed that.
The way Addressables saves the “current” script is as an index into this array, in the members ActivePlayModeDataBuilder and ActivePlayerDataBuilderIndex.
So, for you to set the current builder from code, you’d have to loop the array of builders, find the one you want (by name, or based on selection in a custom dropdown you’ve written), and use that index.
Again, we don’t love this pattern. Some of our early motivations for this pattern still stand, but some do not. (such as we still expect most medium to large studios to create many custom build scripts to suit their needs, thus the dynamic nature)
One additional note, the package is open source, so a lot of these questions are most easily answered just by looking at our code. For example AddressableAssetsSettingsGroupEditor.TopToolbar() implements our dropdown logic.