Unity 2021.2 get current NamedBuildTarget (869508)

I recently started to work with Unity 2021.2 and I found out BuildTargetGroup was being replaced by NamedBuildTarget. Previously, the currently targeted BuildTargetGroup could be retrieved from EditorUserBuildSettings.activeBuildTarget. In Unity 2021.2, I can’t figure out what is supposed to replace this function.

How do you retrieve the currently targeted NamedBuildTarget ?

I’ve been trying to find the solution to this but to no avail, seems like a major oversight from Unity.

I put together the following code to get all NamedBuildTargets (excluding ‘Unknown’) as in my case having all targets will suffice (I’m setting scripting define symbols which aren’t platform specific).

static List<NamedBuildTarget> GetAllNamedBuildTargets()
{
    var staticFields = typeof(NamedBuildTarget).GetFields(BindingFlags.Public | BindingFlags.Static);
    var buildTargets = new List<NamedBuildTarget>();

    foreach (var staticField in staticFields)
    {
        // We exclude 'Unknown' because this can throw errors when used with certain methods.
        if (staticField.Name == "Unknown")
            continue;

        if (staticField.FieldType == typeof(NamedBuildTarget))
            buildTargets.Add((NamedBuildTarget)staticField.GetValue(null));
    }

    return buildTargets;
}

I don’t see the problem. In Unity 2021.2 and 2021.3 LTS you can still call
EditorUserBuildSettings.selectedBuildTargetGroup and
EditorUserBuildSettings.activeBuildTarget

They haven’t been removed nor have they been marked obsolete so how is this “replaced”?
I haven’t seen NamedBuildTarget before. Where is it used?

Also looking into the NamedBuildTarget struct there is a public static method FromBuildTargetGroup that converts a BuildTargetGroup to a NamedBuildTargetGroup

It’s used in PlayerSettings.GetScriptingDefineSymbolsForGroup which is said to be removed in the future in the documentation. And PlayerSettings.SetScriptingDefineSymbols accepts a NamedBuildTarget.

It does seem like there are a few oversights in the API because, well it leads to really verbose conversion code like this:

private static void EditSymbols(Func<string, string, string> action, string value)
{
    var target = EditorUserBuildSettings.activeBuildTarget;
    var group = BuildPipeline.GetBuildTargetGroup(target);
    var namedBuildTarget = NamedBuildTarget.FromBuildTargetGroup(group);
    string symbols = PlayerSettings.GetScriptingDefineSymbols(namedBuildTarget);
    symbols = action(symbols, value);
    PlayerSettings.SetScriptingDefineSymbols(namedBuildTarget, symbols);
}

It seems there should be a more official or better way to do these things, but they are internal:

8107490--1049762--upload_2022-5-6_18-5-13.png

Just came across this exact issue as well since our old CI build script was unable to set scripting defines for the new dedicated server “sub target”
Apparently you’re meant to use the new API with the named build target and just use NamedBuildTarget.Server and THAT can add scripting defines for the server build

simply. genious.

BuildTarget buildTarget = EditorUserBuildSettings.activeBuildTarget;
BuildTargetGroup targetGroup = BuildPipeline.GetBuildTargetGroup(buildTarget);
var namedBuildTarget = UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup(targetGroup);

@Xarbrough_1 Thank you very much for the hint on that internal function. Its original source code seems to be:

To fix my current issues I implemented a function very similar to that internal function and put it into my own sources.

Nevertheless I hope Unity will clean up this mess with old enums and new enums and deprecated functions and broken conversion functions.

There already exists an official issue regarding this problem and setting Scripting Defines Symbols. It is in the “fixed” state which I find hard to believe:

@RuanCardoso The code you posted uses the conversion function UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup which unfortunately does ignore the StandaloneBuildSubtarget (SUB!) and therefore is incomplete.

No, this doesn`t work, it returns “Standalone” when my target platform is set to Dedicated Server.

There is no way to know if the current platform is Server or if it is Standalone? Seems like a major design flaw in the new unity versions.

Right now when you try to automatically assign scripting define symbols when people are importing a unity asset. It won`t work for the Server build. Since activeBuildTarget returns Standalone when it should return DedicatedServer.

Simple workaround I made:

            public static NamedBuildTarget CurrentNamedBuildTarget
            {
                get
                {
#if UNITY_SERVER
                    return NamedBuildTarget.Server;
#else
                    BuildTarget buildTarget = EditorUserBuildSettings.activeBuildTarget;
                    BuildTargetGroup targetGroup = BuildPipeline.GetBuildTargetGroup(buildTarget);
                    NamedBuildTarget namedBuildTarget = NamedBuildTarget.FromBuildTargetGroup(targetGroup);
                    return namedBuildTarget;
#endif
                }
            }

4 years later and.. it’s still the exact same miserable state it was it seems
amazing :slight_smile:


public static class BuildHelper {
    public static NamedBuildTarget GetActiveNamedBuildTarget() {
        return GetActiveNamedBuildTargetFor(EditorUserBuildSettings.activeBuildTarget);
    }

    // This is a 1:1 copy of the internal NamedBuildTarget.FromActiveSettings since unity STILL does not provide a publically accessible method
    public static NamedBuildTarget GetActiveNamedBuildTargetFor(BuildTarget target) {
        BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(target);
        if (buildTargetGroup == BuildTargetGroup.Standalone &&
            EditorUserBuildSettings.standaloneBuildSubtarget == StandaloneBuildSubtarget.Server) {
            return NamedBuildTarget.Server;
        }

        return NamedBuildTarget.FromBuildTargetGroup(buildTargetGroup);
    }
}