#if !(UNITY_DASHBOARD_WIDGET || UNITY_WEBPLAYER || UNITY_WII || UNITY_WIIU || UNITY_NACL || UNITY_FLASH || UNITY_BLACKBERRY) // Disable under unsupported platforms.
using System.Linq;
#if UNITY_EDITOR
using UnityEditor;
public enum AkWwiseMenuOrder
{
ConvertIDs = 200
}
public enum AkWwiseWindowOrder
{
WwiseSettings = 305,
WwiseInitializationSettings = 306,
WwisePicker = 2300
}
public enum AkWwiseHelpOrder
{
WwiseHelpOrder = 200
}
public partial class AkUtilities
{
#region Migration
///
/// These values represent the maximum value of the "Unity Integration Version" number in the Version.txt file that will migrated.
/// For example, in Wwise v2019.1.0, "Unity Integration Version" is 18 which means that all migrations up until this version are required.
///
public enum MigrationStep
{
AkGameObjListenerMask_v2016_1_0 = 9,
AkGameObjPositionOffsetData_v2016_2_0 = 10,
AkAudioListener_v2017_1_0 = 14,
InitializationSettings_v2018_1_0 = 15,
WwiseTypes_v2018_1_6 = 16,
AkEventCallback_v2018_1_6 = 16,
AkAmbient_v2019_1_0 = 17,
NewScriptableObjectFolder_v2019_2_0 = 18,
///
/// The value that is currently in the Version.txt file.
///
Current
}
public static bool IsMigrationRequired(MigrationStep step)
{
return MigrationStartIndex <= (int)step;
}
public static bool IsMigrating
{
get { return MigrationStartIndex < MigrationStopIndex; }
}
public static void BeginMigration(int startIndex)
{
if (startIndex < MigrationStopIndex)
MigrationStartIndex = startIndex;
}
public static void EndMigration()
{
MigrationStartIndex = MigrationStopIndex;
}
public const int MigrationStopIndex = (int)MigrationStep.Current;
public static int MigrationStartIndex
{
private set { migrationStartIndex = value; }
get { return migrationStartIndex; }
}
private static int migrationStartIndex = MigrationStopIndex;
#endregion
private static readonly System.Collections.Generic.Dictionary s_ProjectBankPaths =
new System.Collections.Generic.Dictionary();
private static System.DateTime s_LastBankPathUpdate = System.DateTime.MinValue;
private static readonly System.Collections.Generic.Dictionary>
s_BaseToCustomPF = new System.Collections.Generic.Dictionary>();
public static bool IsWwiseProjectAvailable { set; get; }
public static bool IsSoundbankGenerationAvailable()
{
return GetWwiseCLI() != null;
}
/// Executes a command-line. Blocks the calling thread until the new process has completed. Returns the logged stdout in one big string.
public static string ExecuteCommandLine(string command, string arguments)
{
var process = new System.Diagnostics.Process();
process.StartInfo.FileName = command;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.Arguments = arguments;
process.Start();
// Synchronously read the standard output of the spawned process.
var reader = process.StandardOutput;
var output = reader.ReadToEnd();
// Waiting for the process to exit directly in the UI thread. Similar cases are working that way too.
// TODO: Is it better to provide a timeout avoid any issues of forever blocking the UI thread? If so, what is
// a relevant timeout value for SoundBank generation?
process.WaitForExit();
process.Close();
return output;
}
private static string GetWwiseCLI()
{
string result = null;
var settings = AkWwiseEditorSettings.Instance;
#if UNITY_EDITOR_WIN
if (!string.IsNullOrEmpty(settings.WwiseInstallationPathWindows))
{
result = System.IO.Path.Combine(settings.WwiseInstallationPathWindows, @"Authoring\x64\Release\bin\WwiseCLI.exe");
if (!System.IO.File.Exists(result))
result = System.IO.Path.Combine(settings.WwiseInstallationPathWindows, @"Authoring\Win32\Release\bin\WwiseCLI.exe");
}
#elif UNITY_EDITOR_OSX
if (!string.IsNullOrEmpty(settings.WwiseInstallationPathMac))
result = System.IO.Path.Combine(settings.WwiseInstallationPathMac, "Contents/Tools/WwiseCLI.sh");
#endif
if (result != null && System.IO.File.Exists(result))
return result;
return null;
}
// Generate all the SoundBanks for all the supported platforms in the Wwise project. This effectively calls Wwise for the project
// that is configured in the UnityWwise integration.
public static void GenerateSoundbanks(System.Collections.Generic.List platforms = null)
{
#if AK_WWISE_ADDRESSABLES && UNITY_ADDRESSABLES
AkWwiseEditorSettings.Instance.CheckGeneratedBanksPath();
#endif
var wwiseProjectFullPath = AkWwiseEditorSettings.WwiseProjectAbsolutePath;
if (IsSoundbankOverrideEnabled(wwiseProjectFullPath))
{
UnityEngine.Debug.LogWarning(
"The SoundBank generation process ignores the SoundBank Settings' Overrides currently enabled in the User settings. The project's SoundBank settings will be used.");
}
var wwiseCli = GetWwiseCLI();
if (wwiseCli == null)
{
UnityEngine.Debug.LogError("Couldn't locate WwiseCLI, unable to generate SoundBanks.");
return;
}
#if UNITY_EDITOR_WIN
var command = wwiseCli;
var arguments = "";
#elif UNITY_EDITOR_OSX
var command = "/bin/sh";
var arguments = "\"" + wwiseCli + "\"";
#else
var command = "";
var arguments = "";
#endif
arguments += " \"" + wwiseProjectFullPath + "\"";
if (platforms != null)
{
foreach (var platform in platforms)
{
if (!string.IsNullOrEmpty(platform))
arguments += " -Platform " + platform;
}
}
arguments += " -GenerateSoundBanks";
var output = ExecuteCommandLine(command, arguments);
if (output.Contains("Process completed successfully."))
{
UnityEngine.Debug.LogFormat("WwiseUnity: SoundBanks generation successful:\n{0}", output);
}
else if (output.Contains("Process completed with warning"))
{
UnityEngine.Debug.LogWarningFormat("WwiseUnity: SoundBanks generation has warning(s):\n{0}", output);
}
else
{
UnityEngine.Debug.LogErrorFormat("WwiseUnity: SoundBanks generation error:\n{0}", output);
}
UnityEditor.AssetDatabase.Refresh();
}
/// Reads the user settings (not the project settings) to check if there is an override currently defined for the SoundBank generation folders.
public static bool IsSoundbankOverrideEnabled(string wwiseProjectPath)
{
var userConfigFile = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(wwiseProjectPath),
System.IO.Path.GetFileNameWithoutExtension(wwiseProjectPath) + "." + System.Environment.UserName + ".wsettings");
if (!System.IO.File.Exists(userConfigFile))
return false;
var userConfigDoc = new System.Xml.XmlDocument();
userConfigDoc.Load(userConfigFile);
var userConfigNavigator = userConfigDoc.CreateNavigator();
var userConfigNode = userConfigNavigator.SelectSingleNode(
System.Xml.XPath.XPathExpression.Compile("//Property[@Name='SoundBankPathUserOverride' and @Value = 'True']"));
return userConfigNode != null;
}
public static System.Collections.Generic.IDictionary> PlatformMapping
{
get { return s_BaseToCustomPF; }
}
public static System.Collections.Generic.IDictionary GetAllBankPaths(string xmlFilePath)
{
UpdateSoundbanksDestinationFolders(xmlFilePath);
return s_ProjectBankPaths;
}
public static System.Collections.Generic.IDictionary GetAllBankPaths()
{
UpdateSoundbanksDestinationFolders(AkWwiseEditorSettings.WwiseProjectAbsolutePath);
return s_ProjectBankPaths;
}
// Parses the .wproj to find out where SoundBanks are generated for the given path.
public static string GetWwiseSoundBankDestinationFolder(string Platform)
{
try
{
UpdateSoundbanksDestinationFolders(AkWwiseEditorSettings.WwiseProjectAbsolutePath);
return s_ProjectBankPaths[Platform];
}
catch
{
return "";
}
}
public delegate void GetEventDurationsFunc(uint eventID, ref float maximum, ref float minimum);
public static GetEventDurationsFunc GetEventDurations = (uint eventID, ref float maximum, ref float minimum) => { maximum = minimum = -1.0f; };
private static void UpdateSoundbanksDestinationFolders(string WwiseProjectPath)
{
try
{
if (WwiseProjectPath.Length == 0)
return;
if (!System.IO.File.Exists(WwiseProjectPath))
return;
var t = System.IO.File.GetLastWriteTime(WwiseProjectPath);
if (t <= s_LastBankPathUpdate)
return;
s_ProjectBankPaths.Clear();
var doc = new System.Xml.XmlDocument();
doc.Load(WwiseProjectPath);
var Navigator = doc.CreateNavigator();
s_LastBankPathUpdate = t;
// Gather the mapping of Custom platform to Base platform
var itpf = Navigator.Select("//Platform");
s_BaseToCustomPF.Clear();
foreach (System.Xml.XPath.XPathNavigator node in itpf)
{
System.Collections.Generic.List customList = null;
var basePF = node.GetAttribute("ReferencePlatform", "");
if (!s_BaseToCustomPF.TryGetValue(basePF, out customList))
{
customList = new System.Collections.Generic.List();
s_BaseToCustomPF[basePF] = customList;
}
customList.Add(node.GetAttribute("Name", ""));
}
// Navigate the wproj file (XML format) to where generated SoundBank paths are stored
var it = Navigator.Select("//Property[@Name='SoundBankPaths']/ValueList/Value");
foreach (System.Xml.XPath.XPathNavigator node in it)
{
var path = node.Value;
FixSlashes(ref path);
var pf = node.GetAttribute("Platform", "");
s_ProjectBankPaths[pf] = path;
}
}
catch (System.Exception ex)
{
UnityEngine.Debug.LogError("WwiseUnity: Error while reading project " + WwiseProjectPath + ". Exception: " + ex.Message);
}
}
public static void SetSoundbanksDestinationFoldersInWproj(string WwiseProjectPath, string destinationPath)
{
try
{
if (WwiseProjectPath.Length == 0)
return;
if (!System.IO.File.Exists(WwiseProjectPath))
return;
s_ProjectBankPaths.Clear();
var doc = new System.Xml.XmlDocument();
doc.Load(WwiseProjectPath);
var Navigator = doc.CreateNavigator();
// Gather the mapping of Custom platform to Base platform
var itpf = Navigator.Select("//Platform");
s_BaseToCustomPF.Clear();
foreach (System.Xml.XPath.XPathNavigator node in itpf)
{
System.Collections.Generic.List customList = null;
var basePF = node.GetAttribute("ReferencePlatform", "");
if (!s_BaseToCustomPF.TryGetValue(basePF, out customList))
{
customList = new System.Collections.Generic.List();
s_BaseToCustomPF[basePF] = customList;
}
customList.Add(node.GetAttribute("Name", ""));
}
// Navigate the wproj file (XML format) to where generated SoundBank paths are stored
var it = Navigator.Select("//Property[@Name='SoundBankPaths']/ValueList/Value");
foreach (System.Xml.XPath.XPathNavigator node in it)
{
var pf = node.GetAttribute("Platform", "");
var path = $"{destinationPath}/{pf}";
FixSlashes(ref path);
node.SetValue(path);
s_ProjectBankPaths[pf] = path;
}
doc.Save(WwiseProjectPath);
}
catch (System.Exception ex)
{
UnityEngine.Debug.LogError("WwiseUnity: Error while reading project " + WwiseProjectPath + ". Exception: " + ex.Message);
}
}
public static void SoundBankDestinationsUpdated(string WwiseProjectPath)
{
UpdateSoundbanksDestinationFolders(WwiseProjectPath);
}
// Set SoundBank-related bool settings in the wproj file.
public static bool EnableBoolSoundbankSettingInWproj(string SettingName, string WwiseProjectPath)
{
try
{
if (WwiseProjectPath.Length == 0)
return true;
var doc = new System.Xml.XmlDocument { PreserveWhitespace = true };
doc.Load(WwiseProjectPath);
var Navigator = doc.CreateNavigator();
// Navigate the wproj file (XML format) to where our setting should be
var pathInXml = string.Format("/WwiseDocument/ProjectInfo/Project/PropertyList/Property[@Name='{0}']", SettingName);
var expression = System.Xml.XPath.XPathExpression.Compile(pathInXml);
var node = Navigator.SelectSingleNode(expression);
if (node == null)
{
// Setting isn't in the wproj, add it
// Navigate to the SoundBankHeaderFilePath property (it is always there)
expression =
System.Xml.XPath.XPathExpression.Compile(
"/WwiseDocument/ProjectInfo/Project/PropertyList/Property[@Name='SoundBankHeaderFilePath']");
node = Navigator.SelectSingleNode(expression);
if (node == null)
{
// SoundBankHeaderFilePath not in wproj, invalid wproj file
UnityEngine.Debug.LogError(
"WwiseUnity: Could not find SoundBankHeaderFilePath property in Wwise project file. File is invalid.");
return false;
}
// Add the setting right above SoundBankHeaderFilePath
var propertyToInsert = string.Format("", SettingName);
node.InsertBefore(propertyToInsert);
}
else if (node.GetAttribute("Value", "") == "False")
{
// Value is present, we simply have to modify it.
if (!node.MoveToAttribute("Value", ""))
return false;
// Modify the value to true
node.SetValue("True");
}
else
{
// Parameter already set, nothing to do!
return true;
}
doc.Save(WwiseProjectPath);
return true;
}
catch
{
return false;
}
}
public static bool SetSoundbankHeaderFilePath(string WwiseProjectPath, string SoundbankPath)
{
try
{
if (WwiseProjectPath.Length == 0)
return true;
var doc = new System.Xml.XmlDocument { PreserveWhitespace = true };
doc.Load(WwiseProjectPath);
var Navigator = doc.CreateNavigator();
// Navigate to where the header file path is saved. The node has to be there, or else the wproj is invalid.
var expression =
System.Xml.XPath.XPathExpression.Compile(
"/WwiseDocument/ProjectInfo/Project/PropertyList/Property[@Name='SoundBankHeaderFilePath']");
var node = Navigator.SelectSingleNode(expression);
if (node == null)
{
UnityEngine.Debug.LogError(
"Could not find SoundBankHeaderFilePath property in Wwise project file. File is invalid.");
return false;
}
// Change the "Value" attribute
if (!node.MoveToAttribute("Value", ""))
return false;
node.SetValue(SoundbankPath);
doc.Save(WwiseProjectPath);
return true;
}
catch
{
return false;
}
}
// Make two paths relative to each other
public static string MakeRelativePath(string fromPath, string toPath)
{
// MONO BUG: https://github.com/mono/mono/pull/471
// In the editor, Application.dataPath returns /Assets. There is a bug in
// mono for method Uri.GetRelativeUri where if the path ends in a folder, it will
// ignore the last part of the path. Thus, we need to add fake depth to get the "real"
// relative path.
fromPath += "/fake_depth";
try
{
if (string.IsNullOrEmpty(fromPath))
return toPath;
if (string.IsNullOrEmpty(toPath))
return "";
var fromUri = new System.Uri(fromPath);
var toUri = new System.Uri(toPath);
if (fromUri.Scheme != toUri.Scheme)
return toPath;
var relativeUri = fromUri.MakeRelativeUri(toUri);
var relativePath = System.Uri.UnescapeDataString(relativeUri.ToString());
return relativePath;
}
catch
{
return toPath;
}
}
// Reconcile a base path and a relative path to give a full path without any ".."
public static string GetFullPath(string BasePath, string RelativePath)
{
if (string.IsNullOrEmpty(BasePath))
return "";
var wrongSeparatorChar = System.IO.Path.DirectorySeparatorChar == '/' ? '\\' : '/';
if (string.IsNullOrEmpty(RelativePath))
return BasePath.Replace(wrongSeparatorChar, System.IO.Path.DirectorySeparatorChar);
if (System.IO.Path.GetPathRoot(RelativePath) != "")
return RelativePath.Replace(wrongSeparatorChar, System.IO.Path.DirectorySeparatorChar);
return System.IO.Path.GetFullPath(System.IO.Path.Combine(BasePath, RelativePath));
}
public static bool DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
{
var dir = new System.IO.DirectoryInfo(sourceDirName);
if (!dir.Exists)
{
UnityEngine.Debug.LogError("WwiseUnity: Source directory doesn't exist");
return false;
}
if (!System.IO.Directory.Exists(destDirName))
System.IO.Directory.CreateDirectory(destDirName);
var files = dir.GetFiles();
foreach (var file in files)
{
var destFilePath = System.IO.Path.Combine(destDirName, file.Name);
if (System.IO.File.Exists(destFilePath))
UnityEngine.Debug.LogWarningFormat("WwiseUnity: Destination file path will be overwritten: {0}", destFilePath);
file.CopyTo(destFilePath, true);
}
if (!copySubDirs)
return true;
var dirs = dir.GetDirectories();
foreach (var subdir in dirs)
{
var destSubDirName = System.IO.Path.Combine(destDirName, subdir.Name);
DirectoryCopy(subdir.FullName, destSubDirName, copySubDirs);
}
return true;
}
public static bool MoveAssetsFromDirectory(string sourceDirName, string destDirName, bool copySubDirs)
{
var dir = new System.IO.DirectoryInfo(sourceDirName);
if (!dir.Exists)
{
UnityEngine.Debug.LogError("WwiseUnity: Source directory doesn't exist");
return false;
}
if (!System.IO.Directory.Exists(destDirName))
AssetDatabase.CreateFolder(System.IO.Path.GetDirectoryName(destDirName), System.IO.Path.GetFileName(destDirName));
var files = dir.GetFiles();
string error, source, destFilePath;
foreach (var file in files)
{
if (file.Extension == ".meta") continue;
destFilePath = System.IO.Path.Combine(destDirName, file.Name);
if (System.IO.File.Exists(destFilePath))
UnityEngine.Debug.LogWarningFormat("WwiseUnity: Destination file path will be overwritten: {0}", destFilePath);
source = System.IO.Path.Combine("Assets", AkUtilities.MakeRelativePath(UnityEngine.Application.dataPath, file.FullName));
source = source.Replace(System.IO.Path.AltDirectorySeparatorChar, System.IO.Path.DirectorySeparatorChar);
error = AssetDatabase.MoveAsset(source, destFilePath);
if (!string.IsNullOrEmpty(error))
UnityEngine.Debug.LogErrorFormat("WwiseUnity: Error while attempting to move <{0}> to <{1}>: {2}", source, destFilePath, error);
}
if (!copySubDirs)
return true;
var dirs = dir.GetDirectories();
foreach (var subdir in dirs)
{
source = System.IO.Path.Combine("Assets", AkUtilities.MakeRelativePath(UnityEngine.Application.dataPath, subdir.FullName));
source = source.Replace(System.IO.Path.AltDirectorySeparatorChar, System.IO.Path.DirectorySeparatorChar);
var destSubDirName = System.IO.Path.Combine(destDirName, subdir.Name);
error = UnityEditor.AssetDatabase.MoveAsset(source, destSubDirName);
if (!string.IsNullOrEmpty(error))
UnityEngine.Debug.LogErrorFormat("WwiseUnity: Error while attempting to move <{0}> to <{1}>: {2}", source, destSubDirName, error);
}
return true;
}
public static bool CreateFolder(string folderToCreate)
{
var created = false;
var folder = string.Empty;
var folders = folderToCreate.Split(System.IO.Path.AltDirectorySeparatorChar, System.IO.Path.DirectorySeparatorChar);
for (int i = 0; i < folders.Length; ++i)
{
var parentFolder = folder;
folder = string.IsNullOrEmpty(parentFolder) ? folders[i] : System.IO.Path.Combine(parentFolder, folders[i]);
if (UnityEditor.AssetDatabase.IsValidFolder(folder))
{
continue;
}
var error = UnityEditor.AssetDatabase.CreateFolder(parentFolder, folders[i]);
if (string.IsNullOrEmpty(error))
{
created = true;
continue;
}
return false;
}
if (created)
UnityEditor.AssetDatabase.SaveAssets();
return true;
}
///
/// Renames or moves a folder using UnityEditor.Database API.
///
///
///
/// Returns true if the operation was successful.
public static bool MoveFolder(string oldPath, string newPath)
{
oldPath = oldPath.Replace(System.IO.Path.AltDirectorySeparatorChar, System.IO.Path.DirectorySeparatorChar);
newPath = newPath.Replace(System.IO.Path.AltDirectorySeparatorChar, System.IO.Path.DirectorySeparatorChar);
if (oldPath.Equals(newPath, System.StringComparison.OrdinalIgnoreCase))
return false;
var error = string.Empty;
var newParentFolder = System.IO.Path.GetDirectoryName(newPath);
if (System.IO.Path.GetDirectoryName(oldPath) == newParentFolder)
{
error = UnityEditor.AssetDatabase.RenameAsset(oldPath, newPath.Substring(newParentFolder.Length + 1));
if (string.IsNullOrEmpty(error))
return true;
UnityEngine.Debug.LogErrorFormat("WwiseUnity: Error while attempting to rename folder <{0}> to <{1}>: {2}", oldPath, newPath, error);
return false;
}
if (!CreateFolder(newParentFolder))
return false;
error = UnityEditor.AssetDatabase.MoveAsset(oldPath, newPath);
if (string.IsNullOrEmpty(error))
return true;
UnityEngine.Debug.LogWarningFormat("WwiseUnity: Error while attempting to move folder <{0}> to <{1}>: {2}", oldPath, newPath, error);
return false;
}
///This function returns the absolute position and the width and height of the last drawn GuiLayout(or EditorGuiLayout) element in the inspector window.
///This function must be called in the OnInspectorGUI function
///
///The inspector must be in repaint mode in order to get the correct position
///Example => if(Event.current.type == EventType.Repaint) Rect pos = AkUtilities.GetLastRectAbsolute();
public static UnityEngine.Rect GetLastRectAbsolute(UnityEngine.Rect relativePos)
{
var lastRectAbsolute = relativePos;
try
{
lastRectAbsolute.x += UnityEditor.EditorWindow.focusedWindow.position.x;
lastRectAbsolute.y += UnityEditor.EditorWindow.focusedWindow.position.y;
var inspectorType = UnityEditor.EditorWindow.focusedWindow.GetType();
var currentInspectorFieldInfo = inspectorType.GetField("s_CurrentInspectorWindow",
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
var scrollPosInfo = inspectorType.GetField("m_ScrollPosition",
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var scrollPos = (UnityEngine.Vector2)scrollPosInfo.GetValue(currentInspectorFieldInfo.GetValue(null));
lastRectAbsolute.x -= scrollPos.x;
lastRectAbsolute.y -= scrollPos.y;
}
catch
{
}
return lastRectAbsolute;
}
public static void RepaintInspector()
{
var windows = UnityEngine.Resources.FindObjectsOfTypeAll();
foreach (var win in windows)
if (win.titleContent.text == "Inspector")
win.Repaint();
}
public static string ParseOsxPathFromWinePath(string path)
{
string ret = path.Replace("Y:", System.Environment.GetEnvironmentVariable("HOME"));
ret = ret.Replace("Z:", "");
ret = ret.Replace('\\', '/');
return ret;
}
#region Tooltip Workaround
private static System.Reflection.FieldInfo GetFieldInfoFromProperty(UnityEditor.SerializedProperty property)
{
var serializedProperty = property.serializedObject.FindProperty("m_Script");
if (serializedProperty == null)
return null;
var monoScript = serializedProperty.objectReferenceValue as UnityEditor.MonoScript;
if (monoScript == null)
return null;
var scriptTypeFromProperty = monoScript.GetClass();
if (scriptTypeFromProperty == null)
return null;
return GetFieldInfoFromPropertyPath(scriptTypeFromProperty, property.propertyPath);
}
private static System.Reflection.FieldInfo GetFieldInfoFromPropertyPath(System.Type host, string path)
{
System.Reflection.FieldInfo fieldInfo = null;
var type = host;
var array = path.Split('.');
for (int i = 0; i < array.Length; ++i)
{
string text = array[i];
if (i < array.Length - 1 && text == "Array" && array[i + 1].StartsWith("data["))
{
if (type.IsArray)
type = type.GetElementType();
else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.List<>))
type = type.GetGenericArguments()[0];
i++;
}
else
{
var type2 = type;
while (type2 != null)
{
fieldInfo = type2.GetField(text, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
if (fieldInfo != null)
{
type = fieldInfo.FieldType;
break;
}
type2 = type2.BaseType;
if (type2 == null)
return null;
}
}
}
return fieldInfo;
}
private static string GetTooltip(System.Reflection.FieldInfo field, bool inherit)
{
var attributes = field.GetCustomAttributes(typeof(UnityEngine.TooltipAttribute), inherit) as UnityEngine.TooltipAttribute[];
if (attributes != null && attributes.Length > 0)
return attributes[0].tooltip;
return string.Empty;
}
public static string GetTooltip(UnityEditor.SerializedProperty property)
{
return GetTooltip(GetFieldInfoFromProperty(property), true);
}
#endregion
}
#endif // UNITY_EDITOR
public partial class AkUtilities
{
public static void FixSlashes(ref string path, char separatorChar, char badChar, bool addTrailingSlash)
{
if (string.IsNullOrEmpty(path))
return;
path = path.Trim().Replace(badChar, separatorChar).TrimStart('\\');
// Append a trailing slash to play nicely with Wwise
if (addTrailingSlash && !path.EndsWith(separatorChar.ToString()))
path += separatorChar;
}
public static void FixSlashes(ref string path)
{
#if UNITY_WSA
var separatorChar = '\\';
#else
var separatorChar = System.IO.Path.DirectorySeparatorChar;
#endif // UNITY_WSA
var badChar = separatorChar == '\\' ? '/' : '\\';
FixSlashes(ref path, separatorChar, badChar, true);
}
// public static string GetPathInPackage(string relativePath)
// {
// const string AssetWwisePathParent = "Assets/Wwise/API/";
// const string PackageWwisePathParent = "Packages/com.audiokinetic.wwise.api/";
//
// string rootpath = "";
// if (System.IO.Directory.Exists(System.IO.Path.GetFullPath(PackageWwisePathParent)))
// {
// rootpath = PackageWwisePathParent;
// }
// else if (System.IO.Directory.Exists(System.IO.Path.GetFullPath(AssetWwisePathParent)))
// {
//
// rootpath = AssetWwisePathParent;
// }
// else
// {
// return string.Empty;
// }
//
// var relativePathFolders = new System.Collections.Generic.List(relativePath.Split('/'));
// var rootPathFolders = new System.Collections.Generic.List(rootpath.Split('/'));
// var overlap = relativePathFolders.Intersect(rootPathFolders);
// if (overlap.Count() > 0)
// {
// UnityEngine.Debug.LogWarning("AkUtilities.GetPathInPackage(): relativePath contains overlapping folder names with root path.\nrelativePath: "
// + relativePath
// + "\nroot path: "
// + rootpath
// + "\n This could cause issues with plugins activation and packaging.");
// }
//
// return System.IO.Path.Combine(rootpath, relativePath);
// }
///
/// This is based on FNVHash as used by the DataManager
/// to assign short IDs to objects. Be sure to keep them both in sync
/// when making changes!
///
public class ShortIDGenerator
{
private const uint s_prime32 = 16777619;
private const uint s_offsetBasis32 = 2166136261;
private static byte s_hashSize;
private static uint s_mask;
static ShortIDGenerator()
{
HashSize = 32;
}
public static byte HashSize
{
get { return s_hashSize; }
set
{
s_hashSize = value;
s_mask = (uint)((1 << s_hashSize) - 1);
}
}
public static uint Compute(string in_name)
{
var buffer = System.Text.Encoding.UTF8.GetBytes(in_name.ToLower());
// Start with the basis value
var hval = s_offsetBasis32;
for (var i = 0; i < buffer.Length; i++)
{
// multiply by the 32 bit FNV magic prime mod 2^32
hval *= s_prime32;
// xor the bottom with the current octet
hval ^= buffer[i];
}
if (s_hashSize == 32)
return hval;
// XOR-Fold to the required number of bits
return (hval >> s_hashSize) ^ (hval & s_mask);
}
}
}
#endif // #if ! (UNITY_DASHBOARD_WIDGET || UNITY_WEBPLAYER || UNITY_WII || UNITY_WIIU || UNITY_NACL || UNITY_FLASH || UNITY_BLACKBERRY) // Disable under unsupported platforms.