using System; using UnityEditor; using UnityEditor.Build; namespace MCPForUnity.Editor.Tools.Build { public static class BuildTargetMapping { private const string VisionOSName = "VisionOS"; public static bool TryResolveBuildTarget(string name, out BuildTarget target) { if (string.IsNullOrEmpty(name)) { target = EditorUserBuildSettings.activeBuildTarget; return true; } switch (name.ToLowerInvariant()) { case "windows64": target = BuildTarget.StandaloneWindows64; return true; case "windows": case "windows32": target = BuildTarget.StandaloneWindows; return true; case "osx": case "macos": target = BuildTarget.StandaloneOSX; return true; case "linux64": case "linux": target = BuildTarget.StandaloneLinux64; return true; case "android": target = BuildTarget.Android; return true; case "ios": target = BuildTarget.iOS; return true; case "webgl": target = BuildTarget.WebGL; return true; case "uwp": target = BuildTarget.WSAPlayer; return true; case "tvos": target = BuildTarget.tvOS; return true; default: if (TryParseDefinedBuildTarget(name, out target)) { return true; } target = default; return false; } } public static BuildTargetGroup GetTargetGroup(BuildTarget target) { switch (target) { case BuildTarget.StandaloneWindows: case BuildTarget.StandaloneWindows64: case BuildTarget.StandaloneOSX: case BuildTarget.StandaloneLinux64: return BuildTargetGroup.Standalone; case BuildTarget.iOS: return BuildTargetGroup.iOS; case BuildTarget.Android: return BuildTargetGroup.Android; case BuildTarget.WebGL: return BuildTargetGroup.WebGL; case BuildTarget.WSAPlayer: return BuildTargetGroup.WSA; case BuildTarget.tvOS: return BuildTargetGroup.tvOS; default: if (IsVisionOSTarget(target) && Enum.TryParse(VisionOSName, true, out BuildTargetGroup visionOSGroup)) { return visionOSGroup; } return BuildTargetGroup.Unknown; } } public static NamedBuildTarget GetNamedBuildTarget(BuildTarget target) { return NamedBuildTarget.FromBuildTargetGroup(GetTargetGroup(target)); } public static string TryResolveNamedBuildTarget(string name, out NamedBuildTarget namedTarget) { if (!TryResolveBuildTarget(name, out var buildTarget)) { namedTarget = default; return GetUnknownBuildTargetMessage(name); } var targetGroup = GetTargetGroup(buildTarget); if (targetGroup == BuildTargetGroup.Unknown) { namedTarget = default; return IsVisionOSTarget(buildTarget) ? "VisionOS build target is available, but its BuildTargetGroup is not exposed by this Unity editor installation." : $"Build target group could not be resolved for target '{buildTarget}'."; } namedTarget = NamedBuildTarget.FromBuildTargetGroup(targetGroup); return null; } public static string GetUnknownBuildTargetMessage(string name) { if (string.Equals(name, "visionos", StringComparison.OrdinalIgnoreCase)) { return "VisionOS build target is not available in this Unity editor installation. " + "Install the visionOS build support module or use a Unity version/configuration that exposes BuildTarget.VisionOS."; } return $"Unknown build target: '{name}'. Valid targets: {GetValidTargetsList()}."; } private static string GetValidTargetsList() { string validTargets = "windows64, osx, linux64, android, ios, webgl, uwp, tvos"; if (TryParseDefinedBuildTarget(VisionOSName, out _)) { validTargets += ", visionos"; } return validTargets; } private static bool IsVisionOSTarget(BuildTarget target) { return string.Equals(target.ToString(), VisionOSName, StringComparison.OrdinalIgnoreCase); } private static bool TryParseDefinedBuildTarget(string name, out BuildTarget target) { target = default; if (int.TryParse(name, out _)) { return false; } return Enum.TryParse(name, true, out target) && Enum.IsDefined(typeof(BuildTarget), target); } public static string GetDefaultOutputPath(BuildTarget target, string productName) { string basePath = $"Builds/{target}"; switch (target) { case BuildTarget.StandaloneWindows: case BuildTarget.StandaloneWindows64: return $"{basePath}/{productName}.exe"; case BuildTarget.StandaloneOSX: return $"{basePath}/{productName}.app"; case BuildTarget.StandaloneLinux64: return $"{basePath}/{productName}.x86_64"; case BuildTarget.Android: return EditorUserBuildSettings.buildAppBundle ? $"{basePath}/{productName}.aab" : $"{basePath}/{productName}.apk"; case BuildTarget.iOS: case BuildTarget.WebGL: return $"{basePath}/{productName}"; default: return $"{basePath}/{productName}"; } } public static int ResolveSubtarget(string subtarget) { if (string.IsNullOrEmpty(subtarget)) return (int)StandaloneBuildSubtarget.Player; string lower = subtarget.ToLowerInvariant(); if (lower == "server") return (int)StandaloneBuildSubtarget.Server; return (int)StandaloneBuildSubtarget.Player; } } }