1369 lines
52 KiB
C#
1369 lines
52 KiB
C#
using UnityEngine;
|
|
using UnityEditor;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using UnityEditor.Build;
|
|
using System.Reflection;
|
|
using UnityEditor.Build.Reporting;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
namespace FMODUnity
|
|
{
|
|
[InitializeOnLoad]
|
|
public class EventManager : MonoBehaviour
|
|
{
|
|
private const string FMODLabel = "FMOD";
|
|
|
|
private const string AssetsFolderName = "Assets";
|
|
|
|
private const string CacheAssetName = "FMODStudioCache";
|
|
public static string CacheAssetFullName = EditorUtils.WritableAssetPath(CacheAssetName);
|
|
private static EventCache eventCache;
|
|
|
|
private const string StringBankExtension = "strings.bank";
|
|
private const string BankExtension = "bank";
|
|
|
|
#if UNITY_EDITOR
|
|
[MenuItem("FMOD/Refresh Banks", priority = 1)]
|
|
public static void RefreshBanks()
|
|
{
|
|
string result = UpdateCache();
|
|
|
|
if (eventCache != null)
|
|
{
|
|
OnCacheChange();
|
|
if (Settings.Instance.ImportType == ImportType.AssetBundle)
|
|
{
|
|
UpdateBankStubAssets(EditorUserBuildSettings.activeBuildTarget);
|
|
}
|
|
}
|
|
|
|
BankRefresher.HandleBankRefresh(result);
|
|
}
|
|
#endif
|
|
|
|
private static void ClearCache()
|
|
{
|
|
eventCache.CacheTime = DateTime.MinValue;
|
|
eventCache.EditorBanks.Clear();
|
|
eventCache.EditorEvents.Clear();
|
|
eventCache.EditorParameters.Clear();
|
|
eventCache.StringsBanks.Clear();
|
|
eventCache.MasterBanks.Clear();
|
|
if (Settings.Instance && Settings.Instance.BanksToLoad != null)
|
|
Settings.Instance.BanksToLoad.Clear();
|
|
}
|
|
|
|
private static void AffirmEventCache()
|
|
{
|
|
if (eventCache == null)
|
|
{
|
|
UpdateCache();
|
|
}
|
|
}
|
|
|
|
private static string UpdateCache()
|
|
{
|
|
if (eventCache == null)
|
|
{
|
|
eventCache = AssetDatabase.LoadAssetAtPath(CacheAssetFullName, typeof(EventCache)) as EventCache;
|
|
|
|
// If new libraries need to be staged, or the staging process is in progress, clear the cache and exit.
|
|
if (StagingSystem.SourceLibsExist)
|
|
{
|
|
if (eventCache != null)
|
|
{
|
|
ClearCache();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
if (eventCache == null || eventCache.cacheVersion != FMOD.VERSION.number)
|
|
{
|
|
RuntimeUtils.DebugLog("FMOD: Event cache is missing or in an old format; creating a new instance.");
|
|
|
|
eventCache = ScriptableObject.CreateInstance<EventCache>();
|
|
eventCache.cacheVersion = FMOD.VERSION.number;
|
|
|
|
Directory.CreateDirectory(Path.GetDirectoryName(CacheAssetFullName));
|
|
AssetDatabase.CreateAsset(eventCache, CacheAssetFullName);
|
|
}
|
|
}
|
|
|
|
var settings = Settings.Instance;
|
|
var editorSettings = EditorSettings.Instance;
|
|
|
|
if (string.IsNullOrEmpty(settings.SourceBankPath))
|
|
{
|
|
ClearCache();
|
|
return null;
|
|
}
|
|
|
|
string defaultBankFolder = null;
|
|
|
|
if (!settings.HasPlatforms)
|
|
{
|
|
defaultBankFolder = settings.SourceBankPath;
|
|
}
|
|
else
|
|
{
|
|
Platform platform = editorSettings.CurrentEditorPlatform;
|
|
|
|
if (platform == settings.DefaultPlatform)
|
|
{
|
|
platform = settings.PlayInEditorPlatform;
|
|
}
|
|
|
|
defaultBankFolder = RuntimeUtils.GetCommonPlatformPath(Path.Combine(settings.SourceBankPath, platform.BuildDirectory));
|
|
}
|
|
|
|
string[] bankPlatforms = EditorUtils.GetBankPlatforms();
|
|
string[] bankFolders = new string[bankPlatforms.Length];
|
|
for (int i = 0; i < bankPlatforms.Length; i++)
|
|
{
|
|
bankFolders[i] = RuntimeUtils.GetCommonPlatformPath(Path.Combine(settings.SourceBankPath, bankPlatforms[i]));
|
|
}
|
|
|
|
// Get all banks and set cache time to most recent write time
|
|
List<string> bankFileNames = new List<string>(Directory.GetFiles(defaultBankFolder, "*.bank", SearchOption.AllDirectories));
|
|
DateTime lastWriteTime = bankFileNames.Max(fileName => File.GetLastWriteTime(fileName));
|
|
|
|
// Exit early if cache is up to date
|
|
if (lastWriteTime == eventCache.CacheTime)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
eventCache.CacheTime = lastWriteTime;
|
|
|
|
// Remove string banks from list
|
|
bankFileNames.RemoveAll(x => x.Contains(".strings"));
|
|
|
|
List<string> stringBanks = new List<string>(0);
|
|
try
|
|
{
|
|
var files = Directory.GetFiles(defaultBankFolder, "*." + StringBankExtension, SearchOption.AllDirectories);
|
|
stringBanks = new List<string>(files);
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
|
|
// Strip out OSX resource-fork files that appear on FAT32
|
|
stringBanks.RemoveAll((x) => Path.GetFileName(x).StartsWith("._"));
|
|
|
|
if (stringBanks.Count == 0)
|
|
{
|
|
ClearCache();
|
|
return string.Format("Directory {0} doesn't contain any banks.\nBuild the banks in Studio or check the path in the settings.", defaultBankFolder);
|
|
}
|
|
|
|
// Stop editor preview so no stale data being held
|
|
EditorUtils.StopAllPreviews();
|
|
|
|
bool reloadPreviewBanks = EditorUtils.PreviewBanksLoaded;
|
|
if (reloadPreviewBanks)
|
|
{
|
|
EditorUtils.UnloadPreviewBanks();
|
|
}
|
|
|
|
List<string> reducedStringBanksList = new List<string>();
|
|
HashSet<FMOD.GUID> stringBankGuids = new HashSet<FMOD.GUID>();
|
|
|
|
foreach (string stringBankPath in stringBanks)
|
|
{
|
|
FMOD.Studio.Bank stringBank;
|
|
EditorUtils.CheckResult(EditorUtils.System.loadBankFile(stringBankPath, FMOD.Studio.LOAD_BANK_FLAGS.NORMAL, out stringBank));
|
|
|
|
if (!stringBank.isValid())
|
|
{
|
|
return string.Format("{0} is not a valid bank.", stringBankPath);
|
|
}
|
|
else
|
|
{
|
|
// Unload the strings bank
|
|
stringBank.unload();
|
|
}
|
|
|
|
FMOD.GUID stringBankGuid;
|
|
EditorUtils.CheckResult(stringBank.getID(out stringBankGuid));
|
|
|
|
if (!stringBankGuids.Add(stringBankGuid))
|
|
{
|
|
// If we encounter multiple string banks with the same GUID then only use the first. This handles the scenario where
|
|
// a Studio project is cloned and extended for DLC with a new master bank name.
|
|
continue;
|
|
}
|
|
|
|
reducedStringBanksList.Add(stringBankPath);
|
|
}
|
|
|
|
stringBanks = reducedStringBanksList;
|
|
|
|
// Reload the strings banks
|
|
List<FMOD.Studio.Bank> loadedStringsBanks = new List<FMOD.Studio.Bank>();
|
|
|
|
bool eventRenameOccurred = false;
|
|
|
|
try
|
|
{
|
|
AssetDatabase.StartAssetEditing();
|
|
|
|
eventCache.EditorBanks.ForEach((x) => x.Exists = false);
|
|
HashSet<string> masterBankFileNames = new HashSet<string>();
|
|
|
|
foreach (string stringBankPath in stringBanks)
|
|
{
|
|
FMOD.Studio.Bank stringBank;
|
|
EditorUtils.CheckResult(EditorUtils.System.loadBankFile(stringBankPath, FMOD.Studio.LOAD_BANK_FLAGS.NORMAL, out stringBank));
|
|
|
|
if (!stringBank.isValid())
|
|
{
|
|
ClearCache();
|
|
return string.Format("{0} is not a valid bank.", stringBankPath);
|
|
}
|
|
|
|
loadedStringsBanks.Add(stringBank);
|
|
|
|
FileInfo stringBankFileInfo = new FileInfo(stringBankPath);
|
|
|
|
string masterBankFileName = Path.GetFileName(stringBankPath).Replace(StringBankExtension, BankExtension);
|
|
masterBankFileNames.Add(masterBankFileName);
|
|
|
|
EditorBankRef stringsBankRef = eventCache.StringsBanks.Find(x => RuntimeUtils.GetCommonPlatformPath(stringBankPath) == x.Path);
|
|
|
|
if (stringsBankRef == null)
|
|
{
|
|
stringsBankRef = ScriptableObject.CreateInstance<EditorBankRef>();
|
|
stringsBankRef.FileSizes = new List<EditorBankRef.NameValuePair>();
|
|
AssetDatabase.AddObjectToAsset(stringsBankRef, eventCache);
|
|
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(stringsBankRef));
|
|
eventCache.EditorBanks.Add(stringsBankRef);
|
|
eventCache.StringsBanks.Add(stringsBankRef);
|
|
}
|
|
|
|
stringsBankRef.SetPath(stringBankPath, defaultBankFolder);
|
|
string studioPath;
|
|
stringBank.getPath(out studioPath);
|
|
stringsBankRef.SetStudioPath(studioPath);
|
|
stringsBankRef.LastModified = stringBankFileInfo.LastWriteTime;
|
|
stringsBankRef.Exists = true;
|
|
stringsBankRef.FileSizes.Clear();
|
|
|
|
if (Settings.Instance.HasPlatforms)
|
|
{
|
|
for (int i = 0; i < bankPlatforms.Length; i++)
|
|
{
|
|
stringsBankRef.FileSizes.Add(new EditorBankRef.NameValuePair(bankPlatforms[i], stringBankFileInfo.Length));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
stringsBankRef.FileSizes.Add(new EditorBankRef.NameValuePair("", stringBankFileInfo.Length));
|
|
}
|
|
}
|
|
|
|
eventCache.EditorParameters.ForEach((x) => x.Exists = false);
|
|
|
|
foreach (string bankFileName in bankFileNames)
|
|
{
|
|
EditorBankRef bankRef = eventCache.EditorBanks.Find((x) => RuntimeUtils.GetCommonPlatformPath(bankFileName) == x.Path);
|
|
|
|
// New bank we've never seen before
|
|
if (bankRef == null)
|
|
{
|
|
bankRef = ScriptableObject.CreateInstance<EditorBankRef>();
|
|
AssetDatabase.AddObjectToAsset(bankRef, eventCache);
|
|
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(bankRef));
|
|
|
|
bankRef.SetPath(bankFileName, defaultBankFolder);
|
|
bankRef.LastModified = DateTime.MinValue;
|
|
bankRef.FileSizes = new List<EditorBankRef.NameValuePair>();
|
|
|
|
eventCache.EditorBanks.Add(bankRef);
|
|
}
|
|
|
|
bankRef.Exists = true;
|
|
|
|
FileInfo bankFileInfo = new FileInfo(bankFileName);
|
|
|
|
// Update events from this bank if it has been modified,
|
|
// or it is a master bank (so that we get any global parameters)
|
|
if (bankRef.LastModified != bankFileInfo.LastWriteTime
|
|
|| masterBankFileNames.Contains(Path.GetFileName(bankFileName)))
|
|
{
|
|
bankRef.LastModified = bankFileInfo.LastWriteTime;
|
|
UpdateCacheBank(bankRef, ref eventRenameOccurred);
|
|
}
|
|
|
|
// Update file sizes
|
|
bankRef.FileSizes.Clear();
|
|
if (Settings.Instance.HasPlatforms)
|
|
{
|
|
for (int i = 0; i < bankPlatforms.Length; i++)
|
|
{
|
|
string platformBankPath = RuntimeUtils.GetCommonPlatformPath(bankFolders[i] + bankFileName.Replace(defaultBankFolder, ""));
|
|
var fileInfo = new FileInfo(platformBankPath);
|
|
if (fileInfo.Exists)
|
|
{
|
|
bankRef.FileSizes.Add(new EditorBankRef.NameValuePair(bankPlatforms[i], fileInfo.Length));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string platformBankPath = RuntimeUtils.GetCommonPlatformPath(Path.Combine(Settings.Instance.SourceBankPath, bankFileName));
|
|
var fileInfo = new FileInfo(platformBankPath);
|
|
if (fileInfo.Exists)
|
|
{
|
|
bankRef.FileSizes.Add(new EditorBankRef.NameValuePair("", fileInfo.Length));
|
|
}
|
|
}
|
|
|
|
if (masterBankFileNames.Contains(bankFileInfo.Name))
|
|
{
|
|
if (!eventCache.MasterBanks.Exists(x => RuntimeUtils.GetCommonPlatformPath(bankFileName) == x.Path))
|
|
{
|
|
eventCache.MasterBanks.Add(bankRef);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Remove any stale entries from bank, event and parameter lists
|
|
eventCache.EditorBanks.FindAll((bankRef) => !bankRef.Exists).ForEach((bankRef) =>
|
|
{
|
|
eventCache.EditorEvents.ForEach((eventRef) => eventRef.Banks.Remove(bankRef));
|
|
DestroyImmediate(bankRef, true);
|
|
});
|
|
eventCache.EditorBanks.RemoveAll((x) => x == null);
|
|
eventCache.MasterBanks.RemoveAll((x) => x == null);
|
|
eventCache.StringsBanks.RemoveAll((x) => x == null);
|
|
|
|
eventCache.EditorEvents.FindAll((eventRef) => eventRef.Banks.Count == 0).ForEach((eventRef) =>
|
|
{
|
|
eventRef.Parameters.ForEach((paramRef) => DestroyImmediate(paramRef, true));
|
|
DestroyImmediate(eventRef, true);
|
|
});
|
|
eventCache.EditorEvents.RemoveAll((x) => x == null);
|
|
|
|
eventCache.EditorParameters.FindAll((paramRef) => !paramRef.Exists).ForEach((paramRef) =>
|
|
{
|
|
DestroyImmediate(paramRef, true);
|
|
});
|
|
eventCache.EditorParameters.RemoveAll((x) => x == null);
|
|
|
|
AssetDatabase.SaveAssets();
|
|
}
|
|
finally
|
|
{
|
|
// Unload the strings banks
|
|
loadedStringsBanks.ForEach(x => x.unload());
|
|
AssetDatabase.StopAssetEditing();
|
|
|
|
if (reloadPreviewBanks)
|
|
{
|
|
EditorUtils.LoadPreviewBanks();
|
|
}
|
|
|
|
RuntimeUtils.DebugLog("FMOD: Cache updated.");
|
|
}
|
|
|
|
if (eventRenameOccurred)
|
|
{
|
|
EditorApplication.delayCall += ShowEventsRenamedDialog;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private static void ShowEventsRenamedDialog()
|
|
{
|
|
bool runUpdater = EditorUtility.DisplayDialog("Events Renamed",
|
|
string.Format("Some events have been renamed in FMOD Studio. Do you want to run {0} " +
|
|
"to find and update any references to them?", EventReferenceUpdater.MenuPath), "Yes", "No");
|
|
|
|
if (runUpdater)
|
|
{
|
|
EventReferenceUpdater.ShowWindow();
|
|
}
|
|
}
|
|
|
|
private static void UpdateCacheBank(EditorBankRef bankRef, ref bool renameOccurred)
|
|
{
|
|
// Clear out any cached events from this bank
|
|
eventCache.EditorEvents.ForEach((x) => x.Banks.Remove(bankRef));
|
|
|
|
FMOD.Studio.Bank bank;
|
|
FMOD.RESULT loadResult = EditorUtils.System.loadBankFile(bankRef.Path, FMOD.Studio.LOAD_BANK_FLAGS.NORMAL, out bank);
|
|
|
|
if (loadResult == FMOD.RESULT.OK)
|
|
{
|
|
// Get studio path
|
|
string studioPath;
|
|
bank.getPath(out studioPath);
|
|
bankRef.SetStudioPath(studioPath);
|
|
|
|
// Iterate all events in the bank and cache them
|
|
FMOD.Studio.EventDescription[] eventList;
|
|
var result = bank.getEventList(out eventList);
|
|
if (result == FMOD.RESULT.OK)
|
|
{
|
|
foreach (var eventDesc in eventList)
|
|
{
|
|
string path;
|
|
result = eventDesc.getPath(out path);
|
|
|
|
FMOD.GUID guid;
|
|
eventDesc.getID(out guid);
|
|
|
|
EditorEventRef eventRef = eventCache.EditorEvents.Find((x) => string.Compare(x.Path, path, StringComparison.CurrentCultureIgnoreCase) == 0);
|
|
if (eventRef == null)
|
|
{
|
|
eventRef = ScriptableObject.CreateInstance<EditorEventRef>();
|
|
AssetDatabase.AddObjectToAsset(eventRef, eventCache);
|
|
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(eventRef));
|
|
eventRef.Banks = new List<EditorBankRef>();
|
|
eventCache.EditorEvents.Add(eventRef);
|
|
eventRef.Parameters = new List<EditorParamRef>();
|
|
|
|
if (!renameOccurred)
|
|
{
|
|
EditorEventRef eventRefByGuid = eventCache.EditorEvents.Find((x) => x.Guid == guid);
|
|
|
|
if (eventRefByGuid != null)
|
|
{
|
|
renameOccurred = true;
|
|
}
|
|
}
|
|
}
|
|
else if (eventRef.Guid != guid)
|
|
{
|
|
renameOccurred = true;
|
|
}
|
|
|
|
eventRef.Banks.Add(bankRef);
|
|
eventRef.Guid = guid;
|
|
eventRef.Path = eventRef.name = path;
|
|
eventDesc.is3D(out eventRef.Is3D);
|
|
eventDesc.isOneshot(out eventRef.IsOneShot);
|
|
eventDesc.isStream(out eventRef.IsStream);
|
|
eventDesc.getMinMaxDistance(out eventRef.MinDistance, out eventRef.MaxDistance);
|
|
eventDesc.getLength(out eventRef.Length);
|
|
int paramCount = 0;
|
|
eventDesc.getParameterDescriptionCount(out paramCount);
|
|
eventRef.Parameters.ForEach((x) => x.Exists = false);
|
|
for (int paramIndex = 0; paramIndex < paramCount; paramIndex++)
|
|
{
|
|
FMOD.Studio.PARAMETER_DESCRIPTION param;
|
|
eventDesc.getParameterDescriptionByIndex(paramIndex, out param);
|
|
// Skip if readonly and not global
|
|
if ((param.flags & FMOD.Studio.PARAMETER_FLAGS.READONLY) != 0 && (param.flags & FMOD.Studio.PARAMETER_FLAGS.GLOBAL) == 0)
|
|
{
|
|
continue;
|
|
}
|
|
EditorParamRef paramRef = eventRef.Parameters.Find((x) => x.ID.Equals(param.id));
|
|
if (paramRef == null)
|
|
{
|
|
paramRef = ScriptableObject.CreateInstance<EditorParamRef>();
|
|
AssetDatabase.AddObjectToAsset(paramRef, eventCache);
|
|
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(paramRef));
|
|
eventRef.Parameters.Add(paramRef);
|
|
}
|
|
|
|
InitializeParamRef(paramRef, param, (labelIndex) => {
|
|
string label;
|
|
eventDesc.getParameterLabelByIndex(paramIndex, labelIndex, out label);
|
|
return label;
|
|
});
|
|
|
|
paramRef.name = "parameter:/" + Path.GetFileName(path) + "/" + paramRef.Name;
|
|
paramRef.Exists = true;
|
|
}
|
|
eventRef.Parameters.FindAll((x) => !x.Exists).ForEach((x) => DestroyImmediate(x, true));
|
|
eventRef.Parameters.RemoveAll((x) => x == null);
|
|
}
|
|
}
|
|
|
|
// Update global parameter list for each bank
|
|
FMOD.Studio.PARAMETER_DESCRIPTION[] parameterDescriptions;
|
|
result = EditorUtils.System.getParameterDescriptionList(out parameterDescriptions);
|
|
if (result == FMOD.RESULT.OK)
|
|
{
|
|
for (int i = 0; i < parameterDescriptions.Length; i++)
|
|
{
|
|
FMOD.Studio.PARAMETER_DESCRIPTION param = parameterDescriptions[i];
|
|
if ((param.flags & FMOD.Studio.PARAMETER_FLAGS.GLOBAL) == FMOD.Studio.PARAMETER_FLAGS.GLOBAL)
|
|
{
|
|
EditorParamRef paramRef = eventCache.EditorParameters.Find((x) => x.ID.Equals(param.id));
|
|
if (paramRef == null)
|
|
{
|
|
paramRef = ScriptableObject.CreateInstance<EditorParamRef>();
|
|
AssetDatabase.AddObjectToAsset(paramRef, eventCache);
|
|
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(paramRef));
|
|
eventCache.EditorParameters.Add(paramRef);
|
|
}
|
|
|
|
InitializeParamRef(paramRef, param, (index) => {
|
|
string label;
|
|
EditorUtils.System.getParameterLabelByID(param.id, index, out label);
|
|
return label;
|
|
});
|
|
|
|
paramRef.name = "parameter:/" + param.name;
|
|
EditorUtils.System.lookupPath(param.guid, out paramRef.StudioPath);
|
|
paramRef.Exists = true;
|
|
}
|
|
}
|
|
}
|
|
bank.unload();
|
|
}
|
|
else
|
|
{
|
|
RuntimeUtils.DebugLogError(string.Format("FMOD Studio: Unable to load {0}: {1}", bankRef.Name, FMOD.Error.String(loadResult)));
|
|
eventCache.CacheTime = DateTime.MinValue;
|
|
}
|
|
}
|
|
|
|
private static void InitializeParamRef(EditorParamRef paramRef, FMOD.Studio.PARAMETER_DESCRIPTION description,
|
|
Func<int, string> getLabel)
|
|
{
|
|
paramRef.Name = description.name;
|
|
paramRef.Min = description.minimum;
|
|
paramRef.Max = description.maximum;
|
|
paramRef.Default = description.defaultvalue;
|
|
paramRef.ID = description.id;
|
|
paramRef.IsGlobal = (description.flags & FMOD.Studio.PARAMETER_FLAGS.GLOBAL) != 0;
|
|
|
|
if ((description.flags & FMOD.Studio.PARAMETER_FLAGS.LABELED) != 0)
|
|
{
|
|
paramRef.Type = ParameterType.Labeled;
|
|
paramRef.Labels = GetParameterLabels(description, getLabel);
|
|
}
|
|
else if ((description.flags & FMOD.Studio.PARAMETER_FLAGS.DISCRETE) != 0)
|
|
{
|
|
paramRef.Type = ParameterType.Discrete;
|
|
}
|
|
else
|
|
{
|
|
paramRef.Type = ParameterType.Continuous;
|
|
}
|
|
}
|
|
|
|
private static string[] GetParameterLabels(FMOD.Studio.PARAMETER_DESCRIPTION parameterDescription,
|
|
Func<int, string> getLabel)
|
|
{
|
|
string[] labels = new string[(int)parameterDescription.maximum + 1];
|
|
|
|
for (int i = 0; i <= parameterDescription.maximum; ++i)
|
|
{
|
|
labels[i] = getLabel(i);
|
|
}
|
|
|
|
return labels;
|
|
}
|
|
|
|
static EventManager()
|
|
{
|
|
BuildStatusWatcher.OnBuildStarted += () => {
|
|
BuildTargetChanged();
|
|
CopyToStreamingAssets(EditorUserBuildSettings.activeBuildTarget);
|
|
};
|
|
BuildStatusWatcher.OnBuildEnded += () => {
|
|
UpdateBankStubAssets(EditorUserBuildSettings.activeBuildTarget);
|
|
};
|
|
}
|
|
|
|
public static void Startup()
|
|
{
|
|
EventReference.GuidLookupDelegate = (path) => {
|
|
EditorEventRef editorEventRef = EventFromPath(path);
|
|
|
|
return (editorEventRef != null) ? editorEventRef.Guid : new FMOD.GUID();
|
|
};
|
|
|
|
// Avoid throwing exceptions so we don't stop other startup code from running
|
|
try
|
|
{
|
|
RefreshBanks();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
RuntimeUtils.DebugLogException(e);
|
|
}
|
|
}
|
|
|
|
public static void ValidateEventReferences(Scene scene)
|
|
{
|
|
foreach (GameObject gameObject in scene.GetRootGameObjects())
|
|
{
|
|
MonoBehaviour[] behaviours = gameObject.GetComponentsInChildren<MonoBehaviour>(true);
|
|
|
|
foreach (MonoBehaviour behaviour in behaviours)
|
|
{
|
|
if (behaviour != null)
|
|
{
|
|
if (behaviour is StudioEventEmitter)
|
|
{
|
|
ValidateEventEmitter(behaviour as StudioEventEmitter, scene);
|
|
}
|
|
else
|
|
{
|
|
ValidateEventReferenceFields(behaviour, scene);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static readonly string UpdaterInstructions =
|
|
string.Format("Please run {0} to resolve this issue.", EventReferenceUpdater.MenuPath);
|
|
|
|
private static void ValidateEventEmitter(StudioEventEmitter emitter, Scene scene)
|
|
{
|
|
#pragma warning disable 0618 // Suppress a warning about using the obsolete StudioEventEmitter.Event field
|
|
if (!string.IsNullOrEmpty(emitter.Event))
|
|
#pragma warning restore 0618
|
|
{
|
|
RuntimeUtils.DebugLogWarningFormat("FMOD: A Studio Event Emitter in scene '{0}' on GameObject '{1}' is using the "
|
|
+ "obsolete Event field. {2}",
|
|
scene.name, EditorUtils.GameObjectPath(emitter), UpdaterInstructions);
|
|
}
|
|
|
|
bool changed;
|
|
if (!ValidateEventReference(ref emitter.EventReference, emitter, scene, out changed))
|
|
{
|
|
RuntimeUtils.DebugLogWarningFormat(
|
|
"FMOD: A Studio Event Emitter in scene '{0}' on GameObject '{1}' has an invalid event reference: {2}",
|
|
scene.name, EditorUtils.GameObjectPath(emitter), emitter.EventReference);
|
|
}
|
|
}
|
|
|
|
private static void ValidateEventReferenceFields(MonoBehaviour behaviour, Scene scene)
|
|
{
|
|
Type type = behaviour.GetType();
|
|
|
|
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
|
|
|
foreach (FieldInfo field in fields)
|
|
{
|
|
#pragma warning disable 0618 // Suppress a warning about using the obsolete EventRefAttribute class
|
|
if (EditorUtils.HasAttribute<EventRefAttribute>(field))
|
|
#pragma warning restore 0618
|
|
{
|
|
RuntimeUtils.DebugLogWarningFormat("FMOD: A component of type {0} in scene '{1}' on GameObject '{2}' has an "
|
|
+ "obsolete [EventRef] attribute on field {3}. {4}",
|
|
type.Name, scene.name, EditorUtils.GameObjectPath(behaviour), field.Name,
|
|
UpdaterInstructions);
|
|
}
|
|
else if (field.FieldType == typeof(EventReference))
|
|
{
|
|
EventReference eventReference = (EventReference)field.GetValue(behaviour);
|
|
|
|
bool changed;
|
|
if (!ValidateEventReference(ref eventReference, behaviour, scene, out changed))
|
|
{
|
|
RuntimeUtils.DebugLogWarningFormat(
|
|
"FMOD: A component of type {0} in scene '{1}' on GameObject '{2}' has an "
|
|
+ "invalid event reference in field '{3}': {4}",
|
|
type.Name, scene.name, EditorUtils.GameObjectPath(behaviour), field.Name, eventReference);
|
|
}
|
|
|
|
if (changed)
|
|
{
|
|
field.SetValue(behaviour, eventReference);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Returns true if eventReference is valid, sets changed if eventReference was changed
|
|
private static bool ValidateEventReference(ref EventReference eventReference,
|
|
Component parent, Scene scene, out bool changed)
|
|
{
|
|
changed = false;
|
|
|
|
if (eventReference.IsNull)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
EditorEventRef editorEventRef;
|
|
|
|
EventLinkage eventLinkage = GetEventLinkage(eventReference);
|
|
|
|
if (eventLinkage == EventLinkage.GUID)
|
|
{
|
|
editorEventRef = EventFromGUID(eventReference.Guid);
|
|
|
|
if (editorEventRef == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (eventReference.Path != editorEventRef.Path)
|
|
{
|
|
RuntimeUtils.DebugLogWarningFormat(
|
|
"FMOD: EventReference path '{0}' doesn't match GUID {1} on object '{2}' in scene '{3}'. {4}",
|
|
eventReference.Path, eventReference.Guid, EditorUtils.GameObjectPath(parent), scene.name,
|
|
UpdaterInstructions);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
else if (eventLinkage == EventLinkage.Path)
|
|
{
|
|
editorEventRef = EventFromPath(eventReference.Path);
|
|
|
|
if (editorEventRef == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (eventReference.Guid != editorEventRef.Guid)
|
|
{
|
|
RuntimeUtils.DebugLogWarningFormat(
|
|
"FMOD: Changing EventReference GUID to {0} to match path '{1}' on object '{2}' in scene '{3}'. {4}",
|
|
editorEventRef.Guid, eventReference.Path, EditorUtils.GameObjectPath(parent), scene.name,
|
|
UpdaterInstructions);
|
|
|
|
eventReference.Guid = editorEventRef.Guid;
|
|
EditorUtility.SetDirty(parent);
|
|
|
|
changed = true;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException("Unrecognized EventLinkage: " + eventLinkage);
|
|
}
|
|
}
|
|
|
|
public static void CopyToStreamingAssets(BuildTarget buildTarget)
|
|
{
|
|
if (Settings.Instance.ImportType == ImportType.AssetBundle && BuildPipeline.isBuildingPlayer)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(Settings.Instance.SourceBankPath))
|
|
return;
|
|
|
|
Platform platform = EditorSettings.Instance.GetPlatform(buildTarget);
|
|
|
|
if (platform == Settings.Instance.DefaultPlatform)
|
|
{
|
|
RuntimeUtils.DebugLogWarningFormat("FMOD Studio: copy banks for platform {0} : Unsupported platform", buildTarget);
|
|
return;
|
|
}
|
|
|
|
string bankTargetFolder =
|
|
Settings.Instance.ImportType == ImportType.StreamingAssets
|
|
? Settings.Instance.TargetPath
|
|
: Application.dataPath + (string.IsNullOrEmpty(Settings.Instance.TargetAssetPath) ? "" : '/' + Settings.Instance.TargetAssetPath);
|
|
bankTargetFolder = RuntimeUtils.GetCommonPlatformPath(bankTargetFolder);
|
|
Directory.CreateDirectory(bankTargetFolder);
|
|
|
|
string bankTargetExtension =
|
|
Settings.Instance.ImportType == ImportType.StreamingAssets
|
|
? ".bank"
|
|
: ".bytes";
|
|
|
|
string bankSourceFolder =
|
|
Settings.Instance.HasPlatforms
|
|
? Settings.Instance.SourceBankPath + '/' + platform.BuildDirectory
|
|
: Settings.Instance.SourceBankPath;
|
|
bankSourceFolder = RuntimeUtils.GetCommonPlatformPath(bankSourceFolder);
|
|
|
|
if (Path.GetFullPath(bankTargetFolder).TrimEnd('/').ToUpperInvariant() ==
|
|
Path.GetFullPath(bankSourceFolder).TrimEnd('/').ToUpperInvariant())
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool madeChanges = false;
|
|
|
|
try
|
|
{
|
|
// Clean out any stale .bank files
|
|
string[] existingBankFiles =
|
|
Directory.GetFiles(bankTargetFolder, "*" + bankTargetExtension, SearchOption.AllDirectories);
|
|
|
|
foreach (string bankFilePath in existingBankFiles)
|
|
{
|
|
string bankName = EditorBankRef.CalculateName(bankFilePath, bankTargetFolder);
|
|
|
|
if (!eventCache.EditorBanks.Exists(x => x.Name == bankName))
|
|
{
|
|
string assetPath = bankFilePath.Replace(Application.dataPath, AssetsFolderName);
|
|
|
|
if (AssetHasLabel(assetPath, FMODLabel))
|
|
{
|
|
AssetDatabase.MoveAssetToTrash(assetPath);
|
|
madeChanges = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Copy over any files that don't match timestamp or size or don't exist
|
|
AssetDatabase.StartAssetEditing();
|
|
foreach (var bankRef in eventCache.EditorBanks)
|
|
{
|
|
string sourcePath = bankSourceFolder + "/" + bankRef.Name + ".bank";
|
|
string targetPathRelative = bankRef.Name + bankTargetExtension;
|
|
string targetPathFull = bankTargetFolder + "/" + targetPathRelative;
|
|
|
|
FileInfo sourceInfo = new FileInfo(sourcePath);
|
|
FileInfo targetInfo = new FileInfo(targetPathFull);
|
|
|
|
if (!targetInfo.Exists ||
|
|
sourceInfo.Length != targetInfo.Length ||
|
|
sourceInfo.LastWriteTime != targetInfo.LastWriteTime)
|
|
{
|
|
if (targetInfo.Exists)
|
|
{
|
|
targetInfo.IsReadOnly = false;
|
|
}
|
|
else
|
|
{
|
|
EnsureFoldersExist(targetPathRelative, bankTargetFolder);
|
|
}
|
|
|
|
File.Copy(sourcePath, targetPathFull, true);
|
|
targetInfo = new FileInfo(targetPathFull);
|
|
targetInfo.IsReadOnly = false;
|
|
targetInfo.LastWriteTime = sourceInfo.LastWriteTime;
|
|
|
|
madeChanges = true;
|
|
|
|
string assetString = targetPathFull.Replace(Application.dataPath, "Assets");
|
|
AssetDatabase.ImportAsset(assetString);
|
|
UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(assetString);
|
|
AssetDatabase.SetLabels(obj, new string[] { FMODLabel });
|
|
}
|
|
}
|
|
|
|
RemoveEmptyFMODFolders(bankTargetFolder);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
RuntimeUtils.DebugLogErrorFormat("FMOD Studio: copy banks for platform {0} : copying banks from {1} to {2}",
|
|
platform.DisplayName, bankSourceFolder, bankTargetFolder);
|
|
RuntimeUtils.DebugLogException(exception);
|
|
return;
|
|
}
|
|
finally
|
|
{
|
|
AssetDatabase.StopAssetEditing();
|
|
}
|
|
|
|
if (madeChanges)
|
|
{
|
|
AssetDatabase.SaveAssets();
|
|
AssetDatabase.Refresh();
|
|
RuntimeUtils.DebugLogFormat("FMOD Studio: copy banks for platform {0} : copying banks from {1} to {2} succeeded",
|
|
platform.DisplayName, bankSourceFolder, bankTargetFolder);
|
|
}
|
|
}
|
|
|
|
public static void UpdateBankStubAssets(BuildTarget buildTarget)
|
|
{
|
|
if (Settings.Instance.ImportType != ImportType.AssetBundle
|
|
|| string.IsNullOrEmpty(Settings.Instance.SourceBankPath))
|
|
{
|
|
return;
|
|
}
|
|
|
|
Platform platform = EditorSettings.Instance.GetPlatform(buildTarget);
|
|
|
|
if (platform == Settings.Instance.DefaultPlatform)
|
|
{
|
|
Debug.LogWarningFormat("FMOD: Updating bank stubs: Unsupported platform {0}", buildTarget);
|
|
return;
|
|
}
|
|
|
|
string bankTargetFolder = Application.dataPath;
|
|
|
|
if (!string.IsNullOrEmpty(Settings.Instance.TargetAssetPath))
|
|
{
|
|
bankTargetFolder += "/" + Settings.Instance.TargetAssetPath;
|
|
}
|
|
|
|
bankTargetFolder = RuntimeUtils.GetCommonPlatformPath(bankTargetFolder);
|
|
|
|
string bankSourceFolder = Settings.Instance.SourceBankPath;
|
|
|
|
if (Settings.Instance.HasPlatforms)
|
|
{
|
|
bankSourceFolder += "/" + platform.BuildDirectory;
|
|
}
|
|
|
|
bankSourceFolder = RuntimeUtils.GetCommonPlatformPath(bankSourceFolder);
|
|
|
|
if (Path.GetFullPath(bankTargetFolder).TrimEnd('/').ToUpperInvariant() ==
|
|
Path.GetFullPath(bankSourceFolder).TrimEnd('/').ToUpperInvariant())
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool madeChanges = false;
|
|
|
|
Directory.CreateDirectory(bankTargetFolder);
|
|
|
|
try
|
|
{
|
|
const string BankAssetExtension = ".bytes";
|
|
|
|
// Clean out any stale stubs
|
|
string[] existingBankFiles =
|
|
Directory.GetFiles(bankTargetFolder, "*" + BankAssetExtension, SearchOption.AllDirectories);
|
|
|
|
foreach (string bankFilePath in existingBankFiles)
|
|
{
|
|
string bankName = EditorBankRef.CalculateName(bankFilePath, bankTargetFolder);
|
|
|
|
if (!eventCache.EditorBanks.Exists(x => x.Name == bankName))
|
|
{
|
|
string assetPath = bankFilePath.Replace(Application.dataPath, AssetsFolderName);
|
|
|
|
if (AssetHasLabel(assetPath, FMODLabel))
|
|
{
|
|
AssetDatabase.MoveAssetToTrash(assetPath);
|
|
madeChanges = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Create any stubs that don't exist, and ensure any that do exist have the correct data
|
|
AssetDatabase.StartAssetEditing();
|
|
foreach (var bankRef in eventCache.EditorBanks)
|
|
{
|
|
string sourcePath = bankSourceFolder + "/" + bankRef.Name + ".bank";
|
|
string targetPathRelative = bankRef.Name + BankAssetExtension;
|
|
string targetPathFull = bankTargetFolder + "/" + targetPathRelative;
|
|
|
|
EnsureFoldersExist(targetPathRelative, bankTargetFolder);
|
|
|
|
FileInfo targetInfo = new FileInfo(targetPathFull);
|
|
|
|
string stubData = RuntimeManager.BankStubPrefix + bankRef.Name;
|
|
|
|
// Minimise asset database refreshing by only writing the stub if necessary
|
|
bool writeStub;
|
|
|
|
if (targetInfo.Exists && targetInfo.Length == stubData.Length)
|
|
{
|
|
using (StreamReader reader = targetInfo.OpenText())
|
|
{
|
|
string contents = reader.ReadToEnd();
|
|
writeStub = (contents != stubData);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
writeStub = true;
|
|
}
|
|
|
|
if (writeStub)
|
|
{
|
|
// Create or update the stub
|
|
using (StreamWriter writer = targetInfo.CreateText())
|
|
{
|
|
writer.Write(stubData);
|
|
}
|
|
|
|
madeChanges = true;
|
|
|
|
if (!targetInfo.Exists)
|
|
{
|
|
string assetPath = targetPathFull.Replace(Application.dataPath, "Assets");
|
|
AssetDatabase.ImportAsset(assetPath);
|
|
|
|
UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(assetPath);
|
|
AssetDatabase.SetLabels(obj, new string[] { FMODLabel });
|
|
}
|
|
}
|
|
}
|
|
RemoveEmptyFMODFolders(bankTargetFolder);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
Debug.LogErrorFormat("FMOD: Updating bank stubs in {0} to match {1}",
|
|
bankTargetFolder, bankSourceFolder);
|
|
Debug.LogException(exception);
|
|
return;
|
|
}
|
|
finally
|
|
{
|
|
AssetDatabase.StopAssetEditing();
|
|
}
|
|
|
|
if (madeChanges)
|
|
{
|
|
AssetDatabase.SaveAssets();
|
|
AssetDatabase.Refresh();
|
|
Debug.LogFormat("FMOD: Updated bank stubs in {0} to match {1}", bankTargetFolder, bankSourceFolder);
|
|
}
|
|
}
|
|
|
|
private static void EnsureFoldersExist(string filePath, string basePath)
|
|
{
|
|
string dataPath = Application.dataPath + "/";
|
|
|
|
if (!basePath.StartsWith(dataPath))
|
|
{
|
|
throw new ArgumentException(
|
|
string.Format("Base path {0} is not within the Assets folder", basePath), "basePath");
|
|
}
|
|
|
|
int lastSlash = filePath.LastIndexOf('/');
|
|
|
|
if (lastSlash == -1)
|
|
{
|
|
// No folders
|
|
return;
|
|
}
|
|
|
|
string assetString = filePath.Substring(0, lastSlash);
|
|
|
|
string[] folders = assetString.Split('/');
|
|
string parentFolder = "Assets/" + basePath.Substring(dataPath.Length);
|
|
|
|
for (int i = 0; i < folders.Length; ++i)
|
|
{
|
|
string folderPath = parentFolder + "/" + folders[i];
|
|
|
|
if (!AssetDatabase.IsValidFolder(folderPath))
|
|
{
|
|
AssetDatabase.CreateFolder(parentFolder, folders[i]);
|
|
|
|
var folder = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(folderPath);
|
|
AssetDatabase.SetLabels(folder, new string[] { FMODLabel });
|
|
}
|
|
|
|
parentFolder = folderPath;
|
|
}
|
|
}
|
|
|
|
private static void BuildTargetChanged()
|
|
{
|
|
RefreshBanks();
|
|
#if UNITY_ANDROID
|
|
#if UNITY_2023_1_OR_NEWER
|
|
Settings.Instance.AndroidUseOBB = PlayerSettings.Android.splitApplicationBinary;
|
|
#else
|
|
Settings.Instance.AndroidUseOBB = PlayerSettings.Android.useAPKExpansionFiles;
|
|
#endif //UNITY_2023_1_OR_NEWER
|
|
#endif //UNITY_ANDROID
|
|
}
|
|
|
|
private static void OnCacheChange()
|
|
{
|
|
List<string> masterBanks = new List<string>();
|
|
List<string> banks = new List<string>();
|
|
|
|
var settings = Settings.Instance;
|
|
bool hasChanged = false;
|
|
|
|
foreach (EditorBankRef bankRef in eventCache.MasterBanks)
|
|
{
|
|
masterBanks.Add(bankRef.Name);
|
|
}
|
|
|
|
if (!CompareLists(masterBanks, settings.MasterBanks))
|
|
{
|
|
settings.MasterBanks.Clear();
|
|
settings.MasterBanks.AddRange(masterBanks);
|
|
hasChanged = true;
|
|
}
|
|
|
|
foreach (var bankRef in eventCache.EditorBanks)
|
|
{
|
|
if (!eventCache.MasterBanks.Contains(bankRef) &&
|
|
!eventCache.StringsBanks.Contains(bankRef))
|
|
{
|
|
banks.Add(bankRef.Name);
|
|
}
|
|
}
|
|
banks.Sort((a, b) => string.Compare(a, b, StringComparison.CurrentCultureIgnoreCase));
|
|
|
|
if (!CompareLists(banks, settings.Banks))
|
|
{
|
|
settings.Banks.Clear();
|
|
settings.Banks.AddRange(banks);
|
|
hasChanged = true;
|
|
}
|
|
|
|
if (hasChanged)
|
|
{
|
|
EditorUtility.SetDirty(settings);
|
|
}
|
|
}
|
|
|
|
public static DateTime CacheTime
|
|
{
|
|
get
|
|
{
|
|
if (eventCache != null)
|
|
{
|
|
return eventCache.CacheTime;
|
|
}
|
|
else
|
|
{
|
|
return DateTime.MinValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static List<EditorEventRef> Events
|
|
{
|
|
get
|
|
{
|
|
AffirmEventCache();
|
|
return eventCache.EditorEvents;
|
|
}
|
|
}
|
|
|
|
public static List<EditorBankRef> Banks
|
|
{
|
|
get
|
|
{
|
|
AffirmEventCache();
|
|
return eventCache.EditorBanks;
|
|
}
|
|
}
|
|
|
|
public static List<EditorParamRef> Parameters
|
|
{
|
|
get
|
|
{
|
|
AffirmEventCache();
|
|
return eventCache.EditorParameters;
|
|
}
|
|
}
|
|
|
|
public static List<EditorBankRef> MasterBanks
|
|
{
|
|
get
|
|
{
|
|
AffirmEventCache();
|
|
return eventCache.MasterBanks;
|
|
}
|
|
}
|
|
|
|
public static bool IsLoaded
|
|
{
|
|
get
|
|
{
|
|
return Settings.Instance.SourceBankPath != null;
|
|
}
|
|
}
|
|
|
|
public static bool IsValid
|
|
{
|
|
get
|
|
{
|
|
AffirmEventCache();
|
|
return eventCache.CacheTime != DateTime.MinValue;
|
|
}
|
|
}
|
|
|
|
public static bool IsInitialized
|
|
{
|
|
get
|
|
{
|
|
return eventCache != null;
|
|
}
|
|
}
|
|
|
|
public static EventLinkage GetEventLinkage(EventReference eventReference)
|
|
{
|
|
if (Settings.Instance.EventLinkage == EventLinkage.Path)
|
|
{
|
|
if (string.IsNullOrEmpty(eventReference.Path) && !eventReference.Guid.IsNull)
|
|
{
|
|
return EventLinkage.GUID;
|
|
}
|
|
else
|
|
{
|
|
return EventLinkage.Path;
|
|
}
|
|
}
|
|
else // Assume EventLinkage.GUID
|
|
{
|
|
if (eventReference.Guid.IsNull && !string.IsNullOrEmpty(eventReference.Path))
|
|
{
|
|
return EventLinkage.Path;
|
|
}
|
|
else
|
|
{
|
|
return EventLinkage.GUID;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static EditorEventRef EventFromPath(string pathOrGuid)
|
|
{
|
|
EditorEventRef eventRef;
|
|
if (pathOrGuid.StartsWith("{"))
|
|
{
|
|
eventRef = EventFromGUID(FMOD.GUID.Parse(pathOrGuid));
|
|
}
|
|
else
|
|
{
|
|
eventRef = EventFromString(pathOrGuid);
|
|
}
|
|
return eventRef;
|
|
}
|
|
|
|
public static EditorEventRef EventFromString(string path)
|
|
{
|
|
AffirmEventCache();
|
|
return eventCache.EditorEvents.Find((x) => x.Path.Equals(path, StringComparison.CurrentCultureIgnoreCase));
|
|
}
|
|
|
|
public static EditorEventRef EventFromGUID(FMOD.GUID guid)
|
|
{
|
|
AffirmEventCache();
|
|
return eventCache.EditorEvents.Find((x) => x.Guid == guid);
|
|
}
|
|
|
|
public static EditorParamRef ParamFromPath(string name)
|
|
{
|
|
AffirmEventCache();
|
|
return eventCache.EditorParameters.Find((x) => x.Name.Equals(name, StringComparison.CurrentCultureIgnoreCase));
|
|
}
|
|
|
|
public class ActiveBuildTargetListener : IActiveBuildTargetChanged
|
|
{
|
|
public int callbackOrder{ get { return 0; } }
|
|
public void OnActiveBuildTargetChanged(BuildTarget previousTarget, BuildTarget newTarget)
|
|
{
|
|
BuildTargetChanged();
|
|
}
|
|
}
|
|
|
|
public class PreprocessScene : IProcessSceneWithReport
|
|
{
|
|
public int callbackOrder { get { return 0; } }
|
|
|
|
public void OnProcessScene(Scene scene, BuildReport report)
|
|
{
|
|
if (report == null) return;
|
|
|
|
ValidateEventReferences(scene);
|
|
}
|
|
}
|
|
|
|
private static bool CompareLists(List<string> tempBanks, List<string> banks)
|
|
{
|
|
if (tempBanks.Count != banks.Count)
|
|
return false;
|
|
|
|
for (int i = 0; i < tempBanks.Count; i++)
|
|
{
|
|
if (tempBanks[i] != banks[i])
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private static bool AssetHasLabel(string assetPath, string label)
|
|
{
|
|
UnityEngine.Object asset = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(assetPath);
|
|
string[] labels = AssetDatabase.GetLabels(asset);
|
|
|
|
return labels.Contains(label);
|
|
}
|
|
|
|
public static void RemoveBanks(string basePath)
|
|
{
|
|
if (!Directory.Exists(basePath))
|
|
{
|
|
return;
|
|
}
|
|
|
|
string[] filePaths = Directory.GetFiles(basePath, "*", SearchOption.AllDirectories);
|
|
|
|
foreach (string filePath in filePaths)
|
|
{
|
|
if (!filePath.EndsWith(".meta"))
|
|
{
|
|
string assetPath = filePath.Replace(Application.dataPath, AssetsFolderName);
|
|
|
|
if (AssetHasLabel(assetPath, FMODLabel))
|
|
{
|
|
AssetDatabase.MoveAssetToTrash(assetPath);
|
|
}
|
|
}
|
|
}
|
|
|
|
RemoveEmptyFMODFolders(basePath);
|
|
|
|
if (Directory.GetFileSystemEntries(basePath).Length == 0)
|
|
{
|
|
string baseFolder = basePath.Replace(Application.dataPath, AssetsFolderName);
|
|
AssetDatabase.MoveAssetToTrash(baseFolder);
|
|
}
|
|
}
|
|
|
|
public static void MoveBanks(string from, string to)
|
|
{
|
|
if (!Directory.Exists(from))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!Directory.Exists(to))
|
|
{
|
|
Directory.CreateDirectory(to);
|
|
}
|
|
|
|
string[] oldBankFiles = Directory.GetFiles(from);
|
|
|
|
foreach (var oldBankFileName in oldBankFiles)
|
|
{
|
|
if (oldBankFileName.EndsWith(".meta"))
|
|
continue;
|
|
string assetString = oldBankFileName.Replace(Application.dataPath, "Assets");
|
|
AssetDatabase.ImportAsset(assetString);
|
|
UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(assetString);
|
|
string[] labels = AssetDatabase.GetLabels(obj);
|
|
foreach (string label in labels)
|
|
{
|
|
if (label.Equals("FMOD"))
|
|
{
|
|
AssetDatabase.MoveAsset(assetString, to);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (Directory.GetFiles(Path.GetDirectoryName(oldBankFiles[0])).Length == 0)
|
|
{
|
|
Directory.Delete(Path.GetDirectoryName(oldBankFiles[0]));
|
|
}
|
|
}
|
|
|
|
public static void RemoveEmptyFMODFolders(string basePath)
|
|
{
|
|
string[] folderPaths = Directory.GetDirectories(basePath, "*", SearchOption.AllDirectories);
|
|
|
|
// Process longest paths first so parent folders are cleared out when we get to them
|
|
Array.Sort(folderPaths, (a, b) => b.Length.CompareTo(a.Length));
|
|
|
|
foreach (string folderPath in folderPaths)
|
|
{
|
|
string assetPath = folderPath.Replace(Application.dataPath, AssetsFolderName);
|
|
|
|
if (AssetHasLabel(assetPath, FMODLabel) && Directory.GetFileSystemEntries(folderPath).Length == 0)
|
|
{
|
|
AssetDatabase.MoveAssetToTrash(assetPath);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|