//////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2018 Audiokinetic Inc. / All Rights Reserved
//
//////////////////////////////////////////////////////////////////////
using System.Collections.Generic;
/// @brief Represents Wwise objects as Unity assets.
public abstract class WwiseObjectReference : UnityEngine.ScriptableObject
{
#region Serialized fields
[AkShowOnly]
[UnityEngine.SerializeField]
private string objectName = string.Empty;
[AkShowOnly]
[UnityEngine.SerializeField]
private uint id = AkSoundEngine.AK_INVALID_UNIQUE_ID;
[AkShowOnly]
[UnityEngine.SerializeField]
private string guid = string.Empty;
#endregion
#region Properties
///
/// The Wwise GUID which is represented by the ScriptableObject's asset file name.
///
public System.Guid Guid
{
get { return string.IsNullOrEmpty(guid) ? System.Guid.Empty : new System.Guid(guid); }
}
///
/// The name of the Wwise object.
///
public string ObjectName { get { return objectName; } }
///
/// The display name for the Wwise object.
///
public virtual string DisplayName { get { return ObjectName; } }
///
/// The Wwise ID.
///
public uint Id { get { return id; } }
///
/// The type of the Wwise object resource (for example: Event, State or Switch).
///
public abstract WwiseObjectType WwiseObjectType { get; }
#endregion
#if UNITY_EDITOR
private static Dictionary> s_objectReferenceDictionary = new Dictionary>();
public virtual bool IsComplete()
{
return true;
}
public virtual void CompleteData()
{
}
#region Creation and File Management
private static readonly System.Collections.Generic.Dictionary m_WwiseObjectReferenceClasses
= new System.Collections.Generic.Dictionary
{
{ WwiseObjectType.AcousticTexture, typeof(WwiseAcousticTextureReference) },
{ WwiseObjectType.AuxBus, typeof(WwiseAuxBusReference) },
{ WwiseObjectType.Soundbank, typeof(WwiseBankReference) },
{ WwiseObjectType.Event, typeof(WwiseEventReference) },
{ WwiseObjectType.GameParameter, typeof(WwiseRtpcReference) },
{ WwiseObjectType.StateGroup, typeof(WwiseStateGroupReference) },
{ WwiseObjectType.State, typeof(WwiseStateReference) },
{ WwiseObjectType.SwitchGroup, typeof(WwiseSwitchGroupReference) },
{ WwiseObjectType.Switch, typeof(WwiseSwitchReference) },
{ WwiseObjectType.Trigger, typeof(WwiseTriggerReference) },
};
private static WwiseObjectReference Create(WwiseObjectType wwiseObjectType, System.Guid guid)
{
System.Type type = null;
WwiseObjectReference objectReference = null;
if (m_WwiseObjectReferenceClasses.TryGetValue(wwiseObjectType, out type))
{
objectReference =(WwiseObjectReference)CreateInstance(type);
}
else
{
objectReference = CreateInstance();
}
objectReference.guid = guid.ToString().ToUpper();
if (!s_objectReferenceDictionary.ContainsKey(wwiseObjectType))
{
FetchAssetsOfType(wwiseObjectType);
}
if (s_objectReferenceDictionary[wwiseObjectType].ContainsKey(objectReference.Guid))
{
s_objectReferenceDictionary[wwiseObjectType][objectReference.Guid] = objectReference;
}
else
{
s_objectReferenceDictionary[wwiseObjectType].Add(objectReference.Guid, objectReference);
}
return objectReference;
}
protected static WwiseObjectReference FindExistingWwiseObject(WwiseObjectType wwiseObjectType, System.Guid guid, string path)
{
var asset = UnityEditor.AssetDatabase.LoadAssetAtPath(path);
if (asset)
return asset;
System.Type type = null;
if (!m_WwiseObjectReferenceClasses.TryGetValue(wwiseObjectType, out type))
return null;
if (!s_objectReferenceDictionary.ContainsKey(wwiseObjectType))
{
FetchAssetsOfType(wwiseObjectType);
}
if (s_objectReferenceDictionary[wwiseObjectType].ContainsKey(guid))
{
return s_objectReferenceDictionary[wwiseObjectType][guid];
}
return null;
}
private static void FetchAssetsOfType(WwiseObjectType wwiseObjectType)
{
System.Type type = null;
if (!m_WwiseObjectReferenceClasses.TryGetValue(wwiseObjectType, out type))
type = typeof(WwiseObjectReference);
var objectReferenceDictionary = new Dictionary();
var guids = UnityEditor.AssetDatabase.FindAssets("t:" + type.Name);
foreach (var assetGuid in guids)
{
var assetPath = UnityEditor.AssetDatabase.GUIDToAssetPath(assetGuid);
var asset = UnityEditor.AssetDatabase.LoadAssetAtPath(assetPath);
objectReferenceDictionary[asset.Guid] = asset;
}
s_objectReferenceDictionary[wwiseObjectType] = objectReferenceDictionary;
}
private static bool UpdateWwiseObjectData(WwiseObjectReference wwiseObjectReference, string name)
{
var id = AkUtilities.ShortIDGenerator.Compute(name);
var changed = false;
if (wwiseObjectReference.objectName != name || wwiseObjectReference.id != id)
changed = true;
wwiseObjectReference.objectName = name;
wwiseObjectReference.id = id;
if (!wwiseObjectReference.IsComplete())
{
changed = true;
wwiseObjectReference.CompleteData();
}
return changed;
}
public static string GetParentPath(WwiseObjectType wwiseObjectType)
{
return System.IO.Path.Combine(AkWwiseEditorSettings.WwiseScriptableObjectRelativePath, wwiseObjectType.ToString());
}
public static string GetAssetFileName(System.Guid guid)
{
return guid.ToString().ToUpper() + ".asset";
}
public static WwiseObjectReference FindOrCreateWwiseObject(WwiseObjectType wwiseObjectType, string name, System.Guid guid)
{
var parentPath = GetParentPath(wwiseObjectType);
var path = System.IO.Path.Combine(parentPath, GetAssetFileName(guid));
var asset = FindExistingWwiseObject(wwiseObjectType, guid, path);
var assetExists = asset != null;
if (!assetExists)
{
AkUtilities.CreateFolder(parentPath);
asset = Create(wwiseObjectType, guid);
}
var changed = UpdateWwiseObjectData(asset, name);
if (!assetExists)
UnityEditor.AssetDatabase.CreateAsset(asset, path);
else if (changed)
UnityEditor.EditorUtility.SetDirty(asset);
return asset;
}
public static WwiseObjectReference FindWwiseObject(WwiseObjectType wwiseObjectType, System.Guid guid)
{
var parentPath = GetParentPath(wwiseObjectType);
var path = System.IO.Path.Combine(parentPath, GetAssetFileName(guid));
return FindExistingWwiseObject(wwiseObjectType, guid, path);
}
public static void UpdateWwiseObject(WwiseObjectType wwiseObjectType, string name, System.Guid guid)
{
var path = System.IO.Path.Combine(GetParentPath(wwiseObjectType), GetAssetFileName(guid));
var asset = FindExistingWwiseObject(wwiseObjectType, guid, path);
if (asset && UpdateWwiseObjectData(asset, name))
UnityEditor.EditorUtility.SetDirty(asset);
}
public static void DeleteWwiseObject(WwiseObjectType wwiseObjectType, System.Guid guid)
{
var path = System.IO.Path.Combine(GetParentPath(wwiseObjectType), GetAssetFileName(guid));
var guidString = UnityEditor.AssetDatabase.AssetPathToGUID(path);
if (!string.IsNullOrEmpty(guidString))
UnityEditor.AssetDatabase.DeleteAsset(path);
}
#endregion
#region WwiseMigration
private class WwiseObjectData
{
public string objectName;
}
private static System.Collections.Generic.Dictionary> WwiseObjectDataMap
= new System.Collections.Generic.Dictionary>();
public static void ClearWwiseObjectDataMap()
{
WwiseObjectDataMap.Clear();
}
public static void UpdateWwiseObjectDataMap(WwiseObjectType wwiseObjectType, string name, System.Guid guid)
{
System.Collections.Generic.Dictionary map = null;
if (!WwiseObjectDataMap.TryGetValue(wwiseObjectType, out map))
{
map = new System.Collections.Generic.Dictionary();
WwiseObjectDataMap.Add(wwiseObjectType, map);
}
WwiseObjectData data = null;
if (!map.TryGetValue(guid, out data))
{
data = new WwiseObjectData();
map.Add(guid, data);
}
data.objectName = name;
}
public static WwiseObjectReference GetWwiseObjectForMigration(WwiseObjectType wwiseObjectType, byte[] valueGuid, int id)
{
if (valueGuid == null)
{
return null;
}
System.Collections.Generic.Dictionary map = null;
if (!WwiseObjectDataMap.TryGetValue(wwiseObjectType, out map) || map == null)
{
UnityEngine.Debug.LogWarning("WwiseUnity: Cannot find WwiseObjectReferences of type .");
return null;
}
var guid = System.Guid.Empty;
WwiseObjectData data = null;
try
{
guid = new System.Guid(valueGuid);
}
catch
{
UnityEngine.Debug.LogWarning("WwiseUnity: Invalid guid for WwiseObjectReference of type .");
return null;
}
var formattedId = (uint)id;
if (guid != System.Guid.Empty && !map.TryGetValue(guid, out data))
{
UnityEngine.Debug.LogWarning("WwiseUnity: Cannot find guid <" + guid.ToString() + "> for WwiseObjectReference of type in Wwise Project.");
foreach (var pair in map)
{
if (AkUtilities.ShortIDGenerator.Compute(pair.Value.objectName) == formattedId)
{
guid = pair.Key;
data = pair.Value;
UnityEngine.Debug.LogWarning("WwiseUnity: Found guid <" + guid.ToString() + "> for <" + pair.Value.objectName + ">.");
break;
}
}
}
if (data == null)
{
return null;
}
var objectReference = FindOrCreateWwiseObject(wwiseObjectType, data.objectName, guid);
if (objectReference && objectReference.Id != formattedId)
{
UnityEngine.Debug.LogWarning("WwiseUnity: ID mismatch for WwiseObjectReference of type . Expected <" + formattedId + ">. Found <" + objectReference.Id + ">.");
}
return objectReference;
}
#endregion
#endif
}
/// @brief Represents Wwise group value objects (such as states and switches) as Unity assets.
public abstract class WwiseGroupValueObjectReference : WwiseObjectReference
{
#region Properties
///
/// The group object reference.
///
public abstract WwiseObjectReference GroupObjectReference { get; set; }
///
/// The type of the Wwise object resource (for example: Event, State or Switch).
///
public abstract WwiseObjectType GroupWwiseObjectType { get; }
///
/// The display name for the Wwise object.
///
public override string DisplayName
{
get
{
#if AK_DISPLAY_GROUP_TYPES_WITH_SINGLE_NAME
return ObjectName;
#else
var groupReference = GroupObjectReference;
if (!groupReference)
return ObjectName;
return groupReference.ObjectName + " / " + ObjectName;
#endif // AK_DISPLAY_GROUP_TYPES_WITH_SINGLE_NAME
}
}
#endregion
#if UNITY_EDITOR
public void SetupGroupObjectReference(string name, System.Guid guid)
{
var objectReference = FindOrCreateWwiseObject(GroupWwiseObjectType, name, guid);
if (objectReference != GroupObjectReference)
{
GroupObjectReference = objectReference;
UnityEditor.EditorUtility.SetDirty(this);
}
}
#region WwiseMigration
public static WwiseGroupValueObjectReference GetWwiseObjectForMigration(WwiseObjectType wwiseObjectType, byte[] valueGuid, int id, byte[] groupGuid, int groupId)
{
var objectReference = GetWwiseObjectForMigration(wwiseObjectType, valueGuid, id);
if (!objectReference)
return null;
var groupValueObjectReference = objectReference as WwiseGroupValueObjectReference;
if (!groupValueObjectReference)
{
UnityEngine.Debug.LogWarning("WwiseUnity: Not setting WwiseObjectReference since it is not a WwiseGroupValueObjectReference.");
return null;
}
var groupObjectReference = GetWwiseObjectForMigration(groupValueObjectReference.GroupWwiseObjectType, groupGuid, groupId);
if (!groupObjectReference)
{
UnityEngine.Debug.LogWarning("WwiseUnity: Not setting WwiseObjectReference since its GroupObjectReference cannot be determined.");
return null;
}
groupValueObjectReference.GroupObjectReference = groupObjectReference;
UnityEditor.EditorUtility.SetDirty(groupValueObjectReference);
return groupValueObjectReference;
}
#endregion
#endif
}
#if UNITY_EDITOR
public static class AkWwiseTypes
{
private const string DragAndDropId = "AkDragDropId";
public static WwiseObjectReference DragAndDropObjectReference
{
set { UnityEditor.DragAndDrop.SetGenericData(DragAndDropId, value); }
get { return UnityEditor.DragAndDrop.GetGenericData(DragAndDropId) as WwiseObjectReference; }
}
}
#endif