FrameRateBooster
FrameRateBooster copied to clipboard
Error after building from code
Unity 2021.3.35f1 Console
[Frame Rate Booster] Couldn't locate recursively the assembly containing the optimizations FrameRateBooster.Optimizations.dll in the build folder C:\Users\pje\Unity\game\Builds\StandaloneWindows\game 1.0
UnityEngine.Debug:LogError (object)
ToolBuddy.FrameRateBooster.Optimizer.Optimizer:GetUniqueTargetAssembly (string,System.Collections.Generic.IEnumerable`1<string>,string,string,string&) (at Assets/Plugins/ToolBuddy/Assets/FrameRateBooster/Optimizer/Editor/Optimizer.cs:150)
ToolBuddy.FrameRateBooster.Optimizer.Optimizer:OptimizeBuild (UnityEditor.BuildTarget,string) (at Assets/Plugins/ToolBuddy/Assets/FrameRateBooster/Optimizer/Editor/Optimizer.cs:119)
ToolBuddy.FrameRateBooster.Optimizer.Optimizer:OnPostprocessBuild (UnityEditor.BuildTarget,string) (at Assets/Plugins/ToolBuddy/Assets/FrameRateBooster/Optimizer/Editor/Optimizer.cs:82)
UnityEditor.BuildPipeline:BuildPlayer (UnityEditor.BuildPlayerOptions)
BuildTools:BuildIndividualTarget (UnityEditor.BuildTarget) (at Assets/~BuildTools/Editor/BuildTools.cs:220)
BuildTools/<PerformBuild>d__8:MoveNext () (at Assets/~BuildTools/Editor/BuildTools.cs:144)
Unity.EditorCoroutines.Editor.EditorCoroutine/YieldProcessor:MoveNext (System.Collections.IEnumerator) (at Library/PackageCache/[email protected]/Editor/EditorCoroutine.cs:80)
Unity.EditorCoroutines.Editor.EditorCoroutine:ProcessIEnumeratorRecursive (System.Collections.IEnumerator) (at Library/PackageCache/[email protected]/Editor/EditorCoroutine.cs:134)
Unity.EditorCoroutines.Editor.EditorCoroutine:MoveNext () (at Library/PackageCache/[email protected]/Editor/EditorCoroutine.cs:115)
UnityEditor.EditorApplication:Internal_CallUpdateFunctions ()
BuildTools.cs
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.Build.Reporting;
using Unity.EditorCoroutines.Editor;
using UnityEditor.AddressableAssets.Settings;
using System;
using UnityEditor.AddressableAssets.Build;
using System.Threading.Tasks;
using System.Diagnostics;
using Debug = UnityEngine.Debug;
using System.IO;
public class BuildTools : EditorWindow
{
[MenuItem("Tools/Build Tools")]
public static void OnShowTools()
{
GetWindow<BuildTools>();
}
private BuildTargetGroup GetTargetGroupForTarget(BuildTarget target) => target switch
{
BuildTarget.StandaloneOSX => BuildTargetGroup.Standalone,
BuildTarget.StandaloneWindows => BuildTargetGroup.Standalone,
BuildTarget.iOS => BuildTargetGroup.iOS,
BuildTarget.Android => BuildTargetGroup.Android,
BuildTarget.StandaloneWindows64 => BuildTargetGroup.Standalone,
BuildTarget.WebGL => BuildTargetGroup.WebGL,
BuildTarget.StandaloneLinux64 => BuildTargetGroup.Standalone,
_ => BuildTargetGroup.Unknown
};
readonly Dictionary<BuildTarget, bool> TargetsToBuild = new();
readonly List<BuildTarget> AvailableTargets = new();
void UpdateTarget()
{
BuildToolsP.buildTarget = EditorUserBuildSettings.activeBuildTarget;
}
[System.Obsolete]
private void OnEnable()
{
BuildToolsP.buildTarget = EditorUserBuildSettings.activeBuildTarget;
EditorUserBuildSettings.activeBuildTargetChanged = new(UpdateTarget);
AvailableTargets.Clear();
var buildTargets = System.Enum.GetValues(typeof(BuildTarget));
foreach(var buildTargetValue in buildTargets)
{
BuildTarget target = (BuildTarget)buildTargetValue;
// skip if unsupported
if (!BuildPipeline.IsBuildTargetSupported(GetTargetGroupForTarget(target), target))
continue;
AvailableTargets.Add(target);
// add the target if not in the build list
if (!TargetsToBuild.ContainsKey(target))
TargetsToBuild[target] = false;
}
// check if any targets have gone away
if (TargetsToBuild.Count > AvailableTargets.Count)
{
// build the list of removed targets
List<BuildTarget> targetsToRemove = new();
foreach(var target in TargetsToBuild.Keys)
{
if (!AvailableTargets.Contains(target))
targetsToRemove.Add(target);
}
// cleanup the removed targets
foreach(var target in targetsToRemove)
TargetsToBuild.Remove(target);
}
}
private void OnGUI()
{
GUILayout.Label("Platforms to Build", EditorStyles.boldLabel);
// display the build targets
int numEnabled = 0;
foreach(var target in AvailableTargets)
{
TargetsToBuild[target] = EditorGUILayout.Toggle(target.ToString(), TargetsToBuild[target]);
if (TargetsToBuild[target])
numEnabled++;
}
if (numEnabled > 0)
{
// attempt to build?
string prompt = numEnabled == 1 ? "Build 1 Platform" : $"Build {numEnabled} Platforms";
if (GUILayout.Button(prompt))
{
List<BuildTarget> selectedTargets = new();
foreach (var target in AvailableTargets)
{
if (TargetsToBuild[target])
selectedTargets.Add(target);
}
EditorCoroutineUtility.StartCoroutine(PerformBuild(selectedTargets), this);
}
}
}
int buildAllProgressID = 0;
IEnumerator PerformBuild(List<BuildTarget> targetsToBuild)
{
try
{
Progress.Remove(buildAllProgressID);
}
catch{ }
// show the progress display
buildAllProgressID = Progress.Start("Build All", "Building all selected platforms", Progress.Options.Sticky);
Progress.ShowDetails();
yield return new EditorWaitForSeconds(1f);
BuildTarget originalTarget = EditorUserBuildSettings.activeBuildTarget;
// build each target
for (int targetIndex = 0; targetIndex < targetsToBuild.Count; ++targetIndex)
{
var buildTarget = targetsToBuild[targetIndex];
Progress.Report(buildAllProgressID, targetIndex + 1, targetsToBuild.Count);
int buildTaskProgressID = Progress.Start($"Build {buildTarget}", null, Progress.Options.Sticky, buildAllProgressID);
yield return new EditorWaitForSeconds(1f);
// perform the build
if (!BuildIndividualTarget(buildTarget))
{
Progress.Finish(buildTaskProgressID, Progress.Status.Failed);
Progress.Finish(buildAllProgressID, Progress.Status.Failed);
if (EditorUserBuildSettings.activeBuildTarget != originalTarget)
EditorUserBuildSettings.SwitchActiveBuildTargetAsync(GetTargetGroupForTarget(originalTarget), originalTarget);
BuildToolsP.buildTarget = originalTarget;
yield break;
}
Progress.Finish(buildTaskProgressID, Progress.Status.Succeeded);
yield return new EditorWaitForSeconds(1f);
}
Progress.Finish(buildAllProgressID, Progress.Status.Succeeded);
if (EditorUserBuildSettings.activeBuildTarget != originalTarget)
EditorUserBuildSettings.SwitchActiveBuildTargetAsync(GetTargetGroupForTarget(originalTarget), originalTarget);
BuildToolsP.buildTarget = originalTarget;
yield return null;
}
bool BuildIndividualTarget(BuildTarget target)
{
EditorUserBuildSettings.SwitchActiveBuildTarget(GetTargetGroupForTarget(target), target);
BuildToolsP.buildTarget = target;
BuildPlayerOptions options = new();
// get the list of scenes
List<string> scenes = new();
foreach (var scene in EditorBuildSettings.scenes)
scenes.Add(scene.path);
// configure the build
options.scenes = scenes.ToArray();
options.target = target;
options.targetGroup = GetTargetGroupForTarget(target);
string name = $"{PlayerSettings.productName}";
string folder = $"{name} {Application.version}";
// set the location path name
if (target == BuildTarget.Android)
{
options.locationPathName = System.IO.Path.Combine("Builds", target.ToString(), $"{folder}.apk");
}
else if (target == BuildTarget.StandaloneWindows)
{
options.locationPathName = System.IO.Path.Combine("Builds", target.ToString(), folder, $"{name}.exe");
}
else if (target == BuildTarget.StandaloneWindows64)
{
options.locationPathName = System.IO.Path.Combine("Builds", target.ToString(), folder, $"{name}.exe");
}
else if (target == BuildTarget.StandaloneLinux64)
{
options.locationPathName = System.IO.Path.Combine("Builds", target.ToString(), folder, $"{name}.x86_64");
}
else
options.locationPathName = System.IO.Path.Combine("Builds", target.ToString(), folder, name);
if (BuildPipeline.BuildCanBeAppended(target, options.locationPathName) == CanAppendBuild.Yes)
options.options = BuildOptions.AcceptExternalModificationsToPlayer;
else
options.options = BuildOptions.None;
// build the addressables
if (!BuildToolsAddr.BuildAddressables())
{
return false;
}
// start the build
BuildReport report = BuildPipeline.BuildPlayer(options);
// was the build successful?
if (report.summary.result == BuildResult.Succeeded)
{
Debug.Log($"Build for {target} completed in " +
$"{report.summary.totalTime.Seconds} seconds, " +
$"{Mathf.RoundToInt(report.summary.totalSize / 1048576 * 10) / 10} MB");
if (target == BuildTarget.Android)
{
OpenFileLocation(report.summary.outputPath.Replace("/", "\\"));
}
else
{
string p0 = Application.dataPath;
p0 = p0.Replace("/Assets", Path.Combine("\\Builds", target.ToString()));
string p1 = Path.Combine(p0, folder).Replace("/", "\\");
string p2 = Path.Combine(p0, folder + ".7z").Replace("/", "\\");
PackInto7zip(p1, true, p2);
}
return true;
}
Debug.LogError($"Build for {target} failed");
return false;
}
public async void PackInto7zip(string sourceFolderPath, bool doOpenFileLocation = true, string outputArchivePath = "")
{
await Task.Run(() =>
{
if(outputArchivePath == "")
{
outputArchivePath = sourceFolderPath + "\\..";
}
string sevenZipPath = "C:\\Program Files\\7-Zip\\7zG.exe"; // Update this path based on your 7zip installation
ProcessStartInfo processInfo = new()
{
FileName = sevenZipPath,
Arguments = $"a -t7z -m0=lzma2 -mx9 -mfb=64 -md=32m -ms=on \"{outputArchivePath}\" \"{sourceFolderPath}\"",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
Process process = new()
{
StartInfo = processInfo
};
process.Start();
process.WaitForExit();
if (process.ExitCode == 0)
{
Debug.Log("7zip compression successful.");
if (doOpenFileLocation)
{
OpenFileLocation(outputArchivePath);
}
}
else
{
Debug.LogError($"7zip compression failed with exit code {process.ExitCode}. Check the console for details.");
}
});
}
public void OpenFileLocation(string location)
{
Process.Start("explorer.exe", location + "\\..");
}
}
public class BuildToolsAddr
{
public static string build_script
= "Assets/AddressableAssetsData/DataBuilders/BuildScriptPackedMode.asset";
public static string settings_asset
= "Assets/AddressableAssetsData/AddressableAssetSettings.asset";
public static string profile_name = "Default";
private static AddressableAssetSettings settings;
static void GetSettingsObject(string settingsAsset)
{
// This step is optional, you can also use the default settings:
//settings = AddressableAssetSettingsDefaultObject.Settings;
settings
= AssetDatabase.LoadAssetAtPath<ScriptableObject>(settingsAsset)
as AddressableAssetSettings;
if (settings == null)
Debug.LogError($"{settingsAsset} couldn't be found or isn't " +
$"a settings object.");
}
static void SetProfile(string profile)
{
string profileId = settings.profileSettings.GetProfileId(profile);
if (String.IsNullOrEmpty(profileId))
Debug.LogWarning($"Couldn't find a profile named, {profile}, " +
$"using current profile instead.");
else
settings.activeProfileId = profileId;
}
static void SetBuilder(IDataBuilder builder)
{
int index = settings.DataBuilders.IndexOf((ScriptableObject)builder);
if (index > 0)
settings.ActivePlayerDataBuilderIndex = index;
else
Debug.LogWarning($"{builder} must be added to the " +
$"DataBuilders list before it can be made " +
$"active. Using last run builder instead.");
}
static bool BuildAddressableContent()
{
AddressableAssetSettings
.BuildPlayerContent(out AddressablesPlayerBuildResult result);
bool success = string.IsNullOrEmpty(result.Error);
if (!success)
{
Debug.LogError("Addressables build error encountered: " + result.Error);
}
return success;
}
[MenuItem("Window/Asset Management/Addressables/Build Addressables only")]
public static bool BuildAddressables()
{
AddressableAssetSettings.CleanPlayerContent();
GetSettingsObject(settings_asset);
SetProfile(profile_name);
if (AssetDatabase.LoadAssetAtPath<ScriptableObject>(build_script) is not IDataBuilder builderScript)
{
Debug.LogError(build_script + " couldn't be found or isn't a build script.");
return false;
}
SetBuilder(builderScript);
return BuildAddressableContent();
}
}
public static class BuildToolsP
{
public static BuildTarget buildTarget;
}
#endif