Feat : Wwise Integration

This commit is contained in:
Alex
2026-03-23 14:28:21 +01:00
parent 627d787695
commit 004bc328ed
1149 changed files with 226567 additions and 19 deletions
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 220936fb4b11b9b4fa434a9a3fbe9181
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9234aa3af650e204abb2c35a5c0d92fa
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,40 @@
{
"name": "AK.Wwise.Unity.MonoBehaviour.Editor",
"references": [
"AK.Wwise.Unity.API",
"AK.Wwise.Unity.API.Editor",
"AK.Wwise.Unity.MonoBehaviour",
"AK.Wwise.Unity.API.WwiseTypes",
"AK.Wwise.Unity.Addressables",
"AK.Wwise.Unity.ProjectDatabase",
"AK.Wwise.Unity.Utilities",
"AK.Wwise.Unity.Logging"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [ "!UNITY_SERVER" ],
"versionDefines": [
{
"name": "com.unity.addressables",
"expression": "1.8",
"define": "UNITY_ADDRESSABLES"
},
{
"name": "com.audiokinetic.wwise.addressables",
"expression": "1.0.0",
"define": "AK_WWISE_ADDRESSABLES"
},
{
"name": "com.audiokinetic.wwise.addressables",
"expression": "2022.1.0",
"define": "WWISE_ADDRESABLES_2022_1_0_OR_NEWER"
}
],
"noEngineReferences": false
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 893d452fd51507e4189660dbd93aede0
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,360 @@
using UnityEngine;
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEditor.CanEditMultipleObjects]
[UnityEditor.CustomEditor(typeof(AkAmbient), true)]
public class AkAmbientInspector : AkEventInspector
{
public enum AttenuationSphereOptions
{
Dont_Show,
Current_Event_Only,
All_Events
}
public static System.Collections.Generic.Dictionary<UnityEngine.Object, AttenuationSphereOptions> attSphereProperties =
new System.Collections.Generic.Dictionary<UnityEngine.Object, AttenuationSphereOptions>();
public AttenuationSphereOptions currentAttSphereOp;
private AkAmbient m_AkAmbient;
private UnityEditor.SerializedProperty multiPositionTypeProperty;
private UnityEditor.SerializedProperty largeModePositionArrayProperty;
private UnityEditor.SerializedProperty sphereColorProperty;
private System.Collections.Generic.List<int> triggerList;
public new void OnEnable()
{
base.OnEnable();
m_AkAmbient = target as AkAmbient;
multiPositionTypeProperty = serializedObject.FindProperty("multiPositionTypeLabel");
largeModePositionArrayProperty = serializedObject.FindProperty("LargeModePositions");
sphereColorProperty = serializedObject.FindProperty("attenuationSphereColor");
if (!attSphereProperties.ContainsKey(target))
attSphereProperties.Add(target, AttenuationSphereOptions.Dont_Show);
currentAttSphereOp = attSphereProperties[target];
WwiseProjectDatabase.SoundBankDirectoryUpdated += PopulateMaxAttenuation;
}
public new void OnDisable()
{
base.OnDisable();
DefaultHandles.Hidden = false;
WwiseProjectDatabase.SoundBankDirectoryUpdated -= PopulateMaxAttenuation;
}
public override void OnChildInspectorGUI()
{
//Save trigger mask to know when it changes
triggerList = m_AkAmbient.triggerList;
base.OnChildInspectorGUI();
if (UnityEngine.Event.current.type == UnityEngine.EventType.ExecuteCommand
&& UnityEngine.Event.current.commandName == "ObjectSelectorClosed")
{
var pickedObject = UnityEditor.EditorGUIUtility.GetObjectPickerObject();
if (pickedObject != null)
{
int insertIndex = largeModePositionArrayProperty.arraySize;
largeModePositionArrayProperty.InsertArrayElementAtIndex(insertIndex);
var newElement = largeModePositionArrayProperty.GetArrayElementAtIndex(insertIndex);
newElement.objectReferenceValue = pickedObject;
return;
}
}
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUILayout.PropertyField(multiPositionTypeProperty, new UnityEngine.GUIContent("Position Type: ", "Simple Mode: Only one position is used.\nLarge Mode: Children of AkAmbient with AkAmbientLargeModePositioner component will be used as position source for multi-positioning.\nMultiple Position Mode: Every AkAmbient using the same event will be used as position source for multi-positioning."));
var multiPositionType = (MultiPositionTypeLabel)multiPositionTypeProperty.intValue;
if (multiPositionType == MultiPositionTypeLabel.Large_Mode || multiPositionType == MultiPositionTypeLabel.MultiPosition_Mode)
{
foreach (AkAmbient ambient in targets)
{
if (!ambient.gameObject.isStatic)
{
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
UnityEditor.EditorGUILayout.HelpBox(string.Format("Position Type <{0}> requires an AkGameObj that does not move. Consider setting the associated GameObject to static.", multiPositionType), UnityEditor.MessageType.Warning);
break;
}
}
}
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
currentAttSphereOp = (AttenuationSphereOptions) UnityEditor.EditorGUILayout.EnumPopup("Show Attenuation Sphere: ", currentAttSphereOp);
attSphereProperties[target] = currentAttSphereOp;
UnityEditor.EditorGUI.BeginChangeCheck();
if (currentAttSphereOp != AttenuationSphereOptions.Dont_Show)
{
UnityEditor.EditorGUILayout.PropertyField(sphereColorProperty, new UnityEngine.GUIContent("Attenuation Sphere Color") );
}
if (UnityEditor.EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
}
if (multiPositionType == MultiPositionTypeLabel.Large_Mode)
{
UnityEngine.GUILayout.BeginHorizontal();
if (UnityEngine.GUILayout.Button("Add Large Mode position object"))
{
int insertIndex = largeModePositionArrayProperty.arraySize;
largeModePositionArrayProperty.InsertArrayElementAtIndex(insertIndex);
var newPoint = new UnityEngine.GameObject(string.Format("AkAmbientPoint{0}", insertIndex));
UnityEditor.Undo.RegisterCreatedObjectUndo(newPoint, "CreateNewLargeModePositionObject");
UnityEditor.Undo.AddComponent<AkAmbientLargeModePositioner>(newPoint);
UnityEditor.Undo.SetTransformParent(newPoint.transform, m_AkAmbient.transform, "CreateNewLargeModePositionObjectSetParent");
newPoint.transform.position = m_AkAmbient.transform.TransformPoint(UnityEngine.Vector3.zero);
newPoint.transform.localScale = new UnityEngine.Vector3(1f, 1f, 1f);
var newElement = largeModePositionArrayProperty.GetArrayElementAtIndex(insertIndex);
newElement.objectReferenceValue = newPoint.GetComponent<AkAmbientLargeModePositioner>();
}
if (UnityEngine.GUILayout.Button("Pick existing position object"))
{
int controlID = UnityEngine.GUIUtility.GetControlID(UnityEngine.FocusType.Passive);
UnityEditor.EditorGUIUtility.ShowObjectPicker<AkAmbientLargeModePositioner>(null, true, string.Empty, controlID);
}
UnityEngine.GUILayout.EndHorizontal();
++UnityEditor.EditorGUI.indentLevel;
UnityEditor.EditorGUI.BeginChangeCheck();
for (int i = 0; i < largeModePositionArrayProperty.arraySize; ++i)
{
UnityEditor.EditorGUILayout.PropertyField(largeModePositionArrayProperty.GetArrayElementAtIndex(i), true);
}
if (UnityEditor.EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
}
--UnityEditor.EditorGUI.indentLevel;
}
}
//Save multi-position type to know if it has changed
var multiPosType = m_AkAmbient.multiPositionTypeLabel;
if (m_AkAmbient.multiPositionTypeLabel == MultiPositionTypeLabel.MultiPosition_Mode)
{
UpdateTriggers(multiPosType);
}
}
private void UpdateTriggers(MultiPositionTypeLabel in_multiPosType)
{
//if we just switched to MultiPosition_Mode
if (in_multiPosType != m_AkAmbient.multiPositionTypeLabel)
{
//Get all AkAmbients in the scene
#if UNITY_6000_0_OR_NEWER
var akAmbients = FindObjectsByType<AkAmbient>(FindObjectsSortMode.None);
#else
var akAmbients = FindObjectsOfType<AkAmbient>();
#endif
//Find the first AkAmbient that is in multiPosition_Mode and that has the same event as the current AkAmbient
for (var i = 0; i < akAmbients.Length; i++)
{
if (akAmbients[i] != m_AkAmbient &&
akAmbients[i].multiPositionTypeLabel == MultiPositionTypeLabel.MultiPosition_Mode &&
akAmbients[i].data.Id == m_AkAmbient.data.Id)
{
//if the current AkAmbient doesn't have the same trigger as the others, we ask the user which one he wants to keep
if (!HasSameTriggers(akAmbients[i].triggerList))
{
if (UnityEditor.EditorUtility.DisplayDialog("AkAmbient Trigger Mismatch",
"All ambients in multi-position mode with the same event must have the same triggers.\n" +
"Which triggers would you like to keep?", "Current AkAmbient Triggers", "Other AkAmbients Triggers"))
SetMultiPosTrigger(akAmbients);
else
m_AkAmbient.triggerList = akAmbients[i].triggerList;
}
break;
}
}
}
//if the trigger changed or there was an undo/redo operation, we update the triggers of all the AkAmbients in the same group as the current one
else if (!HasSameTriggers(triggerList) || UnityEngine.Event.current.type == UnityEngine.EventType.ValidateCommand &&
UnityEngine.Event.current.commandName == "UndoRedoPerformed")
{
#if UNITY_6000_0_OR_NEWER
var akAmbients = FindObjectsByType<AkAmbient>(FindObjectsSortMode.None);
#else
var akAmbients = FindObjectsOfType<AkAmbient>();
#endif
SetMultiPosTrigger(akAmbients);
}
}
private bool HasSameTriggers(System.Collections.Generic.List<int> other)
{
return other.Count == m_AkAmbient.triggerList.Count &&
System.Linq.Enumerable.Count(System.Linq.Enumerable.Except(m_AkAmbient.triggerList, other)) == 0;
}
private void SetMultiPosTrigger(AkAmbient[] akAmbients)
{
for (var i = 0; i < akAmbients.Length; i++)
{
if (akAmbients[i].multiPositionTypeLabel == MultiPositionTypeLabel.MultiPosition_Mode &&
akAmbients[i].data.Id == m_AkAmbient.data.Id)
akAmbients[i].triggerList = m_AkAmbient.triggerList;
}
}
private void OnSceneGUI()
{
RenderAttenuationSpheres();
}
public void RenderAttenuationSpheres()
{
if (currentAttSphereOp == AttenuationSphereOptions.Dont_Show)
return;
if (currentAttSphereOp == AttenuationSphereOptions.Current_Event_Only)
{
// Get the max attenuation for the event (if available)
var radius = AkWwiseProjectInfo.GetData().GetEventMaxAttenuation(m_AkAmbient.data.Id) * m_AkAmbient.gameObject.GetComponent<AkGameObj>().ScalingFactor;
if (m_AkAmbient.multiPositionTypeLabel == MultiPositionTypeLabel.Simple_Mode)
{
DrawSphere(m_AkAmbient.gameObject.transform.position, radius, sphereColorProperty.colorValue);
}
else if (m_AkAmbient.multiPositionTypeLabel == MultiPositionTypeLabel.Large_Mode)
{
var positionComponents = m_AkAmbient.GetComponentsInChildren<AkAmbientLargeModePositioner>();
for (int i = 0; i < positionComponents.Length; i++)
{
DrawSphere(positionComponents[i].transform.position, radius, sphereColorProperty.colorValue);
}
}
else
{
#if UNITY_6000_0_OR_NEWER
var akAmbients = FindObjectsByType<AkAmbient>(FindObjectsSortMode.None);
#else
var akAmbients = FindObjectsOfType<AkAmbient>();
#endif
for (var i = 0; i < akAmbients.Length; i++)
{
if (akAmbients[i].multiPositionTypeLabel == MultiPositionTypeLabel.MultiPosition_Mode &&
akAmbients[i].data.Id == m_AkAmbient.data.Id)
{
DrawSphere(akAmbients[i].gameObject.transform.position, radius, akAmbients[i].attenuationSphereColor);
}
}
}
}
else
{
#if UNITY_6000_0_OR_NEWER
var akAmbients = FindObjectsByType<AkAmbient>(FindObjectsSortMode.None);
#else
var akAmbients = FindObjectsOfType<AkAmbient>();
#endif
for (var i = 0; i < akAmbients.Length; i++)
{
// Get the max attenuation for the event (if available)
var radius = AkWwiseProjectInfo.GetData().GetEventMaxAttenuation(akAmbients[i].data.Id);
if (akAmbients[i].multiPositionTypeLabel == MultiPositionTypeLabel.Large_Mode)
{
var positionComponents = m_AkAmbient.GetComponentsInChildren<AkAmbientLargeModePositioner>();
for (int j = 0; j < positionComponents.Length; j++)
{
DrawSphere(positionComponents[j].transform.position, radius, akAmbients[i].attenuationSphereColor);
}
}
else
{
DrawSphere(akAmbients[i].gameObject.transform.position, radius, akAmbients[i].attenuationSphereColor);
}
}
}
}
private void DrawSphere(UnityEngine.Vector3 in_position, float in_radius, UnityEngine.Color in_sphereColor)
{
UnityEngine.Color wireColor = in_sphereColor;
wireColor.a = 0.9f;
if ((UnityEditor.SceneView.lastActiveSceneView.camera.transform.position - in_position).sqrMagnitude > in_radius * in_radius)
{
UnityEditor.Handles.color = wireColor;
DrawWireDiscs(UnityEngine.Vector3.left, UnityEngine.Vector3.right, 2, in_position, in_radius);
UnityEditor.Handles.color = in_sphereColor;
UnityEditor.Handles.SphereHandleCap(0, in_position, UnityEngine.Quaternion.identity, in_radius * 2.0f, UnityEngine.EventType.Repaint);
}
else
{
UnityEditor.Handles.color = wireColor;
DrawWireDiscs(UnityEngine.Vector3.left, UnityEngine.Vector3.right, 6, in_position, in_radius);
UnityEditor.Handles.color = in_sphereColor;
UnityEditor.Handles.DrawSolidDisc(in_position, UnityEngine.Vector3.up, in_radius);
}
}
private void DrawWireDiscs(UnityEngine.Vector3 in_startNormal, UnityEngine.Vector3 in_endNormal, uint in_nbDiscs,
UnityEngine.Vector3 in_position, float in_radius)
{
var f = 1.0f / in_nbDiscs;
for (var i = 0; i < in_nbDiscs; i++)
{
UnityEditor.Handles.DrawWireDisc(in_position, UnityEngine.Vector3.Slerp(in_startNormal, in_endNormal, f * i), in_radius);
}
var orthogonalVector = UnityEngine.Vector3.Cross(in_startNormal, in_endNormal);
//Handle edge case where vectors are parallel
if (orthogonalVector.magnitude == 0.0f)
{
orthogonalVector = UnityEngine.Vector3.Cross(UnityEngine.Vector3.Slerp(in_startNormal, in_endNormal, 0.5f), in_startNormal);
}
UnityEditor.Handles.DrawWireDisc(in_position, orthogonalVector, in_radius);
}
public static void PopulateMaxAttenuation()
{
UnityEditor.SceneView.RepaintAll();
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 6800f9db7948df84a8915cb75d9a9418
@@ -0,0 +1,68 @@
using UnityEditor;
using UnityEngine;
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEditor.CanEditMultipleObjects]
[UnityEditor.CustomEditor(typeof(AkAudioListener), true)]
public class AkAudioListenerInspector : UnityEditor.Editor
{
private UnityEditor.SerializedProperty m_isDefaultListener;
private AkAudioListener m_Listener;
private void OnEnable()
{
m_isDefaultListener = serializedObject.FindProperty("isDefaultListener");
m_Listener = target as AkAudioListener;
}
public override void OnInspectorGUI()
{
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUI.BeginChangeCheck();
UnityEditor.EditorGUILayout.PropertyField(m_isDefaultListener);
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
m_Listener.bOverrideScalingFactor = UnityEditor.EditorGUILayout.Toggle("Override Attenuation Scaling Factor:", m_Listener.bOverrideScalingFactor);
if (m_Listener.bOverrideScalingFactor)
{
m_Listener.ScalingFactor = UnityEditor.EditorGUILayout.FloatField("Attenuation Scaling Factor", m_Listener.ScalingFactor);
}
}
if (UnityEditor.EditorGUI.EndChangeCheck())
{
if (m_Listener.ScalingFactor <= 0)
{
m_Listener.ScalingFactor = 0;
}
else
{
AkAudioListener selectedTarget = (AkAudioListener)target;
if (selectedTarget.gameObject && selectedTarget.gameObject.activeInHierarchy)
{
AkUnitySoundEngine.SetScalingFactor(m_Listener.gameObject, m_Listener.ScalingFactor);
}
}
UnityEditor.EditorUtility.SetDirty(serializedObject.targetObject);
}
}
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 8ce9156dd335763459df339712bdaeab
@@ -0,0 +1,96 @@
using AK.Wwise.Unity.Logging;
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEditor.CanEditMultipleObjects]
[UnityEditor.CustomEditor(typeof(AkBank), true)]
public class AkBankInspector : AkBaseInspector
{
private readonly AkUnityEventHandlerInspector m_LoadBankEventHandlerInspector = new AkUnityEventHandlerInspector();
private readonly AkUnityEventHandlerInspector m_UnloadBankEventHandlerInspector = new AkUnityEventHandlerInspector();
private UnityEditor.SerializedProperty loadAsync;
private UnityEditor.SerializedProperty decode;
private UnityEditor.SerializedProperty saveDecoded;
private UnityEditor.SerializedProperty overrideLoadAsync;
private void OnEnable()
{
m_LoadBankEventHandlerInspector.Init(serializedObject, "triggerList", "Load On: ", false);
m_UnloadBankEventHandlerInspector.Init(serializedObject, "unloadTriggerList", "Unload On: ", false);
decode = serializedObject.FindProperty("decodeBank");
saveDecoded = serializedObject.FindProperty("saveDecodedBank");
loadAsync = serializedObject.FindProperty("loadAsynchronous");
overrideLoadAsync = serializedObject.FindProperty("overrideLoadSetting");
}
public override void OnChildInspectorGUI()
{
m_LoadBankEventHandlerInspector.OnGUI();
m_UnloadBankEventHandlerInspector.OnGUI();
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUILayout.PropertyField(overrideLoadAsync, new UnityEngine.GUIContent("Override Load Setting:"));
if (overrideLoadAsync.boolValue)
{
UnityEditor.EditorGUILayout.PropertyField(loadAsync, new UnityEngine.GUIContent("Load Bank Asynchronously:"));
}
}
#if !(AK_WWISE_ADDRESSABLES && UNITY_ADDRESSABLES)
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEngine.GUIStyle wrapLabelStyle = new UnityEngine.GUIStyle(UnityEditor.EditorStyles.label)
{
wordWrap = true
};
UnityEngine.GUILayout.Label("Decode compressed data (DEPRECATED):", wrapLabelStyle);
decode.boolValue = UnityEditor.EditorGUILayout.ToggleLeft(UnityEngine.GUIContent.none, decode.boolValue);
if (!decode.boolValue)
{
return;
}
var oldSaveDecodedValue = saveDecoded.boolValue;
UnityEditor.EditorGUILayout.PropertyField(saveDecoded, new UnityEngine.GUIContent("Save decoded bank:"));
if (!oldSaveDecodedValue || saveDecoded.boolValue)
{
return;
}
var bank = target as AkBank;
var decodedBankPath = System.IO.Path.Combine(AkBasePathGetter.Get().DecodedBankFullPath, bank.data.Name + ".bnk");
try
{
System.IO.File.Delete(decodedBankPath);
}
catch (System.Exception e)
{
WwiseLogger.Log("Could not delete existing decoded SoundBank. Please delete it manually. " + e);
}
}
#endif
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 4f14ded5987a6254699b017455eaee21
@@ -0,0 +1,42 @@
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
public abstract class AkBaseInspector : UnityEditor.Editor
{
public abstract void OnChildInspectorGUI();
public override void OnInspectorGUI()
{
serializedObject.Update();
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
OnChildInspectorGUI();
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
using (new UnityEngine.GUILayout.HorizontalScope("box"))
UnityEditor.EditorGUILayout.PropertyField(serializedObject.FindProperty("data"), new UnityEngine.GUIContent("Name: "));
if (serializedObject.ApplyModifiedProperties() && UnityEngine.GUI.changed)
{
UnityEditor.EditorUtility.SetDirty(serializedObject.targetObject);
}
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: eeb1eaae19f0b9541b4e02bf49015c94
@@ -0,0 +1,83 @@
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEditor.CanEditMultipleObjects]
[UnityEditor.CustomEditor(typeof(AkEnvironment), true)]
public class AkEnvironmentInspector : AkBaseInspector
{
private AkEnvironment m_AkEnvironment;
private UnityEditor.SerializedProperty m_excludeOthers;
private UnityEditor.SerializedProperty m_isDefault;
private UnityEditor.SerializedProperty m_priority;
private void OnEnable()
{
m_AkEnvironment = target as AkEnvironment;
m_priority = serializedObject.FindProperty("priority");
m_isDefault = serializedObject.FindProperty("isDefault");
m_excludeOthers = serializedObject.FindProperty("excludeOthers");
//We move and replace the game object to trigger the OnTriggerStay function
ShakeEnvironment();
}
public override void OnChildInspectorGUI()
{
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
m_priority.intValue = UnityEditor.EditorGUILayout.IntField("Priority: ", m_priority.intValue);
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
m_isDefault.boolValue = UnityEditor.EditorGUILayout.Toggle("Default: ", m_isDefault.boolValue);
if (m_isDefault.boolValue)
m_excludeOthers.boolValue = false;
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
m_excludeOthers.boolValue = UnityEditor.EditorGUILayout.Toggle("Exclude Others: ", m_excludeOthers.boolValue);
if (m_excludeOthers.boolValue)
m_isDefault.boolValue = false;
}
AkGameObjectInspector.RigidbodyCheck(m_AkEnvironment.gameObject);
}
public void ShakeEnvironment()
{
var temp = m_AkEnvironment.transform.position;
temp.x *= 1.0000001f;
m_AkEnvironment.transform.position = temp;
UnityEditor.EditorApplication.update += ReplaceEnvironment;
}
private void ReplaceEnvironment()
{
UnityEditor.EditorApplication.update -= ReplaceEnvironment;
if (m_AkEnvironment && m_AkEnvironment.transform)
{
var temp = m_AkEnvironment.transform.position;
temp.x /= 1.0000001f;
m_AkEnvironment.transform.position = temp;
}
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 96326b16df198a34e84879de643b9930
@@ -0,0 +1,214 @@
using UnityEngine;
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEditor.CustomEditor(typeof(AkEnvironmentPortal), true)]
public class AkEnvironmentPortalInspector : UnityEditor.Editor
{
private readonly int[] m_selectedIndex = new int[AkEnvironmentPortal.MAX_ENVIRONMENTS_PER_PORTAL];
private AkEnvironmentPortal m_envPortal;
private UnityEditor.SerializedProperty m_environments;
private UnityEditor.SerializedProperty m_axis;
private UnityEditor.SerializedProperty m_envList;
[UnityEditor.MenuItem("GameObject/Wwise/Environment Portal", false, 1)]
public static void CreatePortal()
{
var portal = new UnityEngine.GameObject("EnvironmentPortal");
UnityEditor.Undo.AddComponent<AkEnvironmentPortal>(portal);
portal.GetComponent<UnityEngine.Collider>().isTrigger = true;
UnityEditor.Selection.objects = new UnityEngine.Object[] { portal };
}
private void OnEnable()
{
m_envPortal = target as AkEnvironmentPortal;
m_environments = serializedObject.FindProperty("environments");
m_axis = serializedObject.FindProperty("axis");
m_envList = serializedObject.FindProperty("envList");
FindOverlappingEnvironments();
for (var i = 0; i < AkEnvironmentPortal.MAX_ENVIRONMENTS_PER_PORTAL; i++)
{
m_selectedIndex[i] = 0;
var list = m_envList.GetArrayElementAtIndex(i).FindPropertyRelative("list");
for (var j = 0; j < list.arraySize; ++j)
{
if (list.GetArrayElementAtIndex(j).objectReferenceValue == m_environments.GetArrayElementAtIndex(i).objectReferenceValue)
{
m_selectedIndex[i] = j;
break;
}
}
}
}
public override void OnInspectorGUI()
{
serializedObject.Update();
using (new UnityEngine.GUILayout.VerticalScope("box"))
{
for (var i = 0; i < AkEnvironmentPortal.MAX_ENVIRONMENTS_PER_PORTAL; i++)
{
var list = m_envList.GetArrayElementAtIndex(i).FindPropertyRelative("list");
var labels = new string[list.arraySize];
for (var j = 0; j < list.arraySize; j++)
{
var environment = list.GetArrayElementAtIndex(j).objectReferenceValue as AkEnvironment;
if (environment != null)
{
labels[j] = j + 1 + ". " + GetEnvironmentName(environment) + " (" + environment.name + ")";
}
else
{
list.DeleteArrayElementAtIndex(j);
}
}
var index = UnityEditor.EditorGUILayout.Popup("Environment #" + (i + 1), m_selectedIndex[i], labels);
m_environments.GetArrayElementAtIndex(i).objectReferenceValue = index < 0 || index >= list.arraySize ? null : list.GetArrayElementAtIndex(index).objectReferenceValue;
m_selectedIndex[i] = index;
}
}
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
var axisLabels = new[]{ "X", "Y", "Z" };
var axes = new[] { UnityEngine.Vector3.right, UnityEngine.Vector3.up, UnityEngine.Vector3.forward };
var index = 0;
for (var i = 0; i < 3; i++)
{
if (m_axis.vector3Value == axes[i])
{
index = i;
break;
}
}
var newIndex = UnityEditor.EditorGUILayout.Popup("Axis", index, axisLabels);
m_axis.vector3Value = axes[newIndex];
if (index != newIndex)
{
for (var i = 0; i < AkEnvironmentPortal.MAX_ENVIRONMENTS_PER_PORTAL; i++)
m_envList.GetArrayElementAtIndex(i).FindPropertyRelative("list").ClearArray();
FindOverlappingEnvironments();
}
}
serializedObject.ApplyModifiedProperties();
AkGameObjectInspector.RigidbodyCheck(m_envPortal.gameObject);
}
private string GetEnvironmentName(AkEnvironment in_env)
{
foreach (var wwu in AkWwiseProjectInfo.GetData().BusRoot)
{
var found = wwu.Find(in_env.data.Id);
if (found != null)
{
return found.Name;
}
}
return string.Empty;
}
public void FindOverlappingEnvironments()
{
var myCollider = m_envPortal.gameObject.GetComponent<UnityEngine.Collider>();
if (myCollider == null)
return;
#if UNITY_6000_0_OR_NEWER
var environments = FindObjectsByType<AkEnvironment>(FindObjectsSortMode.None);
#else
var environments = FindObjectsOfType<AkEnvironment>();
#endif
foreach (var environment in environments)
{
var otherCollider = environment.gameObject.GetComponent<UnityEngine.Collider>();
if (otherCollider == null)
continue;
if (myCollider.bounds.Intersects(otherCollider.bounds))
{
//if index == 0 => the environment is on the negative side of the portal(opposite to the direction of the chosen axis)
//if index == 1 => the environment is on the positive side of the portal(same direction as the chosen axis)
var index = UnityEngine.Vector3.Dot(m_envPortal.transform.rotation * m_axis.vector3Value,
environment.transform.position - m_envPortal.transform.position) >= 0 ? 1 : 0;
var list = m_envList.GetArrayElementAtIndex(index).FindPropertyRelative("list");
var isFound = false;
var count = list.arraySize;
for (var j = 0; j < count; j++)
{
if (list.GetArrayElementAtIndex(j).objectReferenceValue == environment)
{
isFound = true;
break;
}
}
if (!isFound)
{
list.InsertArrayElementAtIndex(count);
list.GetArrayElementAtIndex(count).objectReferenceValue = environment;
var otherList = m_envList.GetArrayElementAtIndex(++index % AkEnvironmentPortal.MAX_ENVIRONMENTS_PER_PORTAL).FindPropertyRelative("list");
for (var j = 0; j < otherList.arraySize; j++)
{
if (otherList.GetArrayElementAtIndex(j).objectReferenceValue == environment)
{
otherList.DeleteArrayElementAtIndex(j);
break;
}
}
}
}
else
{
for (var i = 0; i < AkEnvironmentPortal.MAX_ENVIRONMENTS_PER_PORTAL; i++)
{
var list = m_envList.GetArrayElementAtIndex(i).FindPropertyRelative("list");
for (var j = 0; j < list.arraySize; j++)
{
if (list.GetArrayElementAtIndex(j).objectReferenceValue == environment)
{
list.DeleteArrayElementAtIndex(j);
break;
}
}
}
}
}
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 89ee80c35ad4f6f4e81f0d83074bc635
@@ -0,0 +1,325 @@
using AK.Wwise.Unity.Logging;
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEditor.CanEditMultipleObjects]
[UnityEditor.CustomEditor(typeof(AkEvent), true)]
public class AkEventInspector : AkBaseInspector
{
private readonly AkUnityEventHandlerInspector m_UnityEventHandlerInspector = new AkUnityEventHandlerInspector();
private UnityEditor.SerializedProperty actionOnEventType;
private UnityEditor.SerializedProperty callbackData;
private UnityEditor.SerializedProperty curveInterpolation;
private UnityEditor.SerializedProperty enableActionOnEvent;
private UnityEditor.SerializedProperty transitionDuration;
private UnityEditor.SerializedProperty useCallbacks;
private UnityEditor.SerializedProperty stopSoundOnDestroy;
public void OnEnable()
{
m_UnityEventHandlerInspector.Init(serializedObject);
enableActionOnEvent = serializedObject.FindProperty("enableActionOnEvent");
actionOnEventType = serializedObject.FindProperty("actionOnEventType");
curveInterpolation = serializedObject.FindProperty("curveInterpolation");
transitionDuration = serializedObject.FindProperty("transitionDuration");
useCallbacks = serializedObject.FindProperty("useCallbacks");
callbackData = serializedObject.FindProperty("Callbacks");
stopSoundOnDestroy = serializedObject.FindProperty("stopSoundOnDestroy");
AkEditorEventPlayer.RefreshGUI += Repaint;
}
public void OnDisable()
{
AkEditorEventPlayer.RefreshGUI -= Repaint;
}
private void DisplayActionOnEvent()
{
if (useCallbacks.boolValue)
return;
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUILayout.PropertyField(enableActionOnEvent, new UnityEngine.GUIContent("Action On Event: "));
if (!enableActionOnEvent.boolValue)
return;
UnityEditor.EditorGUILayout.PropertyField(actionOnEventType, new UnityEngine.GUIContent("Action On EventType: "));
UnityEditor.EditorGUILayout.PropertyField(curveInterpolation, new UnityEngine.GUIContent("Curve Interpolation: "));
UnityEditor.EditorGUILayout.Slider(transitionDuration, 0.0f, 60.0f, new UnityEngine.GUIContent("Fade Time (secs): "));
}
}
private void DisplayCallbackInformation()
{
if (enableActionOnEvent.boolValue)
return;
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUILayout.PropertyField(useCallbacks, new UnityEngine.GUIContent("Use Callback: "));
if (useCallbacks.boolValue)
{
var emptyContent = new UnityEngine.GUIContent("");
// ensure that there is always at least one entry since we are "using" callbacks
if (callbackData.arraySize == 0)
callbackData.arraySize = 1;
const float callbackSpacerWidth = 4;
const float removeButtonWidth = 20;
var rect = UnityEditor.EditorGUILayout.GetControlRect();
var callbackFieldWidth = (rect.width - removeButtonWidth) / 3;
rect.width = callbackFieldWidth - callbackSpacerWidth;
UnityEngine.GUI.Label(rect, "Game Object");
rect.x += callbackFieldWidth;
UnityEngine.GUI.Label(rect, "Callback Function");
rect.x += callbackFieldWidth;
UnityEngine.GUI.Label(rect, "Callback Flags");
for (var i = 0; i < callbackData.arraySize; ++i)
{
var data = callbackData.GetArrayElementAtIndex(i);
rect = UnityEditor.EditorGUILayout.GetControlRect();
rect.width = callbackFieldWidth - callbackSpacerWidth;
UnityEditor.EditorGUI.PropertyField(rect, data.FindPropertyRelative("GameObject"), emptyContent);
rect.x += callbackFieldWidth;
UnityEditor.EditorGUI.PropertyField(rect, data.FindPropertyRelative("FunctionName"), emptyContent);
rect.x += callbackFieldWidth;
UnityEditor.EditorGUI.PropertyField(rect, data.FindPropertyRelative("Flags"), emptyContent);
rect.x += callbackFieldWidth;
rect.width = removeButtonWidth;
if (UnityEngine.GUI.Button(rect, "X"))
callbackData.DeleteArrayElementAtIndex(i);
}
if (UnityEngine.GUI.Button(UnityEditor.EditorGUILayout.GetControlRect(), "Add"))
{
var i = callbackData.arraySize++;
var data = callbackData.GetArrayElementAtIndex(i);
data.FindPropertyRelative("GameObject").objectReferenceValue = null;
data.FindPropertyRelative("FunctionName").stringValue = string.Empty;
data.FindPropertyRelative("Flags.value").intValue = 0;
}
}
else if (callbackData.arraySize == 1)
{
var data = callbackData.GetArrayElementAtIndex(0);
if (data.FindPropertyRelative("GameObject").objectReferenceValue == null)
if (string.IsNullOrEmpty(data.FindPropertyRelative("FunctionName").stringValue))
if (data.FindPropertyRelative("Flags.value").intValue == 0)
callbackData.arraySize = 0;
}
}
}
private void DisplayStopSoundOnDestroy()
{
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUILayout.PropertyField(stopSoundOnDestroy, new UnityEngine.GUIContent("Stop Sound On Destroy: "));
}
}
public override void OnChildInspectorGUI()
{
m_UnityEventHandlerInspector.OnGUI();
DisplayActionOnEvent();
DisplayCallbackInformation();
DisplayStopSoundOnDestroy();
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
if (targets.Length == 1)
{
PlayOrStopEvent();
}
else
{
var playingEventsSelected = false;
var stoppedEventsSelected = false;
for (var i = 0; i < targets.Length; ++i)
{
var akEventTarget = targets[i] as AkEvent;
if (akEventTarget != null)
{
if (AkEditorEventPlayer.IsEventPlaying(akEventTarget))
{
playingEventsSelected = true;
}
else
{
stoppedEventsSelected = true;
}
if (playingEventsSelected && stoppedEventsSelected)
{
break;
}
}
}
if (stoppedEventsSelected &&
UnityEngine.GUILayout.Button("Play Multiple"))
{
for (var i = 0; i < targets.Length; ++i)
{
var akEventTarget = targets[i] as AkEvent;
if (akEventTarget != null)
{
AkEditorEventPlayer.PlayEvent(akEventTarget);
}
}
}
if (playingEventsSelected &&
UnityEngine.GUILayout.Button("Stop Multiple"))
{
for (var i = 0; i < targets.Length; ++i)
{
var akEventTarget = targets[i] as AkEvent;
if (akEventTarget != null)
{
AkEditorEventPlayer.StopEvent(akEventTarget);
}
}
}
}
if (UnityEngine.GUILayout.Button("Stop All"))
{
UnityEngine.GUIUtility.hotControl = 0;
AkEditorEventPlayer.StopAll();
}
}
}
public void PlayEvent()
{
AkEditorEventPlayer.PlayEvent((AkEvent)target);
}
public void StopEvent()
{
AkEditorEventPlayer.StopEvent((AkEvent)target);
}
private void PlayOrStopEvent()
{
var akEvent = (AkEvent)target;
var eventPlaying = AkEditorEventPlayer.IsEventPlaying(akEvent);
if (eventPlaying)
{
if (UnityEngine.GUILayout.Button("Stop"))
{
UnityEngine.GUIUtility.hotControl = 0;
StopEvent();
}
}
else
{
if (UnityEngine.GUILayout.Button("Play"))
{
UnityEngine.GUIUtility.hotControl = 0;
PlayEvent();
}
}
}
private static class AkEditorEventPlayer
{
private static readonly System.Collections.Generic.List<AkEvent> akEvents = new System.Collections.Generic.List<AkEvent>();
public static event System.Action RefreshGUI;
private static void CallbackHandler(object in_cookie, AkCallbackType in_type, AkCallbackInfo in_info)
{
if (in_type == AkCallbackType.AK_EndOfEvent)
{
akEvents.Remove(in_cookie as AkEvent);
var refreshGUI = RefreshGUI;
if (refreshGUI != null)
{
refreshGUI.Invoke();
}
}
}
public static void PlayEvent(AkEvent akEvent)
{
if (!AkUnitySoundEngine.IsInitialized())
{
WwiseLogger.Warning("Sound Engine is not initialized. No sound will be heard.");
return;
}
if (!AkSoundEngineController.Instance.EditorListenerIsInitialized() && !UnityEditor.EditorApplication.isPlaying)
{
WwiseLogger.Warning("Editor Listener isn't initialized. No sound will be heard.");
return;
}
if (akEvents.Contains(akEvent))
{
return;
}
var playingID = akEvent.data.Post(akEvent.gameObject, (uint)AkCallbackType.AK_EndOfEvent, CallbackHandler, akEvent);
if (playingID != AkUnitySoundEngine.AK_INVALID_PLAYING_ID)
{
akEvents.Add(akEvent);
// In the case where objects are being placed in edit mode and then previewed, their positions won't yet be updated so we ensure they're updated here.
AkUnitySoundEngine.SetObjectPosition(akEvent.gameObject, akEvent.transform);
}
}
public static void StopEvent(AkEvent akEvent)
{
if (akEvents.Remove(akEvent))
{
akEvent.data.Stop(akEvent.gameObject);
}
}
public static bool IsEventPlaying(AkEvent akEvent)
{
return akEvents.Contains(akEvent);
}
public static void StopAll()
{
akEvents.Clear();
AkUnitySoundEngine.StopAll();
}
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0de2d1c16ee6d6841b0facd6d151b37c
@@ -0,0 +1,109 @@
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEditor.CustomPropertyDrawer(typeof(AkGameObjListenerList))]
internal class AkGameObjListenerListDrawer : UnityEditor.PropertyDrawer
{
private const int listenerSpacerWidth = 4;
private const int removeButtonWidth = 20;
public override float GetPropertyHeight(UnityEditor.SerializedProperty property, UnityEngine.GUIContent label)
{
var height = (UnityEditor.EditorGUIUtility.singleLineHeight + UnityEditor.EditorGUIUtility.standardVerticalSpacing) *
2;
var listenerListProperty = property.FindPropertyRelative("initialListenerList");
if (listenerListProperty != null && listenerListProperty.isArray)
{
height += (UnityEditor.EditorGUIUtility.singleLineHeight + UnityEditor.EditorGUIUtility.standardVerticalSpacing) *
listenerListProperty.arraySize + UnityEditor.EditorGUIUtility.standardVerticalSpacing;
}
return height;
}
public override void OnGUI(UnityEngine.Rect position, UnityEditor.SerializedProperty property,
UnityEngine.GUIContent label)
{
// Using BeginProperty / EndProperty on the parent property means that
// prefab override logic works on the entire property.
UnityEditor.EditorGUI.BeginProperty(position, label, property);
var initialRect = position;
position = UnityEditor.EditorGUI.PrefixLabel(position,
UnityEngine.GUIUtility.GetControlID(UnityEngine.FocusType.Passive),
new UnityEngine.GUIContent("Use Default Listeners:"));
position.height = UnityEditor.EditorGUIUtility.singleLineHeight +
UnityEditor.EditorGUIUtility.standardVerticalSpacing;
var useDefaultListenersProperty = property.FindPropertyRelative("useDefaultListeners");
useDefaultListenersProperty.boolValue = UnityEngine.GUI.Toggle(position, useDefaultListenersProperty.boolValue, "");
var listenerListProperty = property.FindPropertyRelative("initialListenerList");
if (listenerListProperty.isArray)
{
position.height = UnityEditor.EditorGUIUtility.singleLineHeight +
UnityEditor.EditorGUIUtility.standardVerticalSpacing;
for (var ii = 0; ii < listenerListProperty.arraySize; ++ii)
{
var listenerFieldWidth = initialRect.width - removeButtonWidth;
position.y += UnityEditor.EditorGUIUtility.singleLineHeight + UnityEditor.EditorGUIUtility.standardVerticalSpacing;
position.x = initialRect.x;
position.width = listenerFieldWidth - listenerSpacerWidth;
var listenerProperty = listenerListProperty.GetArrayElementAtIndex(ii);
UnityEditor.EditorGUI.PropertyField(position, listenerProperty, new UnityEngine.GUIContent("Listener " + ii));
position.x = initialRect.x + listenerFieldWidth;
position.width = removeButtonWidth;
if (UnityEngine.GUI.Button(position, "X"))
{
UnityEngine.GUIUtility.keyboardControl = 0;
UnityEngine.GUIUtility.hotControl = 0;
listenerProperty.objectReferenceValue = null;
listenerListProperty.DeleteArrayElementAtIndex(ii);
--ii;
}
}
position.x = initialRect.x;
position.width = initialRect.width;
position.y += UnityEditor.EditorGUIUtility.singleLineHeight + UnityEditor.EditorGUIUtility.standardVerticalSpacing +
UnityEditor.EditorGUIUtility.standardVerticalSpacing;
if (UnityEngine.GUI.Button(position, "Add Listener"))
{
UnityEngine.GUIUtility.keyboardControl = 0;
UnityEngine.GUIUtility.hotControl = 0;
var lastPosition = listenerListProperty.arraySize;
listenerListProperty.arraySize = lastPosition + 1;
// Avoid copying the previous last array element into the newly added last position
var listenerProperty = listenerListProperty.GetArrayElementAtIndex(lastPosition);
listenerProperty.objectReferenceValue = null;
}
}
UnityEditor.EditorGUI.EndProperty();
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0fbc29ab97cf9cb489c967a85b51d577
@@ -0,0 +1,220 @@
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
public class DefaultHandles
{
public static bool Hidden
{
get
{
var type = typeof(UnityEditor.Tools);
var field = type.GetField("s_Hidden",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
return (bool) field.GetValue(null);
}
set
{
var type = typeof(UnityEditor.Tools);
var field = type.GetField("s_Hidden",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
field.SetValue(null, value);
}
}
}
[UnityEditor.CanEditMultipleObjects]
[UnityEditor.CustomEditor(typeof(AkGameObj), true)]
public class AkGameObjectInspector : UnityEditor.Editor
{
private bool hideDefaultHandle;
private UnityEditor.SerializedProperty listeners;
private AkGameObj m_AkGameObject;
private UnityEditor.SerializedProperty usePositionOffsetData;
private void OnEnable()
{
m_AkGameObject = target as AkGameObj;
listeners = serializedObject.FindProperty("m_listeners");
usePositionOffsetData = serializedObject.FindProperty("usePositionOffsetData");
DefaultHandles.Hidden = hideDefaultHandle;
}
private void OnDisable()
{
DefaultHandles.Hidden = false;
}
public override void OnInspectorGUI()
{
var positionOffsetData = m_AkGameObject.m_positionOffsetData;
var positionOffset = UnityEngine.Vector3.zero;
UnityEditor.EditorGUI.BeginChangeCheck();
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUILayout.PropertyField(usePositionOffsetData, new UnityEngine.GUIContent("Apply Position Offset:"));
if (usePositionOffsetData.boolValue)
{
positionOffset = UnityEditor.EditorGUILayout.Vector3Field("Position Offset", positionOffsetData.positionOffset);
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
if (hideDefaultHandle)
{
if (UnityEngine.GUILayout.Button("Show Main Transform"))
{
hideDefaultHandle = false;
DefaultHandles.Hidden = hideDefaultHandle;
}
}
else if (UnityEngine.GUILayout.Button("Hide Main Transform"))
{
hideDefaultHandle = true;
DefaultHandles.Hidden = hideDefaultHandle;
}
}
else if (hideDefaultHandle)
{
hideDefaultHandle = false;
DefaultHandles.Hidden = hideDefaultHandle;
}
}
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
var isEnvironmentAware = m_AkGameObject.isEnvironmentAware;
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
isEnvironmentAware = UnityEditor.EditorGUILayout.Toggle("Environment Aware:", isEnvironmentAware);
}
if (m_AkGameObject.gameObject.GetComponent<AkRoomAwareObject>() == null)
{
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUILayout.LabelField("Room Aware: ", "");
if (UnityEngine.GUILayout.Button("Add AkRoomAwareObject"))
UnityEditor.Undo.AddComponent<AkRoomAwareObject>(m_AkGameObject.gameObject);
}
}
if (UnityEditor.EditorGUI.EndChangeCheck())
{
UnityEditor.Undo.RecordObject(target, "AkGameObj Parameter Change");
m_AkGameObject.m_positionOffsetData = positionOffsetData;
var posOffsetDataProperty = serializedObject.FindProperty("m_positionOffsetData");
var KeepMeProperty = posOffsetDataProperty.FindPropertyRelative("KeepMe");
KeepMeProperty.boolValue = (positionOffsetData != null);
if (positionOffsetData != null)
{
var posOffsetProperty = posOffsetDataProperty.FindPropertyRelative("positionOffset");
posOffsetProperty.vector3Value = positionOffset;
}
serializedObject.ApplyModifiedProperties();
m_AkGameObject.isEnvironmentAware = isEnvironmentAware;
}
if (isEnvironmentAware)
{
RigidbodyCheck(m_AkGameObject.gameObject);
}
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
UnityEditor.EditorGUI.BeginChangeCheck();
m_AkGameObject.ScalingFactor = UnityEditor.EditorGUILayout.FloatField("Attenuation Scaling Factor", m_AkGameObject.ScalingFactor);
if (UnityEditor.EditorGUI.EndChangeCheck())
{
if (m_AkGameObject.ScalingFactor <= 0)
{
m_AkGameObject.ScalingFactor = 0;
}
else
{
if (m_AkGameObject.gameObject.activeInHierarchy)
{
AkUnitySoundEngine.SetScalingFactor(m_AkGameObject.gameObject, m_AkGameObject.ScalingFactor);
}
}
}
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUI.BeginChangeCheck();
UnityEditor.EditorGUILayout.PropertyField(listeners);
if (UnityEditor.EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
}
}
}
public static void RigidbodyCheck(UnityEngine.GameObject gameObject)
{
if (AkWwiseEditorSettings.Instance.ShowSpatialAudioWarningMsg && gameObject.GetComponent<UnityEngine.Rigidbody>() == null)
{
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUILayout.HelpBox(
"Interactions between AkGameObj and AkEnvironment require a Rigidbody component on the object or the environment.",
UnityEditor.MessageType.Warning);
if (UnityEngine.GUILayout.Button("Add Rigidbody"))
{
var rb = UnityEditor.Undo.AddComponent<UnityEngine.Rigidbody>(gameObject);
rb.useGravity = false;
rb.isKinematic = true;
}
}
}
}
private void OnSceneGUI()
{
if (m_AkGameObject.m_positionOffsetData == null)
{
return;
}
UnityEditor.EditorGUI.BeginChangeCheck();
// Transform local offset to world coordinate
var pos = m_AkGameObject.transform.TransformPoint(m_AkGameObject.m_positionOffsetData.positionOffset);
// Get new handle position
pos = UnityEditor.Handles.PositionHandle(pos, UnityEngine.Quaternion.identity);
if (UnityEditor.EditorGUI.EndChangeCheck())
{
UnityEditor.Undo.RecordObject(target, "Position Offset Change");
// Transform world offset to local coordinate
m_AkGameObject.m_positionOffsetData.positionOffset = m_AkGameObject.transform.InverseTransformPoint(pos);
}
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 1c9d43b9fb1745f46aedd34153ebaed0
@@ -0,0 +1,216 @@
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
using UnityEngine;
[UnityEditor.InitializeOnLoad]
public class AkPortalManager
{
private static AkPortalManager s_portalManager;
public System.Collections.Generic.List<AkEnvironment> EnvironmentList =
new System.Collections.Generic.List<AkEnvironment>();
public System.Collections.Generic.Dictionary<int, System.Collections.Generic.List<AkEnvironment>>[]
IntersectingEnvironments =
{
//All environments on the negative side of each portal(opposite to the direction of the chosen axis)
new System.Collections.Generic.Dictionary<int, System.Collections.Generic.List<AkEnvironment>>(),
//All environments on the positive side of each portal(same direction as the chosen axis)
new System.Collections.Generic.Dictionary<int, System.Collections.Generic.List<AkEnvironment>>()
};
private float m_timeStamp = UnityEngine.Time.realtimeSinceStartup;
public System.Collections.Generic.List<AkEnvironmentPortal> PortalList =
new System.Collections.Generic.List<AkEnvironmentPortal>();
static AkPortalManager()
{
if (UnityEditor.AssetDatabase.IsAssetImportWorkerProcess())
{
return;
}
//This constructor is called before any game object is created when there is a compilation which makes the 'FindObjectsOfType' function return null.
//So we register the init function to be called at hte first update.
UnityEditor.EditorApplication.update += Init;
}
public static void Init()
{
//Do nothing if Manager exists
if (s_portalManager == null)
{
s_portalManager = new AkPortalManager();
s_portalManager.Populate();
//Register the update function to be called at each frame
UnityEditor.EditorApplication.update += s_portalManager.UpdateEnvironments;
}
//Unregister in case we were registered
UnityEditor.EditorApplication.update -= Init;
}
public static AkPortalManager GetManager()
{
return s_portalManager;
}
public void Populate()
{
//Add all environments in the scene to the environment list
#if UNITY_6000_0_OR_NEWER
var akEnv = Object.FindObjectsByType<AkEnvironment>(FindObjectsSortMode.None);
#else
var akEnv = Object.FindObjectsOfType<AkEnvironment>();
#endif
s_portalManager.EnvironmentList.Clear();
s_portalManager.EnvironmentList.AddRange(akEnv);
//Add all portals in the scene to the portal list
#if UNITY_6000_0_OR_NEWER
var akPortals = Object.FindObjectsByType<AkEnvironmentPortal>(FindObjectsSortMode.None);
#else
var akPortals = Object.FindObjectsOfType<AkEnvironmentPortal>();
#endif
s_portalManager.PortalList.Clear();
s_portalManager.PortalList.AddRange(akPortals);
//check for portal-environment intersections and populate the IntersectingEnvironments dictionary
for (var i = 0; i < s_portalManager.PortalList.Count; i++)
s_portalManager.UpdatePortal(s_portalManager.PortalList[i]);
}
public void UpdatePortal(AkEnvironmentPortal in_portal)
{
var envList = new System.Collections.Generic.List<AkEnvironment>[2];
for (var i = 0; i < 2; i++)
{
if (!IntersectingEnvironments[i].TryGetValue(in_portal.GetInstanceID(), out envList[i]))
{
envList[i] = new System.Collections.Generic.List<AkEnvironment>();
IntersectingEnvironments[i][in_portal.GetInstanceID()] = envList[i];
}
else
envList[i].Clear();
}
//We check if a portal intersects any environment
//Iterate in reverse order for safe removal form list while iterating
for (var i = EnvironmentList.Count - 1; i >= 0; i--)
{
if (EnvironmentList[i] != null)
{
//if there is an intersection
if (in_portal.GetComponent<UnityEngine.Collider>().bounds
.Intersects(EnvironmentList[i].GetComponent<UnityEngine.Collider>().bounds))
{
if (UnityEngine.Vector3.Dot(in_portal.transform.rotation * in_portal.axis,
EnvironmentList[i].transform.position - in_portal.transform.position) >= 0)
envList[1].Add(EnvironmentList[i]);
else
envList[0].Add(EnvironmentList[i]);
}
}
else
EnvironmentList.RemoveAt(i);
}
}
private void UpdateEnvironment(AkEnvironment in_env)
{
for (var i = PortalList.Count - 1; i >= 0; i--) //Iterate in reverse order for safe removal form list while iterating
{
if (PortalList[i] != null)
{
if (in_env.GetComponent<UnityEngine.Collider>().bounds
.Intersects(PortalList[i].GetComponent<UnityEngine.Collider>().bounds))
{
System.Collections.Generic.List<AkEnvironment> envList = null;
//Get index of the list that should contain this environment
//Index = 0 means that the enviroment is on the negative side of the portal (opposite to the direction of the chosen axis)
//Index = 1 means that the enviroment is on the positive side of the portal (same direction as the chosen axis)
var index = UnityEngine.Vector3.Dot(PortalList[i].transform.rotation * PortalList[i].axis,
in_env.transform.position - PortalList[i].transform.position) >= 0
? 1
: 0;
if (!IntersectingEnvironments[index].TryGetValue(PortalList[i].GetInstanceID(), out envList))
{
envList = new System.Collections.Generic.List<AkEnvironment>();
envList.Add(in_env);
IntersectingEnvironments[index][PortalList[i].GetInstanceID()] = envList;
}
else if (!envList.Contains(in_env))
envList.Add(in_env);
}
}
else
PortalList.RemoveAt(i);
}
}
public void UpdateEnvironments()
{
//Timer is reset when starting play mode and when coming back to editor mode
if (UnityEngine.Time.realtimeSinceStartup < m_timeStamp)
{
m_timeStamp = UnityEngine.Time.realtimeSinceStartup;
//The PortalManager object doesn't get destroyed but all game objects in our lists become null
//So we populate
Populate();
return;
}
//The update is done once every second
if (UnityEngine.Time.realtimeSinceStartup - m_timeStamp < 1.0f)
return;
m_timeStamp = UnityEngine.Time.realtimeSinceStartup;
var portals = UnityEditor.Selection.GetFiltered(typeof(AkEnvironmentPortal), UnityEditor.SelectionMode.Unfiltered);
if (portals != null)
{
for (var i = 0; i < portals.Length; i++)
{
if (!PortalList.Contains((AkEnvironmentPortal) portals[i]))
PortalList.Add((AkEnvironmentPortal) portals[i]);
UpdatePortal((AkEnvironmentPortal) portals[i]);
}
}
var envs = UnityEditor.Selection.GetFiltered(typeof(AkEnvironment), UnityEditor.SelectionMode.Unfiltered);
if (envs != null)
{
for (var i = 0; i < envs.Length; i++)
{
if (!EnvironmentList.Contains((AkEnvironment) envs[i]))
EnvironmentList.Add((AkEnvironment) envs[i]);
UpdateEnvironment((AkEnvironment) envs[i]);
}
}
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 60b0f9687d4d90043ae39382594ebc52
@@ -0,0 +1,75 @@
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEditor.CustomEditor(typeof(AkRadialEmitter), true)]
public class AkRadialEmitterInspector : UnityEditor.Editor
{
private AkRadialEmitter m_AkRadialEmitter;
private UnityEditor.SerializedProperty outerRadius;
private UnityEditor.SerializedProperty innerRadius;
private void OnEnable()
{
m_AkRadialEmitter = target as AkRadialEmitter;
outerRadius = serializedObject.FindProperty("outerRadius");
innerRadius = serializedObject.FindProperty("innerRadius");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
if (m_AkRadialEmitter.outerRadius < 0.0f)
m_AkRadialEmitter.outerRadius = 0.0f;
if (m_AkRadialEmitter.innerRadius < 0.0f)
m_AkRadialEmitter.innerRadius = 0.0f;
if (m_AkRadialEmitter.innerRadius > m_AkRadialEmitter.outerRadius)
m_AkRadialEmitter.innerRadius = m_AkRadialEmitter.outerRadius;
UnityEditor.EditorGUILayout.PropertyField(outerRadius);
UnityEditor.EditorGUILayout.PropertyField(innerRadius);
EventCheck(m_AkRadialEmitter.gameObject);
serializedObject.ApplyModifiedProperties();
}
public static void EventCheck(UnityEngine.GameObject gameObject)
{
if (AkWwiseEditorSettings.Instance.ShowSpatialAudioWarningMsg && gameObject.GetComponent<AkEvent>() == null)
{
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUILayout.HelpBox(
"Radial emitters are expected to emit sound. Add an AkEvent or an AkAmbient component to this game object.",
UnityEditor.MessageType.Warning);
if (UnityEngine.GUILayout.Button("Add AkEvent"))
UnityEditor.Undo.AddComponent<AkEvent>(gameObject);
if (UnityEngine.GUILayout.Button("Add AkAmbient"))
UnityEditor.Undo.AddComponent<AkAmbient>(gameObject);
}
}
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 1fbe197aa6aa1af45b2a6cd5910de6ff
@@ -0,0 +1,78 @@
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEditor.CustomEditor(typeof(AkRoomAwareObject), true)]
public class AkRoomAwareObjectInspector : UnityEditor.Editor
{
private bool hideDefaultHandle;
private UnityEditor.SerializedProperty listeners;
private AkRoomAwareObject m_AkRoomAwareObject;
private void OnEnable()
{
m_AkRoomAwareObject = target as AkRoomAwareObject;
}
public override void OnInspectorGUI()
{
RigidbodyCheck(m_AkRoomAwareObject.gameObject);
ColliderCheck(m_AkRoomAwareObject.gameObject);
}
public static void ColliderCheck(UnityEngine.GameObject gameObject)
{
if (AkWwiseEditorSettings.Instance.ShowSpatialAudioWarningMsg)
{
var collider = gameObject.GetComponent<UnityEngine.Collider>();
if (collider == null || !collider.enabled)
{
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUILayout.HelpBox(
"Interactions between AkRoomAwareObject and AkRoom require a Collider component on the object.",
UnityEditor.MessageType.Error);
}
}
}
}
public static void RigidbodyCheck(UnityEngine.GameObject gameObject)
{
if (AkWwiseEditorSettings.Instance.ShowSpatialAudioWarningMsg && gameObject.GetComponent<UnityEngine.Rigidbody>() == null)
{
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUILayout.HelpBox(
"Interactions between AkRoomAwareObject and AkRoom require a Rigidbody component on the object or the room.",
UnityEditor.MessageType.Warning);
if (UnityEngine.GUILayout.Button("Add Rigidbody"))
{
var rb = UnityEditor.Undo.AddComponent<UnityEngine.Rigidbody>(gameObject);
rb.useGravity = false;
rb.isKinematic = true;
}
}
}
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: bf09946363d6f1746be03843cdd1e73e
@@ -0,0 +1,129 @@
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEditor.CustomEditor(typeof(AkRoom), true)]
public class AkRoomInspector : UnityEditor.Editor
{
private readonly AkUnityEventHandlerInspector m_PostEventHandlerInspector = new AkUnityEventHandlerInspector();
private AkRoom m_AkRoom;
private UnityEditor.SerializedProperty priority;
private UnityEditor.SerializedProperty reverbAuxBus;
private UnityEditor.SerializedProperty reverbLevel;
private UnityEditor.SerializedProperty transmissionLoss;
private UnityEditor.SerializedProperty distanceBehavior;
private UnityEditor.SerializedProperty roomToneEvent;
private UnityEditor.SerializedProperty roomToneAuxSend;
private UnityEditor.SerializedProperty isStatic;
private void OnEnable()
{
m_PostEventHandlerInspector.Init(serializedObject, "triggerList", "Trigger On: ", false);
m_AkRoom = target as AkRoom;
reverbAuxBus = serializedObject.FindProperty("reverbAuxBus");
reverbLevel = serializedObject.FindProperty("reverbLevel");
transmissionLoss = serializedObject.FindProperty("transmissionLoss");
distanceBehavior = serializedObject.FindProperty("distanceBehavior");
priority = serializedObject.FindProperty("priority");
roomToneEvent = serializedObject.FindProperty("roomToneEvent");
roomToneAuxSend = serializedObject.FindProperty("roomToneAuxSend");
isStatic = serializedObject.FindProperty("isStatic");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
UnityEditor.EditorGUILayout.PropertyField(isStatic);
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUILayout.PropertyField(reverbAuxBus);
UnityEditor.EditorGUILayout.PropertyField(reverbLevel);
UnityEditor.EditorGUILayout.PropertyField(transmissionLoss);
UnityEditor.EditorGUILayout.PropertyField(distanceBehavior);
UnityEditor.EditorGUILayout.PropertyField(priority);
WetTransmissionCheck(m_AkRoom.gameObject);
}
UnityEditor.EditorGUILayout.LabelField("Room Tone", UnityEditor.EditorStyles.boldLabel);
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
m_PostEventHandlerInspector.OnGUI();
UnityEditor.EditorGUILayout.PropertyField(roomToneEvent);
UnityEditor.EditorGUILayout.PropertyField(roomToneAuxSend);
TriggerCheck(m_AkRoom);
}
AkRoomAwareObjectInspector.RigidbodyCheck(m_AkRoom.gameObject);
serializedObject.ApplyModifiedProperties();
}
public static void WetTransmissionCheck(UnityEngine.GameObject gameObject)
{
if (AkWwiseEditorSettings.Instance.ShowSpatialAudioWarningMsg &&
gameObject.GetComponent<AkSurfaceReflector>() == null &&
gameObject.GetComponent<UnityEngine.Mesh>() == null)
{
// wet transmission supports box, sphere, capsule and mesh colliders
bool bSupported = false;
if (gameObject.GetComponent<UnityEngine.BoxCollider>() != null ||
gameObject.GetComponent<UnityEngine.SphereCollider>() != null ||
gameObject.GetComponent<UnityEngine.CapsuleCollider>() != null ||
gameObject.GetComponent<UnityEngine.MeshCollider>() != null ||
(gameObject.GetComponent<AkSurfaceReflector>() != null && gameObject.GetComponent<AkSurfaceReflector>().enabled))
{
bSupported = true;
}
if (bSupported == false)
{
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUILayout.HelpBox(
"Associating a geometry with this room for wet transmission is currently only supported with box, sphere, capsule and mesh colliders, or if the game object also has an enabled AkSurfaceReflector component.",
UnityEditor.MessageType.Warning);
}
}
}
}
public static void TriggerCheck(AkRoom room)
{
if (room.triggerList.Contains(AkTriggerHandler.DESTROY_TRIGGER_ID) ||
room.triggerList.Contains(AkTriggerHandler.ON_DISABLE_TRIGGER_ID))
{
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUILayout.HelpBox(
"Room tones will only be posted on active and enabled gameobjects; it is not possible to post room tones on disable and on destroy.",
UnityEditor.MessageType.Warning);
}
}
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 1f789937f5310a54886157807c75c61e
@@ -0,0 +1,102 @@
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEditor.CanEditMultipleObjects]
[UnityEditor.CustomEditor(typeof(AkRoomPortal), true)]
public class AkRoomPortalInspector : UnityEditor.Editor
{
private UnityEditor.SerializedProperty initialState;
private UnityEditor.SerializedProperty rooms;
private UnityEditor.SerializedProperty isStatic;
private readonly AkUnityEventHandlerInspector m_ClosePortalEventHandlerInspector = new AkUnityEventHandlerInspector();
private readonly AkUnityEventHandlerInspector m_OpenPortalEventHandlerInspector = new AkUnityEventHandlerInspector();
private AkRoomPortal m_roomPortal;
[UnityEditor.MenuItem("GameObject/Wwise/Room Portal", false, 1)]
public static void CreatePortal()
{
var portal = new UnityEngine.GameObject("RoomPortal");
UnityEditor.Undo.AddComponent<AkRoomPortal>(portal);
portal.GetComponent<UnityEngine.Collider>().isTrigger = true;
UnityEditor.Selection.objects = new UnityEngine.Object[] { portal };
}
private void OnEnable()
{
initialState = serializedObject.FindProperty("initialState");
rooms = serializedObject.FindProperty("rooms");
isStatic = serializedObject.FindProperty("isStatic");
m_OpenPortalEventHandlerInspector.Init(serializedObject, "triggerList", "Open On: ", false);
m_ClosePortalEventHandlerInspector.Init(serializedObject, "closePortalTriggerList", "Close On: ", false);
m_roomPortal = target as AkRoomPortal;
}
public override void OnInspectorGUI()
{
serializedObject.Update();
UnityEditor.EditorGUILayout.PropertyField(isStatic);
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUILayout.PropertyField(initialState);
m_OpenPortalEventHandlerInspector.OnGUI();
m_ClosePortalEventHandlerInspector.OnGUI();
}
m_roomPortal.UpdateRooms();
var labels = new[] { "Back Room", "Front Room" };
var tooltips = new[] { "The highest priority, active and enabled AkRoom component overlapping the back surface of this AkRoomPortal.",
"The highest priority, active and enabled AkRoom component overlapping the front surface of this AkRoomPortal." };
var wasEnabled = UnityEngine.GUI.enabled;
UnityEngine.GUI.enabled = false;
for (var i = 0; i < AkRoomPortal.MAX_ROOMS_PER_PORTAL; i++)
UnityEditor.EditorGUILayout.PropertyField(rooms.GetArrayElementAtIndex(i), new UnityEngine.GUIContent(labels[i], tooltips[i]), true);
UnityEngine.GUI.enabled = wasEnabled;
RoomCheck(m_roomPortal);
serializedObject.ApplyModifiedProperties();
}
public static void RoomCheck(AkRoomPortal portal)
{
if (AkWwiseEditorSettings.Instance.ShowSpatialAudioWarningMsg)
{
if (!portal.IsValid)
{
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
UnityEditor.EditorGUILayout.HelpBox(
"Portal placement is invalid. It will not be set in the Spatial Audio engine. The front and back Rooms of the Portal cannot be the same or have a ReverbZone-parent relationship.",
UnityEditor.MessageType.Warning);
}
}
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 7bdd28aaf4add69428d1b3149688ec8d
@@ -0,0 +1,29 @@
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEditor.CustomEditor(typeof(AkSpatialAudioListener), true)]
public class AkSpatialAudioListenerInspector : UnityEditor.Editor
{
public override void OnInspectorGUI()
{
UnityEditor.EditorGUILayout.HelpBox(
"The current version of Spatial Audio only supports one listener. Make sure to only have one AkSpatialAudioListener active at a time.",
UnityEditor.MessageType.Info);
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 335cff85d4897d74bba27db0bd5a5684
@@ -0,0 +1,35 @@
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEditor.CanEditMultipleObjects]
[UnityEditor.CustomEditor(typeof(AkState), true)]
public class AkStateInspector : AkBaseInspector
{
private readonly AkUnityEventHandlerInspector m_UnityEventHandlerInspector = new AkUnityEventHandlerInspector();
private void OnEnable()
{
m_UnityEventHandlerInspector.Init(serializedObject);
}
public override void OnChildInspectorGUI()
{
m_UnityEventHandlerInspector.OnGUI();
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 39955d24bad7d8548bafb60ea0874dda
@@ -0,0 +1,100 @@
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEditor.CustomEditor(typeof(AkSurfaceReflector), true)]
[UnityEditor.CanEditMultipleObjects]
public class AkSurfaceReflectorInspector : UnityEditor.Editor
{
private AkSurfaceReflector m_AkSurfaceReflector;
private UnityEditor.SerializedProperty Mesh;
private UnityEditor.SerializedProperty AcousticTextures;
private UnityEditor.SerializedProperty TransmissionLossValues;
private UnityEditor.SerializedProperty EnableDiffraction;
private UnityEditor.SerializedProperty EnableDiffractionOnBoundaryEdges;
private UnityEditor.SerializedProperty BypassPortalSubtraction;
private UnityEditor.SerializedProperty Solid;
private UnityEditor.SerializedProperty isStatic;
public void OnEnable()
{
m_AkSurfaceReflector = target as AkSurfaceReflector;
Mesh = serializedObject.FindProperty("Mesh");
AcousticTextures = serializedObject.FindProperty("AcousticTextures");
TransmissionLossValues = serializedObject.FindProperty("TransmissionLossValues");
EnableDiffraction = serializedObject.FindProperty("EnableDiffraction");
EnableDiffractionOnBoundaryEdges = serializedObject.FindProperty("EnableDiffractionOnBoundaryEdges");
Solid = serializedObject.FindProperty("Solid");
BypassPortalSubtraction = serializedObject.FindProperty("BypassPortalSubtraction");
isStatic = serializedObject.FindProperty("isStatic");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
UnityEditor.EditorGUILayout.PropertyField(isStatic);
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUILayout.PropertyField(Mesh);
UnityEditor.EditorGUILayout.PropertyField(AcousticTextures, true);
CheckArraySize(m_AkSurfaceReflector, m_AkSurfaceReflector.AcousticTextures.Length, "acoustic textures");
UnityEditor.EditorGUILayout.PropertyField(TransmissionLossValues, true);
CheckArraySize(m_AkSurfaceReflector, m_AkSurfaceReflector.TransmissionLossValues.Length, "transmission loss values");
}
UnityEditor.EditorGUILayout.PropertyField(EnableDiffraction);
if (EnableDiffraction.boolValue)
{
UnityEditor.EditorGUILayout.PropertyField(EnableDiffractionOnBoundaryEdges);
}
UnityEditor.EditorGUILayout.PropertyField(BypassPortalSubtraction);
UnityEditor.EditorGUILayout.PropertyField(Solid);
serializedObject.ApplyModifiedProperties();
}
public static void CheckArraySize(AkSurfaceReflector surfaceReflector, int length, string name)
{
if (surfaceReflector == null || surfaceReflector.Mesh == null)
{
return;
}
int maxSize = surfaceReflector.Mesh.subMeshCount;
if (length <= maxSize)
{
return;
}
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
UnityEditor.EditorGUILayout.HelpBox(
"There are more " + name + " than the Mesh has submeshes. Additional ones will be ignored.",
UnityEditor.MessageType.Warning);
}
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 1bac1f7c5c021bd47b130b9991a9ecde
@@ -0,0 +1,35 @@
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEditor.CanEditMultipleObjects]
[UnityEditor.CustomEditor(typeof(AkSwitch), true)]
public class AkSwitchInspector : AkBaseInspector
{
private readonly AkUnityEventHandlerInspector m_UnityEventHandlerInspector = new AkUnityEventHandlerInspector();
private void OnEnable()
{
m_UnityEventHandlerInspector.Init(serializedObject);
}
public override void OnChildInspectorGUI()
{
m_UnityEventHandlerInspector.OnGUI();
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 261f4e1fa38cc09439250c00da2adb80
@@ -0,0 +1,158 @@
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
public class AkUnityEventHandlerInspector
{
private static string[] m_triggerTypeNames;
private static uint[] m_triggerTypeIDs;
private static System.Collections.Generic.Dictionary<uint, string> m_triggerTypes;
///Defines the triggers that make use of useOtherObjectMask
private static readonly string[] useOtherObjectTriggers =
{ "AkTriggerEnter", "AkTriggerExit", "AkTriggerCollisionEnter", "AkTriggerCollisionExit" };
private string m_label = "Trigger On: ";
private bool m_showUseOtherToggle = true;
private UnityEditor.SerializedProperty m_triggerList;
private UnityEditor.SerializedProperty m_useOtherObject;
public void Init(UnityEditor.SerializedObject in_serializedObject, string in_listName = "triggerList",
string in_label = "Trigger On: ", bool in_showUseOtherToggle = true)
{
m_label = in_label;
m_showUseOtherToggle = in_showUseOtherToggle;
m_triggerList = in_serializedObject.FindProperty(in_listName);
m_useOtherObject = in_serializedObject.FindProperty("useOtherObject");
//Get the updated list of all triggers
if (m_triggerTypes == null)
{
m_triggerTypes = AkTriggerBase.GetAllDerivedTypes();
m_triggerTypeNames = new string[m_triggerTypes.Count];
m_triggerTypes.Values.CopyTo(m_triggerTypeNames, 0);
m_triggerTypeIDs = new uint[m_triggerTypes.Count];
m_triggerTypes.Keys.CopyTo(m_triggerTypeIDs, 0);
}
}
public void OnGUI()
{
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
using (new UnityEditor.EditorGUILayout.VerticalScope("box"))
{
var currentTriggers = GetCurrentTriggers();
var oldMask = BuildCurrentMaskValue(currentTriggers);
var newMask = UnityEditor.EditorGUILayout.MaskField(m_label, oldMask, m_triggerTypeNames);
if (oldMask != newMask)
{
currentTriggers.Clear();
for (var i = 0; i < m_triggerTypeNames.Length; i++)
{
var curTriggerID = AkUtilities.ShortIDGenerator.Compute(m_triggerTypeNames[i]);
if ((newMask & (1 << i)) != 0 && !currentTriggers.Contains(curTriggerID))
currentTriggers.Add(curTriggerID);
}
SaveNewTriggers(currentTriggers);
}
if (m_showUseOtherToggle)
{
var toggleWasDisplayed = false;
for (var i = 0; i < m_triggerTypeNames.Length; i++)
{
if ((newMask & (1 << i)) != 0 && Contain(useOtherObjectTriggers, m_triggerTypeNames[i]))
{
UnityEditor.EditorGUILayout.PropertyField(m_useOtherObject, new UnityEngine.GUIContent("Use Other Object: "));
toggleWasDisplayed = true;
break;
}
}
if (!toggleWasDisplayed)
m_useOtherObject.boolValue = false;
}
}
UnityEngine.GUILayout.Space(UnityEditor.EditorGUIUtility.standardVerticalSpacing);
}
private System.Collections.Generic.List<uint> GetCurrentTriggers()
{
var newList = new System.Collections.Generic.List<uint>();
for (var i = 0; i < m_triggerList.arraySize; i++)
newList.Add((uint)m_triggerList.GetArrayElementAtIndex(i).intValue);
return newList;
}
private int GetIdIndex(uint in_ID)
{
var index = -1;
for (var i = 0; i < m_triggerTypeIDs.Length; i++)
{
if (m_triggerTypeIDs[i] == in_ID)
{
index = i;
break;
}
}
return index;
}
private int BuildCurrentMaskValue(System.Collections.Generic.List<uint> currentTriggers)
{
var maskToReturn = 0;
for (var i = 0; i < currentTriggers.Count; i++)
{
var idIndex = GetIdIndex(currentTriggers[i]);
if (idIndex != -1)
maskToReturn |= 1 << idIndex;
}
return maskToReturn;
}
private void SaveNewTriggers(System.Collections.Generic.List<uint> currentTriggers)
{
m_triggerList.ClearArray();
for (var i = 0; i < currentTriggers.Count; i++)
{
m_triggerList.InsertArrayElementAtIndex(i);
m_triggerList.GetArrayElementAtIndex(i).intValue = (int) currentTriggers[i];
}
}
private bool Contain(string[] in_array, string in_value)
{
for (var i = 0; i < in_array.Length; i++)
{
if (in_array[i].Equals(in_value))
return true;
}
return false;
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 092de7bd13bdfa54fb68789e5f42fd39
@@ -0,0 +1,35 @@
#if UNITY_EDITOR
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEditor.CanEditMultipleObjects]
[UnityEditor.CustomEditor(typeof(AkWwiseTrigger), true)]
public class AkWwiseTriggerInspector : AkBaseInspector
{
private readonly AkUnityEventHandlerInspector m_UnityEventHandlerInspector = new AkUnityEventHandlerInspector();
private void OnEnable()
{
m_UnityEventHandlerInspector.Init(serializedObject);
}
public override void OnChildInspectorGUI()
{
m_UnityEventHandlerInspector.OnGUI();
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 25215f45dc767c74d9735014cb41f2c7
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0f8828073c0dd8e4ca1dc42e88357dce
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9e1f8e0d67ca03b4c9673b30f3a1eb86
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,34 @@
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
#if UNITY_EDITOR
[UnityEditor.InitializeOnLoad]
public class AkMacBuildPreprocessor
{
static AkMacBuildPreprocessor()
{
if (UnityEditor.AssetDatabase.IsAssetImportWorkerProcess())
{
return;
}
WwiseSetupWizard.AddBuildTargetGroup(UnityEditor.BuildTargetGroup.Standalone);
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 392f44b722eebf9409adb5d5aa59907c
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 77675ff2dc9f8a54aaaa0d8d046795b0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,32 @@
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
#if UNITY_EDITOR
[UnityEditor.InitializeOnLoad]
public class AkWindowsBuildPreprocessor
{
static AkWindowsBuildPreprocessor()
{
if (UnityEditor.AssetDatabase.IsAssetImportWorkerProcess())
{
return;
}
WwiseSetupWizard.AddBuildTargetGroup(UnityEditor.BuildTargetGroup.Standalone);
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 9923482a8945cec4ab705fe400c5c8ee
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d4442a4e865c1104d96fc272b2472fbf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,204 @@
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
#if UNITY_EDITOR
using System.Collections.Generic;
using System.IO;
using AK.Wwise.Unity.Logging;
public partial class AkBuildPreprocessor
{
/// <summary>
/// User hook called to retrieve the custom platform name used to determine the base path. Do not modify platformName
/// to use default platform names.
/// </summary>
/// <param name="platformName">The custom platform name.</param>
public delegate void CustomPlatformNameGetter(ref string platformName, UnityEditor.BuildTarget target);
public static CustomPlatformNameGetter GetCustomPlatformName;
public delegate void OnBuildCallback(string path);
public static void BuildCallbackNoOp(string path)
{
// No-op
}
public class PlatformConfiguration
{
public string WwisePlatformName;
public OnBuildCallback OnPreprocessBuild = BuildCallbackNoOp;
public OnBuildCallback OnPostprocessBuild = BuildCallbackNoOp;
}
private static Dictionary<UnityEditor.BuildTarget, PlatformConfiguration> PlatformConfigurations = new Dictionary<UnityEditor.BuildTarget, PlatformConfiguration>();
public static void RegisterBuildTarget(UnityEditor.BuildTarget target, PlatformConfiguration config)
{
PlatformConfigurations.Add(target, config);
}
public static string GetPlatformName(UnityEditor.BuildTarget target)
{
var platformSubDir = string.Empty;
GetCustomPlatformName?.Invoke(ref platformSubDir, target);
if (!string.IsNullOrEmpty(platformSubDir))
return platformSubDir;
//New way to access target platform name
string platformName = AkBasePathGetter.GetTargetPlatformName(target);
if (platformName != string.Empty)
{
return platformName;
}
//For legacy code compatibility. Should maybe remove in 26.1 or 27.1 to give time to adjust
if (PlatformConfigurations.ContainsKey(target))
{
if (platformName == string.Empty)
{
platformName = PlatformConfigurations[target].WwisePlatformName;
}
return platformName;
}
//Keeping the old fallback of using the Unity target name.
return target.ToString();
}
}
#if UNITY_2018_1_OR_NEWER
public partial class AkBuildPreprocessor : UnityEditor.Build.IPreprocessBuildWithReport, UnityEditor.Build.IPostprocessBuildWithReport
#else
public partial class AkBuildPreprocessor : UnityEditor.Build.IPreprocessBuild, UnityEditor.Build.IPostprocessBuild
#endif
{
public int callbackOrder
{
get { return 0; }
}
private string destinationSoundBankFolder = string.Empty;
public static bool CopySoundbanks(bool generate, string platformName, ref string destinationFolder)
{
if (string.IsNullOrEmpty(platformName))
{
WwiseLogger.ErrorFormat("Could not determine platform name for <{0}> platform", platformName);
return false;
}
if (generate)
{
var platforms = new System.Collections.Generic.List<string> { platformName };
string wwiseInstallationPath = "";
#if UNITY_EDITOR_WIN
wwiseInstallationPath = AkWwiseEditorSettings.Instance.WwiseInstallationPathWindows;
#elif UNITY_EDITOR_OSX
wwiseInstallationPath = AkWwiseEditorSettings.Instance.WwiseInstallationPathMac;
#endif
AkUtilities.GenerateSoundbanks(wwiseInstallationPath, AkWwiseEditorSettings.WwiseProjectAbsolutePath, platforms);
}
string sourceFolder;
if (!AkBasePathGetter.GetSoundBankPaths(platformName, out sourceFolder, out destinationFolder))
return false;
if (!AkUtilities.DirectoryCopy(sourceFolder, destinationFolder, true))
{
destinationFolder = null;
WwiseLogger.ErrorFormat("Could not copy SoundBank folder for <{0}> platform", platformName);
return false;
}
WwiseLogger.Log($"Copied SoundBank folder from <{sourceFolder}> to streaming assets folder <{destinationFolder}> for <{platformName}> platform build");
return true;
}
public static void DeleteSoundbanks(string destinationFolder)
{
if (string.IsNullOrEmpty(destinationFolder))
return;
System.IO.Directory.Delete(destinationFolder, true);
WwiseLogger.LogFormat("Deleting streaming assets folder <{0}>", destinationFolder);
}
public void OnPreprocessBuildInternal(UnityEditor.BuildTarget target, string path)
{
var platformName = GetPlatformName(target);
#if !(AK_WWISE_ADDRESSABLES && UNITY_ADDRESSABLES)
if (AkWwiseEditorSettings.Instance.CopySoundBanksAsPreBuildStep)
{
if (!CopySoundbanks(AkWwiseEditorSettings.Instance.GenerateSoundBanksAsPreBuildStep, platformName, ref destinationSoundBankFolder))
{
WwiseLogger.ErrorFormat("SoundBank folder has not been copied for <{0}> target at <{1}>. This will likely result in a build without sound!!!", target, path);
}
}
#endif
if (PlatformConfigurations.TryGetValue(target, out var config))
{
config.OnPreprocessBuild(path);
}
// Init ProjectDB for platform being built
WwiseProjectDatabase.Init(AkWwiseEditorSettings.GetRootOutputPath(), platformName);
AkPluginActivator.ForceUpdate();
AkPluginActivator.ActivatePluginsForDeployment(target, true);
}
public void OnPostprocessBuildInternal(UnityEditor.BuildTarget target, string path)
{
AkPluginActivator.ActivatePluginsForDeployment(target, false);
if (PlatformConfigurations.TryGetValue(target, out var config))
{
config.OnPostprocessBuild(path);
}
#if !(AK_WWISE_ADDRESSABLES && UNITY_ADDRESSABLES)
DeleteSoundbanks(destinationSoundBankFolder);
#endif
destinationSoundBankFolder = string.Empty;
// Point the ProjectDB back on the current editor platform
WwiseProjectDatabase.Init(AkWwiseEditorSettings.GetRootOutputPath(), AkBasePathGetter.GetPlatformName());
}
#if UNITY_2018_1_OR_NEWER
public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report)
{
OnPreprocessBuildInternal(report.summary.platform, report.summary.outputPath);
}
public void OnPostprocessBuild(UnityEditor.Build.Reporting.BuildReport report)
{
OnPostprocessBuildInternal(report.summary.platform, report.summary.outputPath);
}
#else
public void OnPreprocessBuild(UnityEditor.BuildTarget target, string path)
{
OnPreprocessBuildInternal(target, path);
}
public void OnPostprocessBuild(UnityEditor.BuildTarget target, string path)
{
OnPostprocessBuildInternal(target, path);
}
#endif
}
#endif // #if UNITY_EDITOR
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5cf5d16f083391b4a8681b007ca2f85c
@@ -0,0 +1,142 @@
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
#if UNITY_EDITOR
// Note, this code was only written to parse the AudioManager.asset file.
// It has been written to try to be as generic as possible, but might not
// work on other .asset settings files.
public class AkUnitySettingsParser
{
public static bool SetBoolValue(string ValueName, bool ValueToSet, string ConfigFileName)
{
try
{
var SettingsPath = UnityEngine.Application.dataPath.Remove(UnityEngine.Application.dataPath.LastIndexOf("/")) +
"/ProjectSettings/" + ConfigFileName + ".asset";
System.IO.FileStream fs;
System.IO.BinaryReader br;
fs = System.IO.File.Open(SettingsPath, System.IO.FileMode.Open);
br = new System.IO.BinaryReader(fs);
// Read the unsigned int at offset 0x0C in the file.
// This contains the offset at which the setting's numerical values are stored.
br.BaseStream.Seek(0x0C, System.IO.SeekOrigin.Begin);
// For some reason, the offset is Big Endian in the file.
var SettingsOffset = GetBigEndianIntFromBinaryReader(br);
// In the file, we start with 0x14 bytes, then a string containing the unity version,
// then 0x0C bytes, then a string containing the base class name, followed by a string containing "base".
string tempStr;
br.BaseStream.Seek(0x14, System.IO.SeekOrigin.Begin);
tempStr = GetStringFromBinaryReader(br); // Unity Version
br.BaseStream.Seek(0x0C, System.IO.SeekOrigin.Current);
tempStr = GetStringFromBinaryReader(br); // Config file Name
if (tempStr != ConfigFileName)
return false;
tempStr = GetStringFromBinaryReader(br); // "Base"
if (tempStr != "Base")
return false;
// This string is then followed by 24 bytes
br.BaseStream.Seek(24, System.IO.SeekOrigin.Current);
// We then have a series of String (type), String (variable name), and 24 bytes
// We can use the type of the settings before the field we are looking for to
// find its offset after SettingsOffset.
while (br.BaseStream.Position < br.BaseStream.Length)
{
var SettingType = GetStringFromBinaryReader(br);
var SettingName = GetStringFromBinaryReader(br);
if (SettingName == ValueName)
break;
br.BaseStream.Seek(24, System.IO.SeekOrigin.Current);
if (GetSizeofTypeByString(SettingType) == -1)
return false;
SettingsOffset += GetSizeofTypeByString(SettingType);
}
// Set the setting in the file
var bw = new System.IO.BinaryWriter(fs);
bw.Seek(SettingsOffset, System.IO.SeekOrigin.Begin);
bw.Write(ValueToSet ? (byte) 1 : (byte) 0);
bw.Close();
fs.Close();
}
catch (System.Exception)
{
// Error happened
return false;
}
// Success!
return true;
}
// Read a big endian Int, and advances the BinaryReader's position
private static int GetBigEndianIntFromBinaryReader(System.IO.BinaryReader br)
{
var tempBytes = new byte[4];
tempBytes = br.ReadBytes(4);
return (tempBytes[0] << 24) | (tempBytes[1] << 16) | (tempBytes[2] << 8) | tempBytes[3];
}
// Reads a zero-terminated string at the BinaryReader's current position, and advances position
private static string GetStringFromBinaryReader(System.IO.BinaryReader br)
{
var list = new System.Collections.Generic.List<byte>();
// Do not add the \0 in the string, because comparison won't work
var currentByte = br.ReadByte();
while (currentByte != 0)
{
list.Add(currentByte);
currentByte = br.ReadByte();
}
return System.Text.Encoding.Default.GetString(list.ToArray());
}
// Returns the size in bytes of a type, as specified in the .asset file
// NOTE: this function only supports types found in AudioManager.asset.
private static int GetSizeofTypeByString(string typeStr)
{
switch (typeStr)
{
case "int":
case "unsigned int":
case "float":
case "UInt32":
case "SInt32":
return 4;
case "bool":
return 1;
default:
return -1;
}
}
}
#endif // UNITY_EDITOR
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e0e5c350f4eb2c541afb59c6c7203386
@@ -0,0 +1,403 @@
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
using AK.Wwise.Unity.Logging;
[UnityEditor.InitializeOnLoad]
public class AkWwisePostImportCallbackSetup
{
private static int m_scheduledMigrationStart;
private static bool m_scheduledReturnToLauncher;
private static bool m_pendingExecuteMethodCalled;
private static string s_CurrentScene;
static AkWwisePostImportCallbackSetup()
{
if (UnityEditor.AssetDatabase.IsAssetImportWorkerProcess())
{
return;
}
var arguments = System.Environment.GetCommandLineArgs();
if (UnityEngine.Application.isBatchMode
&& System.Array.IndexOf(arguments, "-wwiseEnableWithNoGraphics") == -1)
return;
UnityEditor.EditorApplication.delayCall += CheckMigrationStatus;
AkUtilities.GetEventDurations = (uint eventID, ref float maximum, ref float minimum) =>
{
var eventInfo = AkWwiseProjectInfo.GetData().GetEventInfo(eventID);
if (eventInfo != null)
{
minimum = eventInfo.minDuration;
maximum = eventInfo.maxDuration;
}
};
}
private static void CheckMigrationStatus()
{
try
{
int migrationStart;
bool returnToLauncher;
if (IsMigrationPending(out migrationStart, out returnToLauncher))
{
m_scheduledMigrationStart = migrationStart;
m_scheduledReturnToLauncher = returnToLauncher;
ScheduleMigration();
}
else
{
RefreshCallback();
}
}
catch (System.Exception e)
{
WwiseLogger.Error("Error during migration: " + e);
}
}
private static void ScheduleMigration()
{
// TODO: Is delayCall wiped out during a script reload?
// If not, guard against having a delayCall from a previously loaded code being run after the new loading.
if (UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode || UnityEditor.EditorApplication.isCompiling)
{
// Skip if not in the right mode, wait for the next callback to see if we can proceed then.
UnityEditor.EditorApplication.delayCall += ScheduleMigration;
return;
}
try
{
WwiseSetupWizard.PerformMigration(m_scheduledMigrationStart);
// Force the user to return to the launcher to perform the post-installation process if necessary
if (m_scheduledReturnToLauncher)
{
if (UnityEditor.EditorUtility.DisplayDialog("Wwise Migration Successful!",
"Please close Unity and go back to the Wwise Launcher to complete the installation.", "Quit"))
UnityEditor.EditorApplication.Exit(0);
}
else
UnityEditor.EditorApplication.delayCall += RefreshCallback;
}
catch (System.Exception e)
{
WwiseLogger.Error("Error during migration: " + e);
}
}
private static bool IsMigrationPending(out int migrationStart, out bool returnToLauncher)
{
migrationStart = 0;
returnToLauncher = false;
var filename = UnityEngine.Application.dataPath + "/../.WwiseLauncherLockFile";
if (!System.IO.File.Exists(filename))
return false;
var fileContent = System.IO.File.ReadAllText(filename);
// Instantiate the regular expression object.
var r = new System.Text.RegularExpressions.Regex(
"{\"migrateStart\":(\\d+),\"migrateStop\":(\\d+)(,\"returnToLauncher\":(true|false))?,.*}",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
// Match the regular expression pattern against a text string.
var m = r.Match(fileContent);
if (!m.Success || m.Groups.Count < 2 || m.Groups[1].Captures.Count < 1 || m.Groups[2].Captures.Count < 1 ||
!int.TryParse(m.Groups[1].Captures[0].ToString(), out migrationStart))
throw new System.Exception("Error in the file format of .WwiseLauncherLockFile.");
// Handle optional properties
if (m.Groups.Count > 3 && m.Groups[4].Captures.Count > 0)
bool.TryParse(m.Groups[4].Captures[0].ToString(), out returnToLauncher);
return true;
}
private static void RefreshCallback()
{
PostImportFunction();
if (WwiseSettings.Exists)
{
AkPluginActivator.Update();
AkPluginActivator.ActivatePluginsForEditor();
}
}
private static void PostImportFunction()
{
#if UNITY_2018_1_OR_NEWER
UnityEditor.EditorApplication.hierarchyChanged += CheckWwiseGlobalExistance;
#else
UnityEditor.EditorApplication.hierarchyWindowChanged += CheckWwiseGlobalExistance;
#endif
UnityEditor.EditorApplication.delayCall += CheckPicker;
if (UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode || UnityEditor.EditorApplication.isCompiling)
return;
try
{
if (!string.IsNullOrEmpty(AkWwiseEditorSettings.Instance.WwiseProjectPath))
{
AkWwiseBrowser.Refresh(ignoreIfWaapi: true);
}
}
catch (System.Exception e)
{
WwiseLogger.Log(e.ToString());
}
//Check if a WwiseGlobal object exists in the current scene
CheckWwiseGlobalExistance();
}
private static void RefreshPlugins()
{
if (string.IsNullOrEmpty(AkWwiseProjectInfo.GetData().CurrentPluginConfig))
AkWwiseProjectInfo.GetData().CurrentPluginConfig = AkPluginActivatorConstants.CONFIG_PROFILE;
AkPluginActivator.ActivatePluginsForEditor();
}
public static void CheckPicker()
{
if (UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode || UnityEditor.EditorApplication.isCompiling)
{
// Skip if not in the right mode, wait for the next callback to see if we can proceed then.
UnityEditor.EditorApplication.delayCall += CheckPicker;
return;
}
var settings = AkWwiseEditorSettings.Instance;
if (!settings.CreatedPicker)
{
// Delete all the ghost tabs (Failed to load).
var windows = UnityEngine.Resources.FindObjectsOfTypeAll<UnityEditor.EditorWindow>();
if (windows != null && windows.Length > 0)
{
foreach (var window in windows)
{
var windowTitle = window.titleContent.text;
if (windowTitle.Equals("Failed to load") || windowTitle.Equals("AkWwisePicker"))
{
try
{
window.Close();
}
catch
{
// Do nothing here, this shouldn't cause any problem, however there has been
// occurrences of Unity crashing on a null reference inside that method.
}
}
}
}
// TODO: If no scene is loaded and we are using the demo scene, automatically load it to display it.
// Populate the picker
AkWwiseProjectInfo.GetData(); // Load data
if (!string.IsNullOrEmpty(settings.WwiseProjectPath))
{
AkWwiseProjectInfo.Populate();
AkWwiseBrowser.InitBrowserWindow();
settings.CreatedPicker = true;
settings.SaveSettings();
}
}
UnityEditor.EditorApplication.delayCall += CheckPendingExecuteMethod;
}
// TODO: Put this in AkUtilities?
private static void ExecuteMethod(string method)
{
string className = null;
string methodName = null;
var regex = new System.Text.RegularExpressions.Regex("(.+)\\.(.+)",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
var regexMatchResult = regex.Match(method);
if (!regexMatchResult.Success || regexMatchResult.Groups.Count < 3 || regexMatchResult.Groups[1].Captures.Count < 1 || regexMatchResult.Groups[2].Captures.Count < 1)
{
WwiseLogger.Error("Error parsing wwiseExecuteMethod parameter: " + method);
return;
}
className = regexMatchResult.Groups[1].Captures[0].ToString();
methodName = regexMatchResult.Groups[2].Captures[0].ToString();
try
{
System.Reflection.MethodInfo methodToExecute = null;
if (className == "AkTestUtilities")
{
var assembly = System.Reflection.Assembly.Load("Ak.Wwise.IntegrationTestsEditor");
methodToExecute = assembly.GetType(className).GetMethod(methodName,
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
}
else
{
var type = System.Type.GetType(className);
if (type == null)
{
type = System.Type.GetType(className + ", Assembly-CSharp-Editor");
}
methodToExecute = type.GetMethod(methodName,
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
}
if (methodToExecute == null)
{
WwiseLogger.Error("Error in AkWwisePostImportCallbackSetup::ExecuteMethod(): Could not find method: " + method);
return;
}
methodToExecute.Invoke(null, null);
}
catch (System.Exception e)
{
WwiseLogger.Error("Exception caught when calling " + method + ": " + e);
}
}
private static void CheckPendingExecuteMethod()
{
var arguments = System.Environment.GetCommandLineArgs();
var indexOfCommand = System.Array.IndexOf(arguments, "-wwiseExecuteMethod");
if (!m_pendingExecuteMethodCalled && indexOfCommand != -1 && arguments.Length > indexOfCommand + 1)
{
var methodToExecute = arguments[indexOfCommand + 1];
ExecuteMethod(methodToExecute);
m_pendingExecuteMethodCalled = true;
}
}
// Called when changes are made to the scene and when a new scene is created.
public static void CheckWwiseGlobalExistance()
{
var activeSceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
if (!string.IsNullOrEmpty(s_CurrentScene) && s_CurrentScene.Equals(activeSceneName))
return;
var settings = AkWwiseEditorSettings.Instance;
// Look for a game object which has the initializer component
#if UNITY_6000_0_OR_NEWER
var AkInitializers = Object.FindObjectsByType<AkInitializer>(FindObjectsSortMode.None);
#else
var AkInitializers = Object.FindObjectsOfType<AkInitializer>();
#endif
if (AkInitializers.Length == 0)
{
if (settings.CreateWwiseGlobal)
{
WwiseLogger.LogFormat("No Wwise object in the scene ({0}), creating one.", s_CurrentScene);
//No Wwise object in this scene, create one so that the sound engine is initialized and terminated properly even if the scenes are loaded
//in the wrong order.
var objWwise = new UnityEngine.GameObject("WwiseGlobal");
//Attach initializer and terminator components
AkInitializer akInitializer;
if (AkUtilities.IsRunningTest())
{
akInitializer = objWwise.AddComponent<AkInitializer>();
}
else
{
akInitializer = UnityEditor.Undo.AddComponent<AkInitializer>(objWwise);
}
akInitializer.InitializeInitializationSettings();
}
}
else if (AkInitializers.Length > 0)
{
foreach(AkInitializer Initializer in AkInitializers)
{
if (!Initializer.InitializationSettings)
{
WwiseLogger.LogFormat("Initializing {0} (GO {1}).", Initializer.name, Initializer.gameObject.name);
Initializer.InitializeInitializationSettings();
}
}
}
else if (settings.CreateWwiseGlobal == false && AkInitializers[0].gameObject.name == "WwiseGlobal")
{
WwiseLogger.LogFormat("CreateWwiseGlobal is false. Removing the AkInitializer in scene ({0}).", s_CurrentScene);
UnityEditor.Undo.DestroyObjectImmediate(AkInitializers[0].gameObject);
}
#if AK_WWISE_ADDRESSABLES && UNITY_ADDRESSABLES
var bankHolder = UnityEngine.Object.FindObjectOfType<AK.Wwise.Unity.WwiseAddressables.InitBankHolder>();
if (bankHolder == null)
{
UnityEngine.GameObject wwiseGlobalObject = UnityEngine.GameObject.Find("WwiseGlobal");
if (wwiseGlobalObject != null)
{
bankHolder = UnityEditor.Undo.AddComponent<AK.Wwise.Unity.WwiseAddressables.InitBankHolder>(wwiseGlobalObject);
}
}
if (bankHolder!=null && bankHolder.InitBank == null)
{
#if WWISE_ADDRESABLES_2022_1_0_OR_NEWER
var initBankPath = System.IO.Path.Combine(AkWwiseEditorSettings.WwiseScriptableObjectRelativePath, "InitBank.asset");
var initbank = UnityEditor.AssetDatabase.LoadAssetAtPath<AK.Wwise.Unity.WwiseAddressables.WwiseInitBankReference>(initBankPath);
if (initbank)
{
bankHolder.InitBank = initbank;
EditorUtility.SetDirty(bankHolder);
}
#else
var initBankPath = System.IO.Path.Combine("Assets",settings.RootOutputPath,"Init.asset");
var initbank = UnityEditor.AssetDatabase.LoadAssetAtPath<AK.Wwise.Unity.WwiseAddressables.WwiseAddressableSoundBank>(initBankPath);
bankHolder.InitBank = initbank;
EditorUtility.SetDirty(bankHolder);
#endif
}
#endif
if (settings.CreateWwiseListener)
{
WwiseSetupWizard.AddAkAudioListenerToMainCamera(true);
}
s_CurrentScene = activeSceneName;
}
}
#endif // UNITY_EDITOR
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 159bb4fd4c40a30499af5da93084cf22
@@ -0,0 +1,858 @@
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
#if UNITY_EDITOR
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEditor.PackageManager;
using UnityEngine;
public class WwiseSetupWizard
{
static Dictionary<int, string> WwiseAddressableDefines = new Dictionary<int, string>()
{
{2023, "WWISE_ADDRESSABLES_23_1_OR_LATER"},
{2024, "WWISE_ADDRESSABLES_24_1_OR_LATER"}
};
static Dictionary<int, string> WwiseVersionDefines = new Dictionary<int, string>()
{
{2024, "WWISE_2024_OR_LATER"}
};
//Change this when an API change is introduced that would break older version of the addrerssables package
private static string WwiseAddressableAPIDefine = "ADDRESSABLES_API_BROWSER_TREE_VIEW";
public static void RunModify()
{
try
{
UnityEngine.Debug.Log("WwiseUnity: Running modify setup...");
UnityEditor.SceneManagement.EditorSceneManager.NewScene(UnityEditor.SceneManagement.NewSceneSetup.DefaultGameObjects);
ModifySetup();
UnityEngine.Debug.Log("WwiseUnity: Refreshing asset database.");
UnityEditor.AssetDatabase.Refresh();
// IMPORTANT: This log line is parsed by the Launcher. Do not modify it.
UnityEngine.Debug.Log("WwiseUnity: End of setup, exiting Unity.");
}
catch (System.Exception e)
{
UnityEngine.Debug.LogError("WwiseUnity: Exception caught: " + e);
}
}
public static void RunSetup()
{
try
{
UnityEngine.Debug.Log("WwiseUnity: Running install setup...");
Setup();
UnityEngine.Debug.Log("WwiseUnity: Refreshing asset database.");
UnityEditor.AssetDatabase.Refresh();
// IMPORTANT: This log line is parsed by the Launcher. Do not modify it.
UnityEngine.Debug.Log("WwiseUnity: End of setup, exiting Unity.");
}
catch (System.Exception e)
{
UnityEngine.Debug.LogError("WwiseUnity: Exception caught: " + e);
}
}
public static void RunDemoSceneSetup()
{
try
{
UnityEngine.Debug.Log("WwiseUnity: Running demo scene setup...");
Setup();
UnityEditor.SceneManagement.EditorSceneManager.OpenScene("Assets/WwiseDemoScene/WwiseDemoScene.unity");
UnityEngine.Debug.Log("WwiseUnity: Refreshing asset database.");
UnityEditor.AssetDatabase.Refresh();
UnityEngine.Debug.Log("WwiseUnity: End of demo scene setup, exiting Unity.");
}
catch (System.Exception e)
{
UnityEngine.Debug.LogError("WwiseUnity: Exception caught: " + e);
}
}
private static int TotalNumberOfSections = 3;
private static void UpdateProgressBar(int sectionIndex, int subSectionIndex = 0, int totalSubSections = 1)
{
subSectionIndex = UnityEngine.Mathf.Clamp(subSectionIndex, 0, totalSubSections);
sectionIndex = UnityEngine.Mathf.Clamp(sectionIndex, 0, TotalNumberOfSections);
float progress = ((float)subSectionIndex / totalSubSections + sectionIndex) / TotalNumberOfSections;
UnityEditor.EditorUtility.DisplayProgressBar("Wwise Integration", "Migration in progress - Please wait...", progress);
}
public static void RunMigrate()
{
try
{
UnityEngine.Debug.Log("WwiseUnity: Running migration setup...");
UnityEngine.Debug.Log("WwiseUnity: Reading parameters...");
var arguments = System.Environment.GetCommandLineArgs();
string migrateStartString = null;
var indexMigrateStart = System.Array.IndexOf(arguments, "-wwiseInstallMigrateStart");
if (indexMigrateStart != -1)
migrateStartString = arguments[indexMigrateStart + 1];
else
{
UnityEngine.Debug.LogError("WwiseUnity: ERROR: Missing parameter wwiseInstallMigrateStart.");
return;
}
int migrateStart;
if (!int.TryParse(migrateStartString, out migrateStart))
{
UnityEngine.Debug.LogError("WwiseUnity: ERROR: wwiseInstallMigrateStart is not a number.");
return;
}
PerformMigration(migrateStart - 1);
UnityEditor.AssetDatabase.SaveAssets();
UnityEngine.Debug.Log("WwiseUnity: Refreshing asset database.");
UnityEditor.AssetDatabase.Refresh();
// IMPORTANT: This log line is parsed by the Launcher. Do not modify it.
UnityEngine.Debug.Log("WwiseUnity: End of setup, exiting Unity.");
}
catch (System.Exception e)
{
UnityEngine.Debug.LogError("WwiseUnity: Exception caught: " + e);
}
}
private static void MigrateCurrentScene(System.Type[] wwiseComponentTypes)
{
var objectTypeMap = new System.Collections.Generic.Dictionary<System.Type, UnityEngine.Object[]>();
foreach (var objectType in wwiseComponentTypes)
{
// Get all objects in the scene with the specified type.
#if UNITY_6000_0_OR_NEWER
var objects = UnityEngine.Object.FindObjectsByType(objectType, FindObjectsSortMode.None);
#else
var objects = UnityEngine.Object.FindObjectsOfType(objectType);
#endif
if (objects != null && objects.Length > 0)
objectTypeMap[objectType] = objects;
}
for (var ii = AkUtilities.MigrationStartIndex; ii < AkUtilities.MigrationStopIndex; ++ii)
{
var migrationMethodName = "Migrate" + ii;
var preMigrationMethodName = "PreMigration" + ii;
var postMigrationMethodName = "PostMigration" + ii;
foreach (var objectTypePair in objectTypeMap)
{
var objectType = objectTypePair.Key;
var objects = objectTypePair.Value;
var className = objectType.Name;
var preMigrationMethodInfo = objectType.GetMethod(preMigrationMethodName,
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
if (preMigrationMethodInfo != null)
{
UnityEngine.Debug.Log("WwiseUnity: PreMigration step <" + ii + "> for class <" + className + ">");
preMigrationMethodInfo.Invoke(null, null);
}
var migrationMethodInfo = objectType.GetMethod(migrationMethodName,
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
if (migrationMethodInfo != null)
{
UnityEngine.Debug.Log("WwiseUnity: Migration step <" + ii + "> for class <" + className + ">");
// Call the migration method of each object.
foreach (var currentObject in objects)
migrationMethodInfo.Invoke(currentObject, null);
}
var postMigrationMethodInfo = objectType.GetMethod(postMigrationMethodName,
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
if (postMigrationMethodInfo != null)
{
UnityEngine.Debug.Log("WwiseUnity: PostMigration step <" + ii + "> for class <" + className + ">");
postMigrationMethodInfo.Invoke(null, null);
}
}
}
}
private static System.Type[] GetWwiseComponentTypes()
{
var wwiseComponentTypes = new System.Collections.Generic.List<System.Type>();
var wwiseComponentFolder = UnityEngine.Application.dataPath + "/Wwise/MonoBehaviour/Runtime";
if (System.IO.Directory.Exists(wwiseComponentFolder))
{
var files = new System.IO.DirectoryInfo(wwiseComponentFolder).GetFiles("*.cs", System.IO.SearchOption.AllDirectories);
foreach (var file in files)
{
var className = System.IO.Path.GetFileNameWithoutExtension(file.Name);
var objectType = System.Type.GetType(className + ", AK.Wwise.Unity.MonoBehaviour");
if (objectType != null && objectType.IsSubclassOf(typeof(UnityEngine.Object)))
{
wwiseComponentTypes.Add(objectType);
}
}
}
return wwiseComponentTypes.ToArray();
}
private static void MigrateObject(UnityEngine.Object obj)
{
if (obj == null)
{
UnityEngine.Debug.LogWarning("WwiseUnity: Missing script! Please consider resolving the missing scripts before migrating your Unity project. Any WwiseType on this object will NOT be migrated!");
return;
}
var migratable = obj as AK.Wwise.IMigratable;
if (migratable == null && !AkUtilities.IsMigrationRequired(AkUtilities.MigrationStep.WwiseTypes_v2018_1_6))
return;
var hasChanged = false;
var serializedObject = new UnityEditor.SerializedObject(obj);
if (migratable != null)
hasChanged = migratable.Migrate(serializedObject);
else
hasChanged = AK.Wwise.TypeMigration.SearchAndProcessWwiseTypes(serializedObject.GetIterator());
if (hasChanged)
serializedObject.ApplyModifiedPropertiesWithoutUndo();
}
private static void MigratePrefabs()
{
// The only migration operation done in this method is to call MigrateObject on MonoBehaviours attached to prefabs.
// MigrateObject only runs if a migration is required for the "WwiseTypes_v2018_1_6" migration step.
// Add an early return here to avoid lots of potentially slow code if we are in a case where MigrateObject would
// do nothing.
if (!AkUtilities.IsMigrationRequired(AkUtilities.MigrationStep.WwiseTypes_v2018_1_6))
{
return;
}
var guids = UnityEditor.AssetDatabase.FindAssets("t:Prefab", new[] { "Assets" });
for (var i = 0; i < guids.Length; i++)
{
UpdateProgressBar(0, i, guids.Length);
var path = UnityEditor.AssetDatabase.GUIDToAssetPath(guids[i]);
UnityEngine.Debug.Log("WwiseUnity: Migrating prefab: " + path);
var prefabObject = UnityEditor.AssetDatabase.LoadAssetAtPath<UnityEngine.GameObject>(path);
if (prefabObject == null)
{
UnityEngine.Debug.LogWarning("WwiseUnity: Failed to migrate prefab: " + path);
continue;
}
var objects = prefabObject.GetComponents<UnityEngine.MonoBehaviour>();
// The rather convoluted way of iterating through all objects here has a very specific reason.
// The call to MigrateObject ends up calling SerializedObject.ApplyModifiedPropertiesWithoutUndo.
// This function call will invalidate all references that are held by the code that is running
// (the objects array here).
// In order to iterate properly on all MonoBehaviours available, we get their instance IDs,
// which do not change when Applying modified properties. Then, for each iteration of the
// migration loop, we need to get a valid array of MonoBehaviours again, because it might
// have been invalidated by the call to MigrateObject. We then migrate the objects that
// need migration by making sure their InstanceID is in the list of unmigrated MonoBehaviours.
var instanceIds = new System.Collections.Generic.List<int>();
foreach (var obj in objects)
{
if (obj == null)
continue;
var id = obj.GetInstanceID();
if (!instanceIds.Contains(id))
instanceIds.Add(id);
}
for (; instanceIds.Count > 0; instanceIds.RemoveAt(0))
{
var id = instanceIds[0];
var obj = UnityEditor.EditorUtility.InstanceIDToObject(id);
if (obj && obj.GetInstanceID() == id)
{
MigrateObject(obj);
}
}
}
}
private static string[] ScriptableObjectGuids = null;
private static bool ShouldProcessScriptableObject(UnityEngine.Object obj)
{
if (obj == null)
return true;
if (!(obj is UnityEngine.ScriptableObject))
return false;
if (obj is UnityEngine.GUISkin)
return false;
if (obj is AkWwiseInitializationSettings)
return false;
if (obj is AkCommonPlatformSettings)
return false;
if (AkUtilities.IsMigrationRequired(AkUtilities.MigrationStep.AutoDefinedSoundBanks_v2023_1_0) &&
obj is WwiseEventReference)
return true;
if (obj is WwiseObjectReference)
return false;
return true;
}
private static void MigrateScriptableObjects()
{
var guids = ScriptableObjectGuids;
if (guids == null)
return;
var processedGuids = new System.Collections.Generic.HashSet<string>();
for (var i = 0; i < guids.Length; i++)
{
UpdateProgressBar(2, i, guids.Length);
var guid = guids[i];
if (processedGuids.Contains(guid))
continue;
processedGuids.Add(guid);
var path = UnityEditor.AssetDatabase.GUIDToAssetPath(guid);
var objects = UnityEditor.AssetDatabase.LoadAllAssetsAtPath(path);
foreach (var obj in objects)
{
if (ShouldProcessScriptableObject(obj))
{
UnityEngine.Debug.Log("WwiseUnity: Migrating ScriptableObject: " + path);
MigrateObject(obj);
}
}
}
}
private static void MigrateScenes()
{
var wwiseComponentTypes = GetWwiseComponentTypes();
var guids = UnityEditor.AssetDatabase.FindAssets("t:Scene", new[] { "Assets" });
for (var i = 0; i < guids.Length; i++)
{
UpdateProgressBar(1, i, guids.Length);
var path = UnityEditor.AssetDatabase.GUIDToAssetPath(guids[i]);
UnityEngine.Debug.Log("WwiseUnity: Migrating scene: " + path);
UnityEditor.EditorUtility.UnloadUnusedAssetsImmediate();
var scene = UnityEditor.SceneManagement.EditorSceneManager.OpenScene(path);
MigrateCurrentScene(wwiseComponentTypes);
// From this point on, the only migration operation done in this loop is to call MigrateObject on MonoBehaviours.
// MigrateObject only runs if a migration is required for the "WwiseTypes_v2018_1_6" migration step. Simply
// continue the loop here to avoid lots of potentially slow code if we are in a case where MigrateObject would
// do nothing.
if (!AkUtilities.IsMigrationRequired(AkUtilities.MigrationStep.WwiseTypes_v2018_1_6))
{
continue;
}
var objects = UnityEngine.Resources.FindObjectsOfTypeAll<UnityEngine.MonoBehaviour>();
// The rather convoluted way of iterating through all objects here has a very specific reason.
// The call to MigrateObject ends up calling SerializedObject.ApplyModifiedPropertiesWithoutUndo.
// This function call will invalidate all references that are held by the code that is running
// (the objects array here).
// In order to iterate properly on all MonoBehaviours available, we get their instance IDs,
// which do not change when Applying modified properties. Then, for each iteration of the
// migration loop, we need to get a valid array of MonoBehaviours again, because it might
// have been invalidated by the call to MigrateObject. We then migrate the objects that
// need migration by making sure their InstanceID is in the list of unmigrated MonoBehaviours.
var instanceIds = new System.Collections.Generic.List<int>();
foreach (var obj in objects)
{
if (obj == null)
continue;
var id = obj.GetInstanceID();
if (!instanceIds.Contains(id))
instanceIds.Add(id);
}
for (; instanceIds.Count > 0; instanceIds.RemoveAt(0))
{
var id = instanceIds[0];
var obj = UnityEditor.EditorUtility.InstanceIDToObject(id);
if (obj && obj.GetInstanceID() == id)
{
MigrateObject(obj);
}
}
if (UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(scene))
if (!UnityEditor.SceneManagement.EditorSceneManager.SaveScene(scene))
throw new System.Exception("Error occurred while saving migrated scenes.");
UnityEditor.SceneManagement.EditorSceneManager.CloseScene(scene, true);
}
}
public static void PerformMigration(int migrateStart)
{
AkUtilities.BeginMigration(migrateStart);
UpdateProgressBar(0);
UnityEngine.Debug.Log("WwiseUnity: Migrating from Unity Integration Version " + migrateStart + " to " + AkUtilities.MigrationStopIndex);
AkPluginActivator.DeactivateAllPlugins();
AkPluginActivator.Update();
AkPluginActivator.ActivatePluginsForEditor();
// Get the name of the currently opened scene.
var activeScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();
var loadedScenePath = activeScene.path;
if (!string.IsNullOrEmpty(loadedScenePath))
AkUtilities.FixSlashes(ref loadedScenePath, '\\', '/', false);
UnityEditor.SceneManagement.EditorSceneManager.NewScene(UnityEditor.SceneManagement.NewSceneSetup.DefaultGameObjects);
// obtain a list of ScriptableObjects before any migration is performed
ScriptableObjectGuids = UnityEditor.AssetDatabase.FindAssets("t:ScriptableObject", new[] { "Assets" });
if (AkUtilities.IsMigrationRequired(AkUtilities.MigrationStep.NewScriptableObjectFolder_v2019_2_0))
{
var oldScriptableObjectPath = System.IO.Path.Combine(System.IO.Path.Combine("Assets", "Wwise"), "Resources");
AkUtilities.MoveFolder(oldScriptableObjectPath, AkWwiseEditorSettings.WwiseScriptableObjectRelativePath);
}
if (!UnityEditor.AssetDatabase.IsValidFolder(AkWwiseEditorSettings.WwiseScriptableObjectRelativePath))
{
UnityEngine.Debug.LogFormat("WwiseUnity: Creating ScriptableObjects folder at <{0}>", AkWwiseEditorSettings.WwiseScriptableObjectRelativePath);
AkUtilities.CreateFolder(AkWwiseEditorSettings.WwiseScriptableObjectRelativePath);
}
AkWwiseEditorSettings.GetRootOutputPath();
UnityEngine.Debug.LogFormat("WwiseUnity: Migrating Prefabs...");
MigratePrefabs();
UnityEngine.Debug.LogFormat("WwiseUnity: Done migrating Prefabs");
UnityEngine.Debug.LogFormat("WwiseUnity: Migrating Scenes...");
MigrateScenes();
UnityEngine.Debug.LogFormat("WwiseUnity: Done migrating Scenes");
UnityEngine.Debug.LogFormat("WwiseUnity: Migrating ScriptableObjects...");
MigrateScriptableObjects();
UnityEngine.Debug.LogFormat("WwiseUnity: Done migrating ScriptableObjects");
UnityEditor.EditorUtility.UnloadUnusedAssetsImmediate();
UnityEditor.SceneManagement.EditorSceneManager.NewScene(UnityEditor.SceneManagement.NewSceneSetup.DefaultGameObjects);
AkUtilities.EndMigration();
UpdateProgressBar(TotalNumberOfSections);
// Reopen the scene that was opened before the migration process started.
if (!string.IsNullOrEmpty(loadedScenePath))
{
UnityEditor.SceneManagement.EditorSceneManager.OpenScene(loadedScenePath);
}
SetWwiseVersionDefines(WwiseAddressableDefines, true, "com.audiokinetic.wwise.addressables");
SetWwiseVersionDefines(WwiseVersionDefines);
SetSoundbankSettings();
UnityEngine.Debug.Log("WwiseUnity: Removing lock for launcher.");
// TODO: Moving one folder up is not nice at all. How to find the current project path?
try
{
System.IO.File.Delete(UnityEngine.Application.dataPath + "/../.WwiseLauncherLockFile");
}
catch
{
// Ignore if not present.
}
UnityEditor.EditorUtility.ClearProgressBar();
}
public static void ModifySetup()
{
var currentConfig = AkPluginActivator.GetCurrentConfig();
if (string.IsNullOrEmpty(currentConfig))
currentConfig = AkPluginActivatorConstants.CONFIG_PROFILE;
AkPluginActivator.DeactivateAllPlugins();
AkPluginActivator.Update();
AkPluginActivator.ActivatePluginsForEditor();
SetWwiseVersionDefines(WwiseAddressableDefines, true, "com.audiokinetic.wwise.addressables");
SetWwiseVersionDefines(WwiseVersionDefines);
}
// Perform all necessary steps to use the Wwise Unity integration.
private static void Setup()
{
UnityEditor.SceneManagement.EditorSceneManager.NewScene(UnityEditor.SceneManagement.NewSceneSetup.DefaultGameObjects);
UnityEngine.Debug.Log("WwiseUnity: Deactivating all plugins...");
AkPluginActivator.DeactivateAllPlugins();
// 0. Make sure the SoundBank directory exists
var sbPath = AkWwiseEditorSettings.GetRootOutputPath();
if (!System.IO.Directory.Exists(sbPath))
System.IO.Directory.CreateDirectory(sbPath);
// 1. Disable built-in audio
if (!DisableBuiltInAudio())
{
UnityEngine.Debug.LogWarning(
"WwiseUnity: Could not disable built-in audio. Please disable built-in audio by going to Project->Project Settings->Audio, and check \"Disable Audio\".");
}
// 2. Create a "WwiseGlobal" game object and set the AkSoundEngineInitializer and terminator scripts
// 3. Set the SoundBank path property on AkSoundEngineInitializer
CreateWwiseGlobalObject();
// 5. Disable the built-in audio listener, and add AkAudioListener component to camera
if (AkWwiseEditorSettings.Instance.CreateWwiseListener)
{
AddAkAudioListenerToMainCamera();
}
// 6. Enable "Run In Background" in PlayerSettings (PlayerSettings.runInbackground property)
UnityEditor.PlayerSettings.runInBackground = true;
UnityEngine.Debug.Log("WwiseUnity: Updating PluginActivator...");
AkPluginActivator.Update();
UnityEngine.Debug.Log("WwiseUnity: Activating plugins for editor...");
AkPluginActivator.ActivatePluginsForEditor();
// 9. Activate WwiseIDs file generation, and point Wwise to the Assets/Wwise folder
// 10. Change the SoundBanks options so it adds Max Radius information in the Wwise project
if (!SetSoundbankSettings())
UnityEngine.Debug.LogWarning("WwiseUnity: Could not modify Wwise Project to generate the header file!");
#if !UNITY_2021_1_OR_NEWER
// 11. Activate XboxOne network sockets.
AkXboxOneUtils.EnableXboxOneNetworkSockets();
#endif
// 12. Add addressables version define
SetWwiseVersionDefines(WwiseAddressableDefines, true, "com.audiokinetic.wwise.addressables");
// 13. Set Wwise version defines
SetWwiseVersionDefines(WwiseVersionDefines);
}
private static HashSet<BuildTargetGroup> AvailableBuildTargetGroups = new HashSet<BuildTargetGroup>();
public static void AddBuildTargetGroup(BuildTargetGroup NewGroup)
{
AvailableBuildTargetGroups.Add(NewGroup);
}
private static void SetWwiseVersionDefines(Dictionary<int,string> versionDefines, bool isPackageDependent = false, string packageName ="")
{
string wwiseVersion = AkUnitySoundEngine.WwiseVersion;
string shortWwiseVersion = wwiseVersion.Substring(0, 4);
int wwiseVersionAsInteger = int.Parse(shortWwiseVersion);
int minimalVersion = wwiseVersionAsInteger;
if (isPackageDependent)
{
var listRequest = Client.List();
while (!listRequest.IsCompleted) { }
if (listRequest.Status == StatusCode.Success)
{
foreach (var package in listRequest.Result)
{
if (package.name == packageName)
{
string[] versionParts = package.version.Split('.');
int.TryParse(versionParts[0], out int packageMajorVersion);
if (packageMajorVersion < minimalVersion)
{
minimalVersion = packageMajorVersion;
}
}
}
}
}
//Add version defines with the wwise version as key if a new define is needed.
if (wwiseVersionAsInteger >= 2023)
{
foreach (BuildTargetGroup targetGroup in GetNonObsoleteTargetGroups())
{
#if UNITY_5_4_OR_NEWER
if (targetGroup == BuildTargetGroup.Unknown)
{
continue;
}
#endif
var namedTarget = UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup(targetGroup);
string defines = PlayerSettings.GetScriptingDefineSymbols(namedTarget);
for (int i = 2023; i <= minimalVersion; ++i)
{
if (versionDefines.ContainsKey(i))
{
Match match = Regex.Match(defines, versionDefines[i]);
if (!match.Success)
{
defines += ";" + versionDefines[i];
}
}
}
PlayerSettings.SetScriptingDefineSymbols(namedTarget, defines);
}
}
SetAddressableAdapterSymbol();
}
// Create a Wwise Global object containing the initializer and terminator scripts. Set the SoundBank path of the initializer script.
// This game object will live for the whole project; there is no need to instanciate one per scene.
private static void CreateWwiseGlobalObject()
{
// Look for a game object which has the initializer component
#if UNITY_6000_0_OR_NEWER
var AkInitializers = UnityEngine.Object.FindObjectsByType<AkInitializer>(FindObjectsSortMode.None);
#else
var AkInitializers = UnityEngine.Object.FindObjectsOfType<AkInitializer>();
#endif
if (AkInitializers.Length > 0)
UnityEditor.Undo.DestroyObjectImmediate(AkInitializers[0].gameObject);
var WwiseGlobalGameObject = new UnityEngine.GameObject("WwiseGlobal");
// attach initializer component
UnityEditor.Undo.AddComponent<AkInitializer>(WwiseGlobalGameObject);
}
private static bool DisableBuiltInAudio()
{
UnityEditor.SerializedObject audioSettingsAsset = null;
UnityEditor.SerializedProperty disableAudioProperty = null;
var assets = UnityEditor.AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/AudioManager.asset");
if (assets.Length > 0)
audioSettingsAsset = new UnityEditor.SerializedObject(assets[0]);
if (audioSettingsAsset != null)
disableAudioProperty = audioSettingsAsset.FindProperty("m_DisableAudio");
if (disableAudioProperty == null)
return false;
disableAudioProperty.boolValue = true;
audioSettingsAsset.ApplyModifiedProperties();
return true;
}
private static void MigrateRootOutputPath(string wprojPath)
{
if (string.IsNullOrEmpty(AkWwiseEditorSettings.Instance.RootOutputPath))
{
var defaultRootOutputPath = AkBasePathGetter.GetDefaultRootOutputPath();
var pathRelativeToApplicationDataPath = AkUtilities.MakeRelativePath(UnityEngine.Application.dataPath, defaultRootOutputPath);
AkWwiseEditorSettings.Instance.RootOutputPath = pathRelativeToApplicationDataPath;
AkWwiseEditorSettings.Instance.SaveSettings();
}
if (AkUtilities.IsMigrationRequired(AkUtilities.MigrationStep.RootOutputPath_v2025_1_0))
{
AkWwiseEditorSettings.MigrateRootOutputPath(wprojPath);
}
}
// Modify the .wproj file to set needed SoundBank settings
private static bool SetSoundbankSettings()
{
var settings = AkWwiseEditorSettings.Instance;
if (string.IsNullOrEmpty(settings.WwiseProjectPath))
return true;
var SoundbankPath = AkBasePathGetter.GetDefaultRootOutputPath();
if (AkWwiseEditorSettings.Instance.RootOutputPath != null)
{
var rootOutputPath = AkWwiseEditorSettings.GetRootOutputPath();
var r = new Regex(Regex.Escape("_WwiseIntegrationTemp"));
SoundbankPath = r.Replace(rootOutputPath, "", 1);
}
if (SoundbankPath == null)
{
Debug.LogWarning("Could not get Default Root Output Path.");
return false;
}
var WprojPath = AkUtilities.GetFullPath(UnityEngine.Application.dataPath, settings.WwiseProjectPath);
#if UNITY_EDITOR_OSX
SoundbankPath = "Z:" + SoundbankPath;
#endif
MigrateRootOutputPath(WprojPath);
string[] settingsToDisable = {"GenerateSoundBankXML"};
string[] settingsToEnable = {"SoundBankGenerateHeaderFile", "SoundBankGenerateMaxAttenuationInfo", "GenerateSoundBankJSON", "SoundBankGeneratePrintGUID", "SoundBankGeneratePrintPath", "AutoSoundBankEnabled"};
if (AkUtilities.SetSoundbankHeaderFilePath(WprojPath, SoundbankPath))
if (AkUtilities.ToggleBoolSoundbankSettingInWproj(settingsToDisable, WprojPath, false))
return AkUtilities.ToggleBoolSoundbankSettingInWproj(settingsToEnable, WprojPath, true);
return false;
}
public static void AddAkAudioListenerToMainCamera(bool logWarning = false)
{
UnityEngine.Camera camera = UnityEngine.Camera.main;
// Workaround for some versions of Unity not setting properly the MainCamera tag
// on the first scene of a new project
if (camera == null)
{
#if UNITY_6000_0_OR_NEWER
var cameraArray = UnityEngine.Object.FindObjectsByType<UnityEngine.Camera>(FindObjectsSortMode.None);
#else
var cameraArray = UnityEngine.Object.FindObjectsOfType<UnityEngine.Camera>();
#endif
if (cameraArray.Length > 0)
{
foreach (var entry in cameraArray)
{
if (entry.name == "Main Camera")
{
camera = entry;
break;
}
}
}
if (camera == null)
{
return;
}
}
if (camera.GetComponentInChildren<AkAudioListener>())
{
return;
}
var oldListener = camera.gameObject.GetComponent<UnityEngine.AudioListener>();
if (oldListener != null)
{
UnityEditor.Undo.DestroyObjectImmediate(oldListener);
}
var akAudioListener = UnityEditor.Undo.AddComponent<AkAudioListener>(camera.gameObject);
if (!akAudioListener)
{
return;
}
var akGameObj = akAudioListener.GetComponentInChildren<AkGameObj>();
if (akGameObj)
{
akGameObj.isEnvironmentAware = false;
}
if (logWarning)
{
UnityEngine.Debug.Log("Automatically added AkAudioListener to Main Camera. Go to \"Edit > Wwise Settings...\" to disable this functionality.");
}
}
public static BuildTargetGroup[] GetNonObsoleteTargetGroups()
{
System.Type enumType = typeof(BuildTargetGroup);
return System.Enum.GetValues(enumType).Cast<BuildTargetGroup>().Where(targetGroup =>
{
string name = targetGroup.ToString();
MemberInfo member = enumType.GetMember(name).FirstOrDefault();
if (member == null) return false;
return member.GetCustomAttribute<System.ObsoleteAttribute>() == null;
}).ToArray();
}
private static void SetAddressableAdapterSymbol()
{
foreach (BuildTargetGroup targetGroup in GetNonObsoleteTargetGroups())
{
#if UNITY_5_4_OR_NEWER
if (targetGroup == BuildTargetGroup.Unknown)
{
continue;
}
#endif
var namedTarget = UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup(targetGroup);
if (PlayerSettings.GetScriptingDefineSymbols(namedTarget).Contains(WwiseAddressableAPIDefine))
{
continue;
}
string currentDefines = PlayerSettings.GetScriptingDefineSymbols(namedTarget);
var currentDefineList = currentDefines.Split(';').ToList();
const string wwiseAddressablePrefix = "ADDRESSABLES_API";
currentDefineList.RemoveAll(define => define.StartsWith(wwiseAddressablePrefix));
currentDefineList.Add(WwiseAddressableAPIDefine);
string newDefinesString = string.Join(";", currentDefineList.Distinct());
PlayerSettings.SetScriptingDefineSymbols(namedTarget, newDefinesString);
}
}
}
#endif // UNITY_EDITOR
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 90f5790a76fd1f4449499e336513354d
@@ -0,0 +1,56 @@
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
#if !UNITY_2021_1_OR_NEWER
public static class AkXboxOneUtils
{
private static readonly int[] Usages = { 0, 1, 4, 7 };
private static readonly int SessionRequirement = 0;
private static readonly int[] DeviceUsages = { 0 };
[UnityEditor.MenuItem("Assets/Wwise/Xbox One/Enable Network Sockets")]
public static void EnableXboxOneNetworkSockets()
{
var definitions = new[]
{
new SocketDefinition("WwiseDiscoverySocket", "24024", 1, "WwiseDiscovery"),
new SocketDefinition("WwiseCommandSocket", "24025", 0, "WwiseCommand")
};
foreach (var def in definitions)
{
UnityEditor.PlayerSettings.XboxOne.SetSocketDefinition(def.Name, def.Port, def.Protocol, Usages, def.TemplateName,
SessionRequirement, DeviceUsages);
}
}
private class SocketDefinition
{
public readonly string Name;
public readonly string Port;
public readonly int Protocol;
public readonly string TemplateName;
public SocketDefinition(string name, string port, int protocol, string templateName)
{
Name = name;
Port = port;
Protocol = protocol;
TemplateName = templateName;
}
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 6ff0287eef1770945b7f6cc88ed7ce3e
+16
View File
@@ -0,0 +1,16 @@
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the AUDIOKINETIC
Wwise Technology.
Note that the use of the game engine is subject to the Unity Terms of Service
at https://unity3d.com/legal/terms-of-service.
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) <COPYRIGHTYEAR> Audiokinetic Inc.
*******************************************************************************/
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 185c24837d2b84c4d9082de81a9667d8
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+30
View File
@@ -0,0 +1,30 @@
# Unity Wwise MonoBehaviour integration
This package adds high-level MonoBehaviour components to use Wwise in Unity.
## Usage
See [Unity Wwise Components](https://www.audiokinetic.com/library/edge/?source=Unity&id=pg__wwise_components.html) for more information about how to use the package.
## Requirements
* AK.Wwise.Unity.API == 2020.1.0
## Legal
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the AUDIOKINETIC
Wwise Technology.
Note that the use of the game engine is subject to the Unity Terms of Service
at https://unity3d.com/legal/terms-of-service.
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright c <COPYRIGHTYEAR> Audiokinetic Inc.
*******************************************************************************/
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9e6f427593ba80641afb76cfaab97960
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 685f43ae7bed0334fb402f2b4a0e8632
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,39 @@
{
"name": "AK.Wwise.Unity.MonoBehaviour",
"rootNamespace": "",
"references": [
"AK.Wwise.Unity.API",
"Unity.Addressables",
"Unity.ResourceManager",
"AK.Wwise.Unity.API.WwiseTypes",
"AK.Wwise.Unity.Addressables",
"AK.Wwise.Unity.ProjectDatabase",
"AK.Wwise.Unity.Utilities",
"AK.Wwise.Unity.Logging"
],
"includePlatforms": [],
"excludePlatforms": [
"Lumin",
"Stadia"
],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [
"!UNITY_SERVER"
],
"versionDefines": [
{
"name": "com.unity.addressables",
"expression": "1.8",
"define": "UNITY_ADDRESSABLES"
},
{
"name": "com.audiokinetic.wwise.addressables",
"expression": "1.0.0",
"define": "AK_WWISE_ADDRESSABLES"
}
],
"noEngineReferences": false
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4fadb0004432d254fbccfa19b3f43341
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,328 @@
#if !(UNITY_QNX) // Disable under unsupported platforms.
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
public enum MultiPositionTypeLabel
{
Simple_Mode,
Large_Mode,
MultiPosition_Mode
}
public class AkMultiPosEvent
{
public bool eventIsPlaying;
public System.Collections.Generic.List<AkAmbient> list = new System.Collections.Generic.List<AkAmbient>();
public void FinishedPlaying(object in_cookie, AkCallbackType in_type, object in_info)
{
eventIsPlaying = false;
}
}
[UnityEngine.AddComponentMenu("Wwise/AkAmbient")]
/// @brief Use this component to attach a Wwise Event to any object in a scene.
/// The sound can be started at various moments, dependent on the selected Unity trigger. This component is more useful for ambient sounds (sounds related to scene-bound objects) but could also be used for other purposes.
/// Since AkAmbient has AkEvent as its base class, it features the play/stop, play multiple, stop multiple and stop all buttons for previewing the associated Wwise event.
/// \sa
/// - \ref unity_use_AkEvent_AkAmbient
/// - \ref AkGameObj
/// - \ref AkEvent
/// - <a href="https://www.audiokinetic.com/library/edge/?source=SDK&id=soundengine__events.html" target="_blank">Integration Details - Events</a> (Note: This is described in the Wwise SDK documentation.)
public class AkAmbient : AkEvent
{
public static System.Collections.Generic.Dictionary<uint, AkMultiPosEvent> multiPosEventTree =
new System.Collections.Generic.Dictionary<uint, AkMultiPosEvent>();
public AkMultiPositionType MultiPositionType = AkMultiPositionType.AkMultiPositionType_MultiSources;
public MultiPositionTypeLabel multiPositionTypeLabel = MultiPositionTypeLabel.Simple_Mode;
private static UnityEngine.Color SPHERE_DEFAULT_COLOR = new UnityEngine.Color(1.0f, 0.0f, 0.0f, 0.1f);
public UnityEngine.Color attenuationSphereColor= SPHERE_DEFAULT_COLOR;
public AkAmbientLargeModePositioner[] LargeModePositions;
public override void OnEnable()
{
#if UNITY_EDITOR
if (UnityEngine.Application.isBatchMode)
{
return;
}
#endif
if (multiPositionTypeLabel == MultiPositionTypeLabel.MultiPosition_Mode)
{
var gameObj = gameObject.GetComponents<AkGameObj>();
for (var i = 1; i < gameObj.Length; i++)
{
gameObj[i].enabled = false;
}
AkMultiPosEvent eventPosList;
if (multiPosEventTree.TryGetValue(data.Id, out eventPosList))
{
if (!eventPosList.list.Contains(this))
{
eventPosList.list.Add(this);
}
}
else
{
eventPosList = new AkMultiPosEvent();
eventPosList.list.Add(this);
multiPosEventTree.Add(data.Id, eventPosList);
}
var positionArray = BuildMultiDirectionArray(eventPosList);
//Set multiple positions
AkUnitySoundEngine.SetMultiplePositions(eventPosList.list[0].gameObject, positionArray, (ushort) positionArray.Count, MultiPositionType);
}
base.OnEnable();
}
protected override void Start()
{
base.Start();
if (multiPositionTypeLabel == MultiPositionTypeLabel.Simple_Mode)
{
var gameObj = gameObject.GetComponents<AkGameObj>();
for (var i = 0; i < gameObj.Length; i++)
{
gameObj[i].enabled = true;
}
}
else if (multiPositionTypeLabel == MultiPositionTypeLabel.Large_Mode)
{
#if UNITY_EDITOR
if (!UnityEditor.EditorApplication.isPlaying || UnityEngine.Application.isBatchMode)
{
return;
}
#endif
var positionArray = BuildAkPositionArray();
AkUnitySoundEngine.SetMultiplePositions(gameObject, positionArray, (ushort)positionArray.Count, MultiPositionType);
}
}
private new void OnDisable()
{
#if UNITY_EDITOR
if (UnityEngine.Application.isBatchMode)
{
return;
}
#endif
if (multiPositionTypeLabel == MultiPositionTypeLabel.MultiPosition_Mode)
{
var eventPosList = multiPosEventTree[data.Id];
if (eventPosList.list.Count == 1)
{
multiPosEventTree.Remove(data.Id);
}
else
{
eventPosList.list.Remove(this);
var positionArray = BuildMultiDirectionArray(eventPosList);
AkUnitySoundEngine.SetMultiplePositions(eventPosList.list[0].gameObject, positionArray, (ushort) positionArray.Count, MultiPositionType);
}
}
base.OnDisable();
}
protected new void OnDestroy()
{
if (multiPositionTypeLabel != MultiPositionTypeLabel.MultiPosition_Mode)
{
base.OnDestroy();
}
}
public override void HandleEvent(UnityEngine.GameObject in_gameObject)
{
if (multiPositionTypeLabel != MultiPositionTypeLabel.MultiPosition_Mode)
{
base.HandleEvent(in_gameObject);
}
else
{
var multiPositionSoundEmitter = multiPosEventTree[data.Id];
if (multiPositionSoundEmitter.eventIsPlaying)
{
return;
}
multiPositionSoundEmitter.eventIsPlaying = true;
soundEmitterObject = multiPositionSoundEmitter.list[0].gameObject;
if (enableActionOnEvent)
{
data.ExecuteAction(soundEmitterObject, actionOnEventType, (int)transitionDuration * 1000, curveInterpolation);
}
else
{
data.Post(soundEmitterObject, (uint)AkCallbackType.AK_EndOfEvent, multiPositionSoundEmitter.FinishedPlaying);
}
}
}
public void OnDrawGizmosSelected()
{
if (!enabled)
{
return;
}
UnityEngine.Gizmos.DrawIcon(transform.position, "WwiseAudioSpeaker.png", false);
#if UNITY_EDITOR
if (multiPositionTypeLabel == MultiPositionTypeLabel.Large_Mode)
{
foreach (var entry in LargeModePositions)
{
if (entry != null)
{
UnityEngine.Gizmos.color = UnityEngine.Color.green;
UnityEngine.Gizmos.DrawSphere(entry.transform.position, 0.1f);
UnityEditor.Handles.Label(entry.transform.position, entry.name);
AkRadialEmitter radialEmitter = GetComponent<AkRadialEmitter>();
if (radialEmitter)
{
UnityEngine.Color SphereColor = UnityEngine.Color.yellow;
SphereColor.a = 0.25f;
UnityEngine.Gizmos.color = SphereColor;
UnityEngine.Gizmos.DrawSphere(entry.transform.position, radialEmitter.innerRadius);
UnityEngine.Gizmos.DrawSphere(entry.transform.position, radialEmitter.outerRadius);
}
}
}
}
#endif
}
public AkPositionArray BuildMultiDirectionArray(AkMultiPosEvent eventPosList)
{
var positionArray = new AkPositionArray((uint) eventPosList.list.Count);
for (var i = 0; i < eventPosList.list.Count; i++)
{
positionArray.Add(eventPosList.list[i].transform.position, eventPosList.list[i].transform.forward,
eventPosList.list[i].transform.up);
}
return positionArray;
}
private AkPositionArray BuildAkPositionArray()
{
var validPositionList = new System.Collections.Generic.List<AkAmbientLargeModePositioner>();
for( int i= 0; i < LargeModePositions.Length; ++i)
{
if (LargeModePositions[i] != null)
{
if (!validPositionList.Contains(LargeModePositions[i]))
{
validPositionList.Add(LargeModePositions[i]);
}
}
}
var positionArray = new AkPositionArray((uint)validPositionList.Count);
for (int i = 0; i < validPositionList.Count; ++i)
{
positionArray.Add(validPositionList[i].Position, validPositionList[i].Forward, validPositionList[i].Up);
}
return positionArray;
}
#region WwiseMigration
#pragma warning disable 0414 // private field assigned but not used.
[UnityEngine.HideInInspector]
[UnityEngine.SerializeField]
public System.Collections.Generic.List<UnityEngine.Vector3> multiPositionArray = null;
#pragma warning restore 0414 // private field assigned but not used.
#if UNITY_EDITOR
public override bool Migrate(UnityEditor.SerializedObject obj)
{
var hasMigrated = base.Migrate(obj);
if (!AkUtilities.IsMigrationRequired(AkUtilities.MigrationStep.AkAmbient_v2019_1_0))
{
return hasMigrated;
}
var multiPositionTypeLabelProperty = obj.FindProperty("multiPositionTypeLabel");
if (multiPositionTypeLabelProperty == null)
{
return hasMigrated;
}
if (multiPositionTypeLabelProperty.intValue != (int)MultiPositionTypeLabel.Large_Mode)
{
return hasMigrated;
}
var multiPositionArrayProperty = obj.FindProperty("multiPositionArray");
if (multiPositionArrayProperty == null)
{
return hasMigrated;
}
if (multiPositionArrayProperty.arraySize == 0)
{
return hasMigrated;
}
var largeModePositionsProperty = obj.FindProperty("LargeModePositions");
if (largeModePositionsProperty == null)
{
return hasMigrated;
}
largeModePositionsProperty.arraySize = multiPositionArrayProperty.arraySize;
for (int point = 0; point < multiPositionArrayProperty.arraySize; ++point)
{
var elementProperty = multiPositionArrayProperty.GetArrayElementAtIndex(point);
var largeModePositionElementProperty = largeModePositionsProperty.GetArrayElementAtIndex(point);
if (largeModePositionElementProperty != null)
{
var newPoint = new UnityEngine.GameObject("AkAmbientPoint" + point.ToString());
newPoint.AddComponent<AkAmbientLargeModePositioner>();
newPoint.transform.SetParent(transform);
newPoint.transform.position = transform.TransformPoint(elementProperty.vector3Value);
largeModePositionElementProperty.objectReferenceValue = newPoint.GetComponent<AkAmbientLargeModePositioner>();
}
}
multiPositionArrayProperty.arraySize = 0;
return true;
}
#endif
#endregion
}
#endif // #if !(UNITY_QNX) // Disable under unsupported platforms.
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d8f7c2e3a1433a142b688e469bcd2de5
@@ -0,0 +1,59 @@
#if !(UNITY_QNX) // Disable under unsupported platforms.
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
/// @brief Use this component to add a Large Mode position to any AkAmbient in a Scene.
/// \sa
/// - \ref unity_use_AkEvent_AkAmbient
/// - \ref AkAmbient
public class AkAmbientLargeModePositioner : UnityEngine.MonoBehaviour
{
public UnityEngine.Vector3 Position
{
get
{
return transform.position;
}
}
public UnityEngine.Vector3 Forward
{
get
{
return transform.forward;
}
}
public UnityEngine.Vector3 Up
{
get
{
return transform.up;
}
}
#if UNITY_EDITOR
void OnDrawGizmosSelected()
{
UnityEngine.Gizmos.color = UnityEngine.Color.green;
UnityEngine.Gizmos.DrawSphere(transform.position, 0.1f);
UnityEditor.Handles.Label(transform.position, name);
}
#endif
}
#endif // #if !(UNITY_QNX) // Disable under unsupported platforms.
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 678fdbf1414b898409c98bf8497cdb8f
@@ -0,0 +1,286 @@
#if !(UNITY_QNX) // Disable under unsupported platforms.
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
using AK.Wwise.Unity.Logging;
[UnityEngine.AddComponentMenu("Wwise/AkAudioListener")]
[UnityEngine.RequireComponent(typeof(AkGameObj))]
[UnityEngine.DisallowMultipleComponent]
[UnityEngine.DefaultExecutionOrder(-50)]
///@brief Add this script on the game object that represent a listener. This is normally added to the Camera object or the Player object, but can be added to any game object when implementing 3D busses. \c isDefaultListener determines whether the game object will be considered a default listener - a listener that automatically listens to all game objects that do not have listeners attached to their AkGameObjListenerList's.
/// \sa
/// - <a href="https://www.audiokinetic.com/library/edge/?source=SDK&id=soundengine__listeners.html" target="_blank">Integrating Listeners</a> (Note: This is described in the Wwise SDK documentation.)
public class AkAudioListener : UnityEngine.MonoBehaviour
{
private static readonly DefaultListenerList defaultListeners = new DefaultListenerList();
private ulong akGameObjectID = AkUnitySoundEngine.AK_INVALID_GAME_OBJECT;
private System.Collections.Generic.List<AkGameObj> EmittersToStartListeningTo =
new System.Collections.Generic.List<AkGameObj>();
private System.Collections.Generic.List<AkGameObj> EmittersToStopListeningTo =
new System.Collections.Generic.List<AkGameObj>();
public bool isDefaultListener = true;
[UnityEngine.SerializeField]
public bool bOverrideScalingFactor = false;
[UnityEngine.SerializeField]
private float scalingFactor = -1f;
public float ScalingFactor
{
get
{
if (bOverrideScalingFactor)
{
return scalingFactor;
}
var settings = AkWwiseInitializationSettings.Instance;
if (settings)
{
return settings.UserSettings.m_DefaultListenerScalingFactor;
}
return 1.0f;
}
set
{
if (value < 0)
{
scalingFactor = 0;
}
else
{
scalingFactor = value;
}
}
}
public static DefaultListenerList DefaultListeners
{
get { return defaultListeners; }
}
public void StartListeningToEmitter(AkGameObj emitter)
{
EmittersToStartListeningTo.Add(emitter);
EmittersToStopListeningTo.Remove(emitter);
}
public void StopListeningToEmitter(AkGameObj emitter)
{
EmittersToStartListeningTo.Remove(emitter);
EmittersToStopListeningTo.Add(emitter);
}
public void SetIsDefaultListener(bool isDefault)
{
if (isDefaultListener != isDefault)
{
isDefaultListener = isDefault;
if (isDefault)
{
DefaultListeners.Add(this);
}
else
{
DefaultListeners.Remove(this);
}
}
}
private void Awake()
{
var akGameObj = GetComponent<AkGameObj>();
UnityEngine.Debug.Assert(akGameObj != null);
if (akGameObj)
{
akGameObj.Register();
}
akGameObjectID = AkUnitySoundEngine.GetAkGameObjectID(gameObject);
}
private void OnEnable()
{
if (isDefaultListener)
{
DefaultListeners.Add(this);
}
if (scalingFactor < 0f)
{
var initializer = AkInitializer.GetAkInitializerGameObject();
if (initializer)
{
scalingFactor = initializer.GetComponent<AkInitializer>().InitializationSettings.UserSettings.m_DefaultListenerScalingFactor;
}
else
{
scalingFactor = 1f;
}
}
var akGameObj = GetComponent<AkGameObj>();
if (akGameObj && gameObject.activeInHierarchy)
{
AkUnitySoundEngine.SetScalingFactor(gameObject, ScalingFactor);
}
}
private void OnDisable()
{
if (isDefaultListener)
{
DefaultListeners.Remove(this);
}
}
private void OnDestroy()
{
AkUnitySoundEngine.UnregisterGameObj(gameObject);
}
private void Update()
{
for (var i = 0; i < EmittersToStartListeningTo.Count; ++i)
{
EmittersToStartListeningTo[i].AddListener(this);
}
EmittersToStartListeningTo.Clear();
for (var i = 0; i < EmittersToStopListeningTo.Count; ++i)
{
EmittersToStopListeningTo[i].RemoveListener(this);
}
EmittersToStopListeningTo.Clear();
}
public ulong GetAkGameObjectID()
{
return akGameObjectID;
}
public class BaseListenerList
{
// @todo: Use HashSet<ulong> and CopyTo() with a private ulong[]
private readonly System.Collections.Generic.List<ulong> listenerIdList = new System.Collections.Generic.List<ulong>();
private readonly System.Collections.Generic.List<AkAudioListener> listenerList =
new System.Collections.Generic.List<AkAudioListener>();
public System.Collections.Generic.List<AkAudioListener> ListenerList
{
get { return listenerList; }
}
/// <summary>
/// Uniquely adds listeners to the list
/// </summary>
/// <param name="listener"></param>
/// <returns></returns>
public virtual bool Add(AkAudioListener listener)
{
if (listener == null)
{
return false;
}
var gameObjectId = listener.GetAkGameObjectID();
if (listenerIdList.Contains(gameObjectId))
{
return false;
}
listenerIdList.Add(gameObjectId);
listenerList.Add(listener);
return true;
}
/// <summary>
/// Removes listeners from the list
/// </summary>
/// <param name="listener"></param>
/// <returns></returns>
public virtual bool Remove(AkAudioListener listener)
{
if (listener == null)
{
return false;
}
var gameObjectId = listener.GetAkGameObjectID();
if (!listenerIdList.Remove(gameObjectId))
{
return false;
}
listenerList.Remove(listener);
return true;
}
public ulong[] GetListenerIds()
{
return listenerIdList.ToArray();
}
}
public class DefaultListenerList : BaseListenerList
{
public override bool Add(AkAudioListener listener)
{
var ret = base.Add(listener);
if (ret && AkUnitySoundEngine.IsInitialized())
{
AkUnitySoundEngine.AddDefaultListener(listener.gameObject);
}
return ret;
}
public override bool Remove(AkAudioListener listener)
{
var ret = base.Remove(listener);
if (ret && AkUnitySoundEngine.IsInitialized())
{
AkUnitySoundEngine.RemoveDefaultListener(listener.gameObject);
}
return ret;
}
}
#region WwiseMigration
#pragma warning disable 0414 // private field assigned but not used.
[UnityEngine.SerializeField]
// Wwise v2016.2 and below supported up to 8 listeners[0-7].
public int listenerId = 0;
#pragma warning restore 0414 // private field assigned but not used.
public void Migrate14()
{
var wasDefaultListener = listenerId == 0;
WwiseLogger.Log("AkAudioListener.Migrate14 for " + gameObject.name);
isDefaultListener = wasDefaultListener;
}
#endregion
}
#endif // #if !(UNITY_QNX) // Disable under unsupported platforms.
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a835ee92b0863c9459a0f816c5ff62ac
@@ -0,0 +1,189 @@
#if !(UNITY_QNX) // Disable under unsupported platforms.
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEngine.AddComponentMenu("Wwise/AkBank")]
[UnityEngine.ExecuteInEditMode]
[UnityEngine.DefaultExecutionOrder(-75)]
/// @brief Loads and unloads a SoundBank at a specified moment. Vorbis sounds can be decompressed at a specified moment using the decode compressed data option. In that case, the SoundBank will be prepared.
public class AkBank : AkTriggerHandler
#if UNITY_EDITOR
, AK.Wwise.IMigratable
#endif
{
public AK.Wwise.Bank data = new AK.Wwise.Bank();
/// DEPRECATED Decode this SoundBank upon load
public bool decodeBank = false;
public bool overrideLoadSetting = false;
/// Check this to load the SoundBank in the background. Be careful, if Events are triggered and the SoundBank hasn't finished loading, you'll have "Event not found" errors.
public bool loadAsynchronous = false;
/// DEPRECATED Save the decoded SoundBank to disk for faster loads in the future
public bool saveDecodedBank = false;
/// Reserved.
public System.Collections.Generic.List<int> unloadTriggerList =
new System.Collections.Generic.List<int> { DESTROY_TRIGGER_ID };
protected override void Awake()
{
#if UNITY_EDITOR
AkUnitySoundEngineInitialization.Instance.initializationDelegate += HandleEvent;
if (UnityEditor.BuildPipeline.isBuildingPlayer || AkUtilities.IsMigrating)
{
return;
}
var reference = AkWwiseTypes.DragAndDropObjectReference;
if (reference)
{
UnityEngine.GUIUtility.hotControl = 0;
data.ObjectReference = reference;
AkWwiseTypes.DragAndDropObjectReference = null;
}
#endif
base.Awake();
RegisterTriggers(unloadTriggerList, UnloadBank);
}
#if UNITY_EDITOR
public override void OnEnable()
{
if (UnityEditor.BuildPipeline.isBuildingPlayer)
{
return;
}
base.OnEnable();
}
#endif
protected override void Start()
{
#if UNITY_EDITOR
if (UnityEditor.BuildPipeline.isBuildingPlayer || AkUtilities.IsMigrating)
{
return;
}
if (!UnityEditor.EditorApplication.isPlaying)
{
HandleEvent();
}
#endif
base.Start();
//Call the UnloadBank function if registered to the Start Trigger
if (unloadTriggerList.Contains(START_TRIGGER_ID))
{
UnloadBank(null);
}
}
/// Loads the SoundBank
public override void HandleEvent(UnityEngine.GameObject in_gameObject)
{
bool asyncResult = loadAsynchronous;
if(!overrideLoadSetting)
{
asyncResult = AkWwiseInitializationSettings.ActivePlatformSettings.LoadBanksAsynchronously;
}
if (asyncResult)
{
data.LoadAsync();
}
else
{
data.Load(decodeBank, saveDecodedBank);
}
}
private void HandleEvent()
{
HandleEvent(gameObject);
}
/// Unloads a SoundBank
public void UnloadBank(UnityEngine.GameObject in_gameObject)
{
data.Unload();
}
protected override void OnDestroy()
{
#if UNITY_EDITOR
AkUnitySoundEngineInitialization.Instance.initializationDelegate -= HandleEvent;
if (UnityEditor.BuildPipeline.isBuildingPlayer || AkUtilities.IsMigrating)
{
return;
}
#endif
base.OnDestroy();
UnregisterTriggers(unloadTriggerList, UnloadBank);
}
#region Obsolete
[System.Obsolete(AkUnitySoundEngine.Deprecation_2018_1_6)]
public string bankName { get { return data == null ? string.Empty : data.Name; } }
[System.Obsolete(AkUnitySoundEngine.Deprecation_2018_1_6)]
public byte[] valueGuid
{
get
{
if (data == null)
return null;
var objRef = data.ObjectReference;
return !objRef ? null : objRef.Guid.ToByteArray();
}
}
#endregion
#region WwiseMigration
#pragma warning disable 0414 // private field assigned but not used.
[UnityEngine.HideInInspector]
[UnityEngine.SerializeField]
[UnityEngine.Serialization.FormerlySerializedAs("bankName")]
private string bankNameInternal;
[UnityEngine.HideInInspector]
[UnityEngine.SerializeField]
[UnityEngine.Serialization.FormerlySerializedAs("valueGuid")]
private byte[] valueGuidInternal;
#pragma warning restore 0414 // private field assigned but not used.
#if UNITY_EDITOR
bool AK.Wwise.IMigratable.Migrate(UnityEditor.SerializedObject obj)
{
if (!AkUtilities.IsMigrationRequired(AkUtilities.MigrationStep.WwiseTypes_v2018_1_6))
return false;
return AK.Wwise.TypeMigration.ProcessSingleGuidType(obj.FindProperty("data.WwiseObjectReference"), WwiseObjectType.Soundbank,
obj.FindProperty("valueGuidInternal"), obj.FindProperty("bankNameInternal"));
}
#endif
#endregion
}
#endif // #if !(UNITY_QNX) // Disable under unsupported platforms.
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 401f3889052f60e4dad8542d1fd7a96d
@@ -0,0 +1,60 @@
#if !(UNITY_QNX) // Disable under unsupported platforms.
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEngine.AddComponentMenu("Wwise/Spatial Audio/AkEarlyReflections")]
[UnityEngine.RequireComponent(typeof(AkGameObj))]
[UnityEngine.DisallowMultipleComponent]
///@brief Set an early reflections auxiliary bus and send volume for a particular game object.
public class AkEarlyReflections : UnityEngine.MonoBehaviour
{
[UnityEngine.Tooltip("The early reflections auxiliary bus for all sounds playing on this particular game object. The early reflection auxiliary bus specified in the authoring tool has precedence.")]
/// The early reflections auxiliary bus for this particular game object.
/// Geometrical reflection calculation inside spatial audio is enabled for a game object if any sound playing on the game object has a valid early reflections aux bus specified in the authoring tool,
/// or if an aux bus is specified via this parameter. The early reflection auxiliary bus specified in the authoring tool has precedence.
/// Users may apply this function to avoid duplicating sounds in the actor-mixer hierarchy solely for the sake of specifying a unique early reflection bus, or in any situation where the same
/// sound should be played on different game objects with different early reflection aux buses (the early reflection bus must be left blank in the authoring tool if the user intends to specify it through the API).
public AK.Wwise.AuxBus reflectionsAuxBus = new AK.Wwise.AuxBus();
[UnityEngine.Range(0, 1)]
[UnityEngine.Tooltip("The early reflections send volume for all sounds playing on this particular game object. It is combined with the early reflections volume specified in the authoring tool.")]
/// The early reflections send volume for this particular game object.
/// This parameter is used to control the volume of the early reflections send. It is combined with the early reflections volume specified in the authoring tool, and is applied to all sounds playing on the game object.
/// Setting to 0.f will disable all reflection processing for this game object. Valid range 0.f-1.f.
public float reflectionsVolume = 1;
private void OnEnable()
{
if (reflectionsAuxBus != null)
{
AkUnitySoundEngine.SetEarlyReflectionsAuxSend(gameObject, reflectionsAuxBus.Id);
}
AkUnitySoundEngine.SetEarlyReflectionsVolume(gameObject, reflectionsVolume);
}
public void SetEarlyReflectionsVolume(float volume)
{
if (reflectionsVolume != volume)
{
AkUnitySoundEngine.SetEarlyReflectionsVolume(gameObject, volume);
reflectionsVolume = volume;
}
}
}
#endif // #if !(UNITY_QNX) // Disable under unsupported platforms.
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 4ffbdddf1255a664fa019a1000a78287
@@ -0,0 +1,60 @@
#if !(UNITY_QNX) // Disable under unsupported platforms.
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEngine.AddComponentMenu("Wwise/AkEmitterObstructionOcclusion")]
[UnityEngine.RequireComponent(typeof(AkGameObj))]
/// @brief Completely obstructs/occludes the emitter of the current game object from its listeners if at least one object is between them.
public class AkEmitterObstructionOcclusion : AkObstructionOcclusion
{
private AkGameObj m_gameObj;
private void Awake()
{
InitIntervalsAndFadeRates();
m_gameObj = GetComponent<AkGameObj>();
}
protected override void UpdateCurrentListenerList()
{
if (AkSpatialAudioListener.TheSpatialAudioListener != null && AkRoom.RoomCount > 0)
{
currentListenerList.Add(AkSpatialAudioListener.TheSpatialAudioListener);
return;
}
if (m_gameObj.IsUsingDefaultListeners)
{
currentListenerList.AddRange(AkAudioListener.DefaultListeners.ListenerList);
}
currentListenerList.AddRange(m_gameObj.ListenerList);
}
protected override void SetObstructionOcclusion(
System.Collections.Generic.KeyValuePair<AkAudioListener, ObstructionOcclusionValue> ObsOccPair)
{
if (AkSpatialAudioListener.TheSpatialAudioListener != null && AkRoom.RoomCount > 0)
{
AkUnitySoundEngine.SetObjectObstructionAndOcclusion(gameObject, ObsOccPair.Key.gameObject, ObsOccPair.Value.currentValue, 0.0f);
}
else
{
AkUnitySoundEngine.SetObjectObstructionAndOcclusion(gameObject, ObsOccPair.Key.gameObject, 0.0f, ObsOccPair.Value.currentValue);
}
}
}
#endif // #if !(UNITY_QNX) // Disable under unsupported platforms.
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 2587568098810e748aba262930593206
@@ -0,0 +1,158 @@
#if !(UNITY_QNX) // Disable under unsupported platforms.
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[UnityEngine.AddComponentMenu("Wwise/AkEnvironment")]
[UnityEngine.ExecuteInEditMode]
[UnityEngine.RequireComponent(typeof(UnityEngine.Collider))]
/// @brief Use this component to define a reverb zone. This needs to be added to a collider object to work properly. See \ref unity_use_AkEnvironment_AkEnvironmentPortal.
/// @details This component can be attached to any collider. You can specify a roll-off to fade-in/out of the reverb.
/// The reverb parameters will be defined in the Wwise project, by the sound designer. All AkGameObj that are
/// "environment"-aware will receive a send value when entering the attached collider.
/// \sa
/// - \ref unity_use_AkEnvironment_AkEnvironmentPortal
/// - <a href="https://www.audiokinetic.com/library/edge/?source=SDK&id=integrating__elements__environments.html" target="_blank">Integrating Environments and Game-defined Auxiliary Sends</a> (Note: This is described in the Wwise SDK documentation.)
/// - <a href="https://www.audiokinetic.com/library/edge/?source=SDK&id=namespace_a_k_1_1_sound_engine_af960fca0239e219b9d08c2659fe9e5d4.html" target="_blank">AK::SoundEngine::SetGameObjectAuxSendValues</a> (Note: This is described in the Wwise SDK documentation.)
public class AkEnvironment : UnityEngine.MonoBehaviour
#if UNITY_EDITOR
, AK.Wwise.IMigratable
#endif
{
public const int MAX_NB_ENVIRONMENTS = 4;
public static AkEnvironment_CompareByPriority s_compareByPriority = new AkEnvironment_CompareByPriority();
public static AkEnvironment_CompareBySelectionAlgorithm s_compareBySelectionAlgorithm =
new AkEnvironment_CompareBySelectionAlgorithm();
//if excludeOthers, then only the environment with the excludeOthers flag set to true and with the highest priority will be active
public bool excludeOthers = false;
//if isDefault, then this environment will be bumped out if any other is present
public bool isDefault = false;
public AK.Wwise.AuxBus data = new AK.Wwise.AuxBus();
//Cache of the colliders for this environment, to avoid calls to GetComponent.
public UnityEngine.Collider Collider { get; private set; }
//smaller number has a higher priority
public int priority = 0;
public void Awake()
{
#if UNITY_EDITOR
var reference = AkWwiseTypes.DragAndDropObjectReference;
if (reference)
{
UnityEngine.GUIUtility.hotControl = 0;
data.ObjectReference = reference;
AkWwiseTypes.DragAndDropObjectReference = null;
}
#endif
Collider = GetComponent<UnityEngine.Collider>();
}
/// @brief Sorts AkEnvironments based on their priorities.
public class AkEnvironment_CompareByPriority : System.Collections.Generic.IComparer<AkEnvironment>
{
public virtual int Compare(AkEnvironment a, AkEnvironment b)
{
var result = a.priority.CompareTo(b.priority);
return result == 0 && a != b ? 1 : result;
}
}
/// @brief Sorts AkEnvironments based on the selection algorithm.
/// The selection algorithm is as follows:
/// -# Environments have priorities.
/// -# Environments have a "Default" flag. This flag effectively says that this environment will be bumped out if any other is present.
/// -# Environments have an "Exclude Other" flag. This flag will tell that this env is not overlappable with others. So, only one (the highest priority) should be selected.
public class AkEnvironment_CompareBySelectionAlgorithm : AkEnvironment_CompareByPriority
{
public override int Compare(AkEnvironment a, AkEnvironment b)
{
if (a.isDefault)
return b.isDefault ? base.Compare(a, b) : 1;
if (b.isDefault)
return -1;
if (a.excludeOthers)
return b.excludeOthers ? base.Compare(a, b) : -1;
return b.excludeOthers ? 1 : base.Compare(a, b);
}
}
#region Obsolete
[System.Obsolete(AkUnitySoundEngine.Deprecation_2018_1_2)]
public int m_auxBusID { get { return (int)(data == null ? AkUnitySoundEngine.AK_INVALID_UNIQUE_ID : data.Id); } }
[System.Obsolete(AkUnitySoundEngine.Deprecation_2018_1_6)]
public byte[] valueGuid
{
get
{
if (data == null)
return null;
var objRef = data.ObjectReference;
return !objRef ? null : objRef.Guid.ToByteArray();
}
}
[System.Obsolete(AkUnitySoundEngine.Deprecation_2018_1_2)]
public uint GetAuxBusID()
{
return data.Id;
}
[System.Obsolete(AkUnitySoundEngine.Deprecation_2018_1_6)]
public UnityEngine.Collider GetCollider()
{
return Collider;
}
#endregion
#region WwiseMigration
#pragma warning disable 0414 // private field assigned but not used.
[UnityEngine.HideInInspector]
[UnityEngine.SerializeField]
[UnityEngine.Serialization.FormerlySerializedAs("m_auxBusID")]
private int auxBusIdInternal = (int)AkUnitySoundEngine.AK_INVALID_UNIQUE_ID;
[UnityEngine.HideInInspector]
[UnityEngine.SerializeField]
[UnityEngine.Serialization.FormerlySerializedAs("valueGuid")]
private byte[] valueGuidInternal;
#pragma warning restore 0414 // private field assigned but not used.
#if UNITY_EDITOR
bool AK.Wwise.IMigratable.Migrate(UnityEditor.SerializedObject obj)
{
if (!AkUtilities.IsMigrationRequired(AkUtilities.MigrationStep.WwiseTypes_v2018_1_6))
return false;
return AK.Wwise.TypeMigration.ProcessSingleGuidType(obj.FindProperty("data.WwiseObjectReference"), WwiseObjectType.AuxBus,
obj.FindProperty("valueGuidInternal"), obj.FindProperty("auxBusIdInternal"));
}
#endif
#endregion
}
#endif // #if !(UNITY_QNX) // Disable under unsupported platforms.
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: cf838bd1abd0bcb41b145cbc06b3112f
@@ -0,0 +1,103 @@
#if !(UNITY_QNX) // Disable under unsupported platforms.
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
/// @brief Use this component to define an area that straddles two different AkEnvironment's zones and allow mixing between both zones. \ref unity_use_AkEnvironment_AkEnvironmentPortal
[UnityEngine.AddComponentMenu("Wwise/AkEnvironmentPortal")]
[UnityEngine.RequireComponent(typeof(UnityEngine.BoxCollider))]
public class AkEnvironmentPortal : UnityEngine.MonoBehaviour
{
public const int MAX_ENVIRONMENTS_PER_PORTAL = 2;
///The axis used to find the contribution of each environment
public UnityEngine.Vector3 axis = UnityEngine.Vector3.right;
///The array is already sorted by position.
///The first environment is on the negative side of the portal(opposite to the direction of the chosen axis)
///The second environment is on the positive side of the portal
public AkEnvironment[] environments = new AkEnvironment[MAX_ENVIRONMENTS_PER_PORTAL];
private UnityEngine.BoxCollider m_BoxCollider;
private UnityEngine.BoxCollider BoxCollider
{
get
{
if (!m_BoxCollider)
m_BoxCollider = GetComponent<UnityEngine.BoxCollider>();
return m_BoxCollider;
}
}
public bool EnvironmentsShareAuxBus
{
get
{
if (environments[0] == null)
return environments[1] == null;
if (environments[1] == null)
return false;
if (environments[0].data == null)
return environments[1].data == null;
if (environments[1].data == null)
return false;
return environments[0].data.Id == environments[1].data.Id;
}
}
public float GetAuxSendValueForPosition(UnityEngine.Vector3 in_position, int index)
{
//total length of the portal in the direction of axis
var portalLength = UnityEngine.Vector3.Dot(UnityEngine.Vector3.Scale(BoxCollider.size, transform.lossyScale), axis);
//transform axis to world coordinates
var axisWorld = UnityEngine.Vector3.Normalize(transform.rotation * axis);
//Get distance form left side of the portal(opposite to the direction of axis) to the game object in the direction of axisWorld
var dist = UnityEngine.Vector3.Dot(in_position - (transform.position - portalLength * 0.5f * axisWorld), axisWorld);
dist = UnityEngine.Mathf.Clamp(dist, 0, portalLength);
//calculate value of the environment referred by index
if (index == 0)
return (portalLength - dist) * (portalLength - dist) / (portalLength * portalLength);
return dist * dist / (portalLength * portalLength);
}
#if UNITY_EDITOR
/// This enables us to detect intersections between portals and environments in the editor
[System.Serializable]
public class EnvListWrapper
{
public System.Collections.Generic.List<AkEnvironment> list = new System.Collections.Generic.List<AkEnvironment>();
}
/// Unity can't serialize an array of list so we wrap the list in a serializable class
public EnvListWrapper[] envList =
{
new EnvListWrapper(), //All environments on the negative side of each portal(opposite to the direction of the chosen axis)
new EnvListWrapper() //All environments on the positive side of each portal(same direction as the chosen axis)
};
#endif
}
#endif // #if !(UNITY_QNX) // Disable under unsupported platforms.
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 4efdb117a2234b74fbdc4a34171a1a11
@@ -0,0 +1,270 @@
#if !(UNITY_QNX) // Disable under unsupported platforms.
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
using AK.Wwise.Unity.Logging;
/// <summary>
/// Event callback information.
/// Event callback functions can receive this structure as a parameter
/// </summary>
public class AkEventCallbackMsg
{
///For more information about the event callback, see the classes derived from AkCallbackInfo.
public AkCallbackInfo info;
/// GameObject from whom the callback function was called
public UnityEngine.GameObject sender;
///AkUnitySoundEngine.PostEvent callback flags. See the AkCallbackType enumeration for a list of all callbacks
public AkCallbackType type;
}
[UnityEngine.AddComponentMenu("Wwise/AkEvent")]
[UnityEngine.ExecuteInEditMode]
[UnityEngine.RequireComponent(typeof(AkGameObj))]
/// @brief Helper class that knows a Wwise Event and when to trigger it in Unity. As of 2017.2.0, the AkEvent inspector has buttons for play/stop, play multiple, stop multiple, and stop all.
/// Play/Stop will play or stop the event such that it can be previewed both in edit mode and play mode. When multiple objects are selected, Play Multiple and Stop Multiple will play or stop the associated AkEvent for each object.
/// \sa
/// - \ref sect_edit_mode
/// - \ref unity_use_AkEvent_AkAmbient
/// - <a href="https://www.audiokinetic.com/library/edge/?source=SDK&id=soundengine__events.html" target="_blank">Integration Details - Events</a> (Note: This is described in the Wwise SDK documentation.)
public class AkEvent : AkDragDropTriggerHandler
#if UNITY_EDITOR
, AK.Wwise.IMigratable
#endif
{
/// Replacement action. See AK::SoundEngine::ExecuteEventOnAction()
public AkActionOnEventType actionOnEventType = AkActionOnEventType.AkActionOnEventType_Stop;
/// Fade curve to use with the new Action. See AK::SoundEngine::ExecuteEventOnAction()
public AkCurveInterpolation curveInterpolation = AkCurveInterpolation.AkCurveInterpolation_Linear;
/// Enables additional options to reuse existing events. Use it to transform a Play event into a Stop event without having to define one in the Wwise Project.
public bool enableActionOnEvent = false;
public AK.Wwise.Event data = new AK.Wwise.Event();
protected override AK.Wwise.BaseType WwiseType { get { return data; } }
[System.Serializable]
public class CallbackData
{
public AK.Wwise.CallbackFlags Flags;
public string FunctionName;
public UnityEngine.GameObject GameObject;
public void CallFunction(AkEventCallbackMsg eventCallbackMsg)
{
if (((uint)eventCallbackMsg.type & Flags.value) != 0 && GameObject)
GameObject.SendMessage(FunctionName, eventCallbackMsg);
}
}
private UnityEngine.GameObject otherGameObject;
public bool useCallbacks = false;
public bool stopSoundOnDestroy = true;
public System.Collections.Generic.List<CallbackData> Callbacks = new System.Collections.Generic.List<CallbackData>();
public uint playingId => data.PlayingId;
/// Game object onto which the Event will be posted. By default, when empty, it is posted on the same object on which the component was added.
public UnityEngine.GameObject soundEmitterObject;
/// Duration of the fade, in milliseconds. See <a href="https://www.audiokinetic.com/library/edge/?source=SDK&id=namespace_a_k_1_1_sound_engine_ac55e3d6ac464b0579a8487c88a755d8c.html" target="_blank">AK::SoundEngine::ExecuteEventOnAction()</a>.
public float transitionDuration = 0.0f;
private AkEventCallbackMsg EventCallbackMsg = null;
protected override void Awake()
{
base.Awake();
#if UNITY_EDITOR
var reference = AkWwiseTypes.DragAndDropObjectReference;
if (reference)
{
UnityEngine.GUIUtility.hotControl = 0;
data.ObjectReference = reference;
AkWwiseTypes.DragAndDropObjectReference = null;
}
#endif
}
protected override void Start()
{
#if UNITY_EDITOR
if (UnityEditor.BuildPipeline.isBuildingPlayer || AkUtilities.IsMigrating || !UnityEditor.EditorApplication.isPlaying)
return;
#endif
if (useCallbacks)
{
EventCallbackMsg = new AkEventCallbackMsg { sender = gameObject };
}
soundEmitterObject = gameObject;
base.Start();
}
private void Callback(object in_cookie, AkCallbackType in_type, AkCallbackInfo in_info)
{
EventCallbackMsg.type = in_type;
EventCallbackMsg.info = in_info;
for (var i = 0; i < Callbacks.Count; ++i)
{
Callbacks[i].CallFunction(EventCallbackMsg);
}
}
public override void HandleEvent(UnityEngine.GameObject in_gameObject)
{
var gameObj = useOtherObject && in_gameObject != null ? in_gameObject : gameObject;
soundEmitterObject = gameObj;
if (useOtherObject)
{
otherGameObject = in_gameObject;
}
if (enableActionOnEvent)
{
data.ExecuteAction(gameObj, actionOnEventType, (int)transitionDuration * 1000, curveInterpolation);
return;
}
if (useCallbacks)
{
uint flags = 0;
for (var i = 0; i < Callbacks.Count; ++i)
{
if (Callbacks[i].GameObject)
{
flags |= Callbacks[i].Flags.value;
}
}
if (flags != 0)
{
data.Post(gameObj, flags, Callback);
return;
}
}
data.Post(gameObj);
}
protected void OnDisable()
{
var akGameObj = gameObject.GetComponent<AkGameObj>();
if (stopSoundOnDestroy && akGameObj != null && akGameObj.GameObjIsRegistered())
{
var gameObj = useOtherObject && otherGameObject != null ? otherGameObject : gameObject;
data.ExecuteAction(gameObj, AkActionOnEventType.AkActionOnEventType_Stop, (int)transitionDuration * 1000, curveInterpolation);
}
}
public void Stop(int _transitionDuration)
{
Stop(_transitionDuration, AkCurveInterpolation.AkCurveInterpolation_Linear);
}
public void Stop(int _transitionDuration, AkCurveInterpolation _curveInterpolation)
{
data.Stop(soundEmitterObject ? soundEmitterObject : gameObject, _transitionDuration, _curveInterpolation);
}
#region Obsolete
[System.Obsolete(AkUnitySoundEngine.Deprecation_2018_1_2)]
public int eventID { get { return (int)(data == null ? AkUnitySoundEngine.AK_INVALID_UNIQUE_ID : data.Id); } }
[System.Obsolete(AkUnitySoundEngine.Deprecation_2018_1_6)]
public byte[] valueGuid
{
get
{
if (data == null)
return null;
var objRef = data.ObjectReference;
return !objRef ? null : objRef.Guid.ToByteArray();
}
}
[System.Obsolete(AkUnitySoundEngine.Deprecation_2018_1_6)]
public AkEventCallbackData m_callbackData { get { return m_callbackDataInternal; } }
#endregion
#region WwiseMigration
#pragma warning disable 0414 // private field assigned but not used.
[UnityEngine.HideInInspector]
[UnityEngine.SerializeField]
[UnityEngine.Serialization.FormerlySerializedAs("eventID")]
private int eventIdInternal = (int)AkUnitySoundEngine.AK_INVALID_UNIQUE_ID;
[UnityEngine.HideInInspector]
[UnityEngine.SerializeField]
[UnityEngine.Serialization.FormerlySerializedAs("valueGuid")]
private byte[] valueGuidInternal;
[UnityEngine.HideInInspector]
[UnityEngine.SerializeField]
[UnityEngine.Serialization.FormerlySerializedAs("m_callbackData")]
private AkEventCallbackData m_callbackDataInternal = null;
#pragma warning restore 0414 // private field assigned but not used.
#if UNITY_EDITOR
public virtual bool Migrate(UnityEditor.SerializedObject obj)
{
var hasMigrated = false;
if (AkUtilities.IsMigrationRequired(AkUtilities.MigrationStep.WwiseTypes_v2018_1_6))
{
hasMigrated = AK.Wwise.TypeMigration.ProcessSingleGuidType(obj.FindProperty("data.WwiseObjectReference"), WwiseObjectType.Event,
obj.FindProperty("valueGuidInternal"), obj.FindProperty("eventIdInternal"));
}
if (!AkUtilities.IsMigrationRequired(AkUtilities.MigrationStep.AkEventCallback_v2018_1_6))
return hasMigrated;
var oldCallbackDataProperty = obj.FindProperty("m_callbackDataInternal");
var oldCallbackData = oldCallbackDataProperty.objectReferenceValue as AkEventCallbackData;
if (!oldCallbackData)
return hasMigrated;
var count = oldCallbackData.callbackFlags.Count;
if (count != oldCallbackData.callbackFunc.Count || count != oldCallbackData.callbackGameObj.Count)
{
WwiseLogger.Warning("Inconsistent callback data!");
return hasMigrated;
}
var newCallbackData = obj.FindProperty("Callbacks");
newCallbackData.arraySize = count;
obj.FindProperty("useCallbacks").boolValue = true;
for (var i = 0; i < count; ++i)
{
var data = newCallbackData.GetArrayElementAtIndex(i);
data.FindPropertyRelative("GameObject").objectReferenceValue = oldCallbackData.callbackGameObj[i];
data.FindPropertyRelative("FunctionName").stringValue = oldCallbackData.callbackFunc[i];
data.FindPropertyRelative("Flags.value").intValue = oldCallbackData.callbackFlags[i];
WwiseLogger.Log("Migrated Callback for function \"" + oldCallbackData.callbackFunc[i] + "\" on <" + oldCallbackData.callbackGameObj[i] + "> with flags <" + (AkCallbackType)oldCallbackData.callbackFlags[i] + ">.");
}
return true;
}
#endif
#endregion
}
#endif // #if !(UNITY_QNX) // Disable under unsupported platforms.
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: eec618f338d13bf43b8519814d335311
@@ -0,0 +1,35 @@
#if !(UNITY_QNX) // Disable under unsupported platforms.
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
public class AkEventCallbackData : UnityEngine.ScriptableObject
{
////AkUnitySoundEngine.PostEvent callback flags. See the AkCallbackType enumeration for a list of all callbacks
public System.Collections.Generic.List<int> callbackFlags = new System.Collections.Generic.List<int>();
////Names of the callback functions.
public System.Collections.Generic.List<string> callbackFunc = new System.Collections.Generic.List<string>();
////GameObject that will receive the callback
public System.Collections.Generic.List<UnityEngine.GameObject> callbackGameObj =
new System.Collections.Generic.List<UnityEngine.GameObject>();
////The sum of the flags of all game objects. This is the flag that will be passed to AkUnitySoundEngine.PostEvent
public int uFlags = 0;
}
#endif // #if !(UNITY_QNX) // Disable under unsupported platforms.
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 2b86bc90937438846b772e3f72ff18c9
@@ -0,0 +1,531 @@
#if !(UNITY_QNX) // Disable under unsupported platforms.
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
using UnityEngine;
using AK.Wwise.Unity.Logging;
[UnityEngine.AddComponentMenu("Wwise/AkGameObj")]
[UnityEngine.DisallowMultipleComponent]
[UnityEngine.ExecuteInEditMode] //ExecuteInEditMode necessary to maintain proper state of isStaticObject.
[UnityEngine.DefaultExecutionOrder(-25)]
///@brief This component represents a sound object in your scene and tracks its position and other game syncs such as Switches, RTPCs, and environment values. You can add this to any object that emits sound, and it is added to any object to which an AkAudioListener is attached. If it is not present, Wwise adds it automatically, with the default values, to any Unity Game Object that is passed to Wwise.
/// \sa
/// - <a href="https://www.audiokinetic.com/library/edge/?source=SDK&id=soundengine__gameobj.html" target="_blank">Integration Details - Game Objects</a> (SDK documentation)
/// - <a href="https://www.audiokinetic.com/library/edge/?source=SDK&id=soundengine__events.html" target="_blank">Integration Details - Events</a> (SDK documentation)
/// - <a href="https://www.audiokinetic.com/library/edge/?source=SDK&id=soundengine__listeners.html" target="_blank">Integrating Listeners</a> (SDK documentation)
/// - <a href="https://www.audiokinetic.com/library/edge/?source=SDK&id=soundengine__switch.html" target="_blank">Integration Details - Switches</a> (SDK documentation)
/// - <a href="https://www.audiokinetic.com/library/edge/?source=SDK&id=soundengine__states.html" target="_blank">Integration Details - States</a> (SDK documentation)
/// - <a href="https://www.audiokinetic.com/library/edge/?source=SDK&id=soundengine__environments.html" target="_blank">Integration Details - Environments and Game-defined Auxiliary Sends</a> (SDK documentation)
public class AkGameObj : UnityEngine.MonoBehaviour
{
[UnityEngine.SerializeField] private AkGameObjListenerList m_listeners = new AkGameObjListenerList();
/// Indicates whether the object is affected by environmental changes. Set to false if the object is not affected in order to save some unnecessary calls. The default value is true.
public bool isEnvironmentAware = true;
/// Maintains and persists the Static setting of the game object, which is available only in the editor.
[UnityEngine.SerializeField] private bool isStaticObject = false;
/// Cache the bounds to avoid calls to GetComponent()
private UnityEngine.Collider m_Collider;
private AkGameObjEnvironmentData m_envData;
private AkGameObjPositionData m_posData;
public bool usePositionOffsetData;
/// When not set to null, the position is offset relative to the Game Object position by the Position Offset
public AkGameObjPositionOffsetData m_positionOffsetData;
[UnityEngine.SerializeField]
private float scalingFactor = 1f;
public float ScalingFactor
{
get => scalingFactor;
set
{
if (value > 0)
{
scalingFactor = value;
if (gameObject.activeInHierarchy)
{
AkUnitySoundEngine.SetScalingFactor(gameObject, scalingFactor);
}
}
else
{
WwiseLogger.Error("Scaling Factor needs to be a positive value greater than 0.");
}
}
}
public bool IsUsingDefaultListeners
{
get { return m_listeners.useDefaultListeners; }
}
public System.Collections.Generic.List<AkAudioListener> ListenerList
{
get { return m_listeners.ListenerList; }
}
private bool isRegistered = false;
public bool GameObjIsRegistered()
{
return isRegistered;
}
internal void AddListener(AkAudioListener listener)
{
m_listeners.Add(listener);
}
internal void RemoveListener(AkAudioListener listener)
{
m_listeners.Remove(listener);
}
public AKRESULT Register()
{
if (isRegistered)
{
return AKRESULT.AK_Success;
}
isRegistered = true;
return AkUnitySoundEngine.RegisterGameObj(gameObject, gameObject.name);
}
private void UnregisterGameObject()
{
if (AkUnitySoundEngine.IsInitialized())
{
Unregister();
}
}
public AKRESULT Unregister()
{
if (!isRegistered)
{
return AKRESULT.AK_Success;
}
isRegistered = false;
m_posData = null;
return AkUnitySoundEngine.UnregisterGameObj(gameObject);
}
private void SetPosition()
{
var position = GetPosition();
var forward = GetForward();
var up = GetUpward();
if (m_posData != null)
{
if (m_posData.position == position && m_posData.forward == forward && m_posData.up == up)
{
return;
}
m_posData.position = position;
m_posData.forward = forward;
m_posData.up = up;
}
AkUnitySoundEngine.SetObjectPosition(gameObject, position, forward, up);
}
private void Awake()
{
#if UNITY_EDITOR
if (AkUtilities.IsMigrating)
{
return;
}
if (!UnityEditor.EditorApplication.isPlaying)
{
UnityEditor.EditorApplication.update += CheckStaticStatus;
}
AkUnitySoundEngineInitialization.Instance.initializationDelegate += RegisterGameObject;
AkUnitySoundEngineInitialization.Instance.terminationDelegate += UnregisterGameObject;
#endif
// If the object was marked as static, don't update its position to save cycles.
if (!isStaticObject)
{
m_posData = new AkGameObjPositionData();
}
// Cache the bounds to avoid calls to GetComponent()
m_Collider = GetComponent<UnityEngine.Collider>();
}
private void RegisterGameObject()
{
if (!AkUnitySoundEngine.IsInitialized())
{
return;
}
//Register a Game Object in the sound engine, with its name.
if (Register() == AKRESULT.AK_Success)
{
SetPosition();
if (isEnvironmentAware)
{
m_envData = new AkGameObjEnvironmentData();
if (m_Collider)
{
m_envData.AddAkEnvironment(m_Collider, m_Collider);
}
m_envData.UpdateAuxSend(gameObject, transform.position);
}
m_listeners.Init(this);
//The Listener will win for the scaling factor
if (gameObject.GetComponent<AkAudioListener>() == null && gameObject.activeInHierarchy)
{
AkUnitySoundEngine.SetScalingFactor(gameObject, ScalingFactor);
}
}
}
private void CheckStaticStatus()
{
#if UNITY_EDITOR
if (AkUtilities.IsMigrating)
{
return;
}
try
{
if (gameObject != null && isStaticObject != gameObject.isStatic)
{
isStaticObject = gameObject.isStatic;
UnityEditor.EditorUtility.SetDirty(this);
}
}
catch
{
UnityEditor.EditorApplication.update -= CheckStaticStatus;
}
#endif
}
private void OnEnable()
{
#if UNITY_EDITOR
if (AkUtilities.IsMigrating)
{
return;
}
#endif
RegisterGameObject();
}
#if UNITY_EDITOR
private void OnDisable()
{
if (!AkUnitySoundEngineInitialization.Instance.ShouldKeepSoundEngineEnabled())
{
Unregister();
}
}
#endif
private void OnDestroy()
{
#if UNITY_EDITOR
if (AkUtilities.IsMigrating)
{
return;
}
if (!UnityEditor.EditorApplication.isPlaying)
{
UnityEditor.EditorApplication.update -= CheckStaticStatus;
}
AkUnitySoundEngineInitialization.Instance.initializationDelegate -= RegisterGameObject;
AkUnitySoundEngineInitialization.Instance.terminationDelegate -= UnregisterGameObject;
#endif
// We can't do the code in OnDestroy if the gameObj is unregistered, so do it now.
var eventHandlers = gameObject.GetComponents<AkTriggerHandler>();
foreach (var handler in eventHandlers)
{
if (handler.triggerList.Contains(AkTriggerHandler.DESTROY_TRIGGER_ID))
{
handler.DoDestroy();
}
}
if (AkUnitySoundEngine.IsInitialized())
{
Unregister();
}
}
private void Update()
{
#if UNITY_EDITOR
if (AkUtilities.IsMigrating || !UnityEditor.EditorApplication.isPlaying)
{
return;
}
#endif
if (!isStaticObject)
{
if (m_envData != null)
{
m_envData.UpdateAuxSend(gameObject, transform.position);
}
SetPosition();
}
}
/// Gets the position including the position offset, if applyPositionOffset is enabled. User can also override this method to calculate an arbitrary position.
/// \return The position.
public virtual UnityEngine.Vector3 GetPosition()
{
if (!usePositionOffsetData)
{
return transform.position;
}
var worldOffset = transform.rotation * m_positionOffsetData.positionOffset;
return transform.position + worldOffset;
}
/// Gets the orientation forward vector. User can also override this method to calculate an arbitrary vector.
/// \return The forward vector of orientation.
public virtual UnityEngine.Vector3 GetForward()
{
return transform.forward;
}
/// Gets the orientation upward vector. User can also override this method to calculate an arbitrary vector.
/// \return The upward vector of orientation.
public virtual UnityEngine.Vector3 GetUpward()
{
return transform.up;
}
private void OnTriggerEnter(UnityEngine.Collider other)
{
#if UNITY_EDITOR
if (AkUtilities.IsMigrating || !UnityEditor.EditorApplication.isPlaying)
{
return;
}
#endif
if (isEnvironmentAware && m_envData != null)
{
m_envData.AddAkEnvironment(other, m_Collider);
}
}
private void OnTriggerExit(UnityEngine.Collider other)
{
#if UNITY_EDITOR
if (AkUtilities.IsMigrating || !UnityEditor.EditorApplication.isPlaying)
{
return;
}
#endif
if (isEnvironmentAware && m_envData != null)
{
m_envData.RemoveAkEnvironment(other, m_Collider);
}
}
#if UNITY_EDITOR
public void OnDrawGizmosSelected()
{
if (AkUtilities.IsMigrating)
{
return;
}
var position = GetPosition();
UnityEngine.Gizmos.DrawIcon(position, "WwiseAudioSpeaker.png", false);
}
#endif
#region WwiseMigration
#pragma warning disable 0414 // private field assigned but not used.
[UnityEngine.HideInInspector]
[UnityEngine.SerializeField]
private AkGameObjPosOffsetData m_posOffsetData;
// Wwise v2016.2 and below supported up to 8 listeners[0-7].
private const int AK_NUM_LISTENERS = 8;
[UnityEngine.HideInInspector]
[UnityEngine.SerializeField]
/// Listener 0 by default.
private int listenerMask = 1;
#pragma warning restore 0414 // private field assigned but not used.
#if UNITY_EDITOR
public void Migrate9()
{
WwiseLogger.Log("AkGameObj.Migrate9 for " + gameObject.name);
const int ALL_LISTENER_MASK = (1 << AK_NUM_LISTENERS) - 1;
if ((listenerMask & ALL_LISTENER_MASK) == ALL_LISTENER_MASK)
listenerMask = 1;
}
public void Migrate10()
{
WwiseLogger.Log("AkGameObj.Migrate10 for " + gameObject.name);
if (m_posOffsetData != null)
{
m_positionOffsetData = new AkGameObjPositionOffsetData(true);
m_positionOffsetData.positionOffset = m_posOffsetData.positionOffset;
m_posOffsetData = null;
}
}
private class Migration14Data
{
private readonly System.Collections.Generic.List<AkAudioListener>[] listeners =
new System.Collections.Generic.List<AkAudioListener>[AK_NUM_LISTENERS];
public Migration14Data()
{
var fullSceneListenerMask = 0;
// Get all AkAudioListeners in the scene.
#if UNITY_6000_0_OR_NEWER
var listenerObjects = FindObjectsByType<AkAudioListener>(FindObjectsSortMode.None);
#else
var listenerObjects = FindObjectsOfType<AkAudioListener>();
#endif
foreach (var listener in listenerObjects)
{
// Add AkGameObj to AkAudioListeners
if (listener.GetComponent<AkGameObj>() == null)
{
var akGameObj = listener.gameObject.AddComponent<AkGameObj>();
if (akGameObj)
{
akGameObj.isEnvironmentAware = false;
WwiseLogger.Log("Added AkGameObj to <" + listener.gameObject.name + ">.");
}
else
WwiseLogger.Error("Failed to add AkGameObj to <" + listener.gameObject.name + ">.");
}
var listenerId = listener.listenerId;
if (listenerId >= 0 && listenerId < AK_NUM_LISTENERS)
{
if (listeners[listenerId] == null)
listeners[listenerId] = new System.Collections.Generic.List<AkAudioListener>();
listeners[listenerId].Add(listener);
fullSceneListenerMask |= 1 << listenerId;
}
else
WwiseLogger.Error("Invalid listenerId <" + listenerId + "> found during migration.");
}
if (fullSceneListenerMask == 0)
{
WwiseLogger.Warning("Listeners were not added via components within this Scene.");
listeners = null;
}
else
{
for (var ii = 0; ii < AK_NUM_LISTENERS; ++ii)
{
if (listeners[ii] != null && listeners[ii].Count > 1)
{
WwiseLogger.Warning("Multiple listeners <" + listeners[ii].Count +
"> with same listenerId <" + ii + "> found during migration.");
}
}
if (fullSceneListenerMask == 1)
{
WwiseLogger.Log("Default listeners will be used for this Scene.");
listeners = null;
}
}
}
public void Migrate(AkGameObj akGameObj)
{
if (listeners != null)
{
for (var ii = 0; ii < AK_NUM_LISTENERS; ++ii)
{
var idMask = 1 << ii;
if ((akGameObj.listenerMask & idMask) != 0 && listeners[ii] != null)
{
foreach (var listener in listeners[ii])
akGameObj.m_listeners.AddToInitialListenerList(listener);
}
}
}
}
}
private static Migration14Data migration14data;
public static void PreMigration14()
{
migration14data = new Migration14Data();
}
public void Migrate14()
{
WwiseLogger.Log("AkGameObj.Migrate14 for " + gameObject.name);
if (migration14data != null)
migration14data.Migrate(this);
}
public static void PostMigration14()
{
migration14data = null;
}
#endif
#endregion
}
#endif // #if !(UNITY_QNX) // Disable under unsupported platforms.
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 4ccb80e2899444642bdbf406a3c31f7b
@@ -0,0 +1,203 @@
#if !(UNITY_QNX) // Disable under unsupported platforms.
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
public class AkGameObjEnvironmentData
{
/// Contains all active environments sorted by default, excludeOthers and priority, even those inside a portal.
private readonly System.Collections.Generic.List<AkEnvironment> activeEnvironments =
new System.Collections.Generic.List<AkEnvironment>();
/// Contains all active environments sorted by priority, even those inside a portal.
private readonly System.Collections.Generic.List<AkEnvironment> activeEnvironmentsFromPortals =
new System.Collections.Generic.List<AkEnvironment>();
/// Contains all active portals.
private readonly System.Collections.Generic.List<AkEnvironmentPortal> activePortals =
new System.Collections.Generic.List<AkEnvironmentPortal>();
private readonly AkAuxSendArray auxSendValues = new AkAuxSendArray();
private UnityEngine.Vector3 lastPosition = UnityEngine.Vector3.zero;
private bool hasEnvironmentListChanged = true;
private bool hasActivePortalListChanged = true;
private bool hasSentZero = false;
private void AddHighestPriorityEnvironmentsFromPortals(UnityEngine.Vector3 position)
{
for (var i = 0; i < activePortals.Count; i++)
{
var portal = activePortals[i];
if (portal.EnvironmentsShareAuxBus)
{
var env = portal.environments[0];
if (env == null)
continue;
var index = activeEnvironmentsFromPortals.BinarySearch(env, AkEnvironment.s_compareByPriority);
if (index < 0 || index >= AkEnvironment.MAX_NB_ENVIRONMENTS)
continue;
var auxBusID = env.data.Id;
if (!auxSendValues.Contains(auxBusID))
{
auxSendValues.Add(auxBusID, 1.0f);
if (auxSendValues.isFull)
return;
}
continue;
}
for (var j = 0; j < AkEnvironmentPortal.MAX_ENVIRONMENTS_PER_PORTAL; j++)
{
var env = portal.environments[j];
if (env == null)
continue;
var index = activeEnvironmentsFromPortals.BinarySearch(env, AkEnvironment.s_compareByPriority);
if (index < 0 || index >= AkEnvironment.MAX_NB_ENVIRONMENTS)
continue;
var auxBusID = env.data.Id;
if (!auxSendValues.Contains(auxBusID))
{
auxSendValues.Add(auxBusID, portal.GetAuxSendValueForPosition(position, j));
if (auxSendValues.isFull)
return;
}
}
}
}
private void AddHighestPriorityEnvironments(UnityEngine.Vector3 position)
{
if (!auxSendValues.isFull && auxSendValues.Count() < activeEnvironments.Count)
{
for (var i = 0; i < activeEnvironments.Count; i++)
{
var env = activeEnvironments[i];
var auxBusID = env.data.Id;
if ((!env.isDefault || i == 0) && !auxSendValues.Contains(auxBusID))
{
auxSendValues.Add(auxBusID, 1.0f);
//No other environment can be added after an environment with the excludeOthers flag set to true
if (env.excludeOthers || auxSendValues.isFull)
break;
}
}
}
}
public void UpdateAuxSend(UnityEngine.GameObject gameObject, UnityEngine.Vector3 position)
{
if (!hasEnvironmentListChanged && !hasActivePortalListChanged && lastPosition == position)
return;
auxSendValues.Reset();
AddHighestPriorityEnvironmentsFromPortals(position);
AddHighestPriorityEnvironments(position);
bool isSendingZero = auxSendValues.Count() == 0;
if (!hasSentZero || !isSendingZero)
auxSendValues.SetValues(gameObject);
hasSentZero = isSendingZero;
lastPosition = position;
hasActivePortalListChanged = false;
hasEnvironmentListChanged = false;
}
private void TryAddEnvironment(AkEnvironment env)
{
if (env == null)
return;
var index = activeEnvironmentsFromPortals.BinarySearch(env, AkEnvironment.s_compareByPriority);
if (index >= 0)
return;
activeEnvironmentsFromPortals.Insert(~index, env);
index = activeEnvironments.BinarySearch(env, AkEnvironment.s_compareBySelectionAlgorithm);
if (index < 0)
activeEnvironments.Insert(~index, env);
hasEnvironmentListChanged = true;
}
private void RemoveEnvironment(AkEnvironment env)
{
activeEnvironmentsFromPortals.Remove(env);
activeEnvironments.Remove(env);
hasEnvironmentListChanged = true;
}
public void AddAkEnvironment(UnityEngine.Collider environmentCollider, UnityEngine.Collider gameObjectCollider)
{
var portal = environmentCollider.GetComponent<AkEnvironmentPortal>();
if (portal == null)
{
var env = environmentCollider.GetComponent<AkEnvironment>();
TryAddEnvironment(env);
return;
}
activePortals.Add(portal);
hasActivePortalListChanged = true;
for (var i = 0; i < AkEnvironmentPortal.MAX_ENVIRONMENTS_PER_PORTAL; i++)
TryAddEnvironment(portal.environments[i]);
}
private bool AkEnvironmentBelongsToActivePortals(AkEnvironment env)
{
for (var i = 0; i < activePortals.Count; i++)
for (var j = 0; j < AkEnvironmentPortal.MAX_ENVIRONMENTS_PER_PORTAL; j++)
{
if (env == activePortals[i].environments[j])
return true;
}
return false;
}
public void RemoveAkEnvironment(UnityEngine.Collider environmentCollider, UnityEngine.Collider gameObjectCollider)
{
var portal = environmentCollider.GetComponent<AkEnvironmentPortal>();
if (portal != null)
{
for (var i = 0; i < AkEnvironmentPortal.MAX_ENVIRONMENTS_PER_PORTAL; i++)
{
var env = portal.environments[i];
if (env != null && !gameObjectCollider.bounds.Intersects(env.Collider.bounds))
RemoveEnvironment(env);
}
activePortals.Remove(portal);
hasActivePortalListChanged = true;
}
else
{
var env = environmentCollider.GetComponent<AkEnvironment>();
if (env != null && !AkEnvironmentBelongsToActivePortals(env))
RemoveEnvironment(env);
}
}
}
#endif // #if !(UNITY_QNX) // Disable under unsupported platforms.
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ed0f82de77a42fc4090c3ca5876767a2
@@ -0,0 +1,91 @@
#if !(UNITY_QNX) // Disable under unsupported platforms.
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
[System.Serializable]
public class AkGameObjListenerList : AkAudioListener.BaseListenerList
{
[System.NonSerialized] private AkGameObj akGameObj;
[UnityEngine.SerializeField]
public System.Collections.Generic.List<AkAudioListener> initialListenerList =
new System.Collections.Generic.List<AkAudioListener>();
[UnityEngine.SerializeField] public bool useDefaultListeners = true;
public void SetUseDefaultListeners(bool useDefault)
{
if (useDefaultListeners != useDefault)
{
useDefaultListeners = useDefault;
if (useDefault)
{
AkUnitySoundEngine.ResetListenersToDefault(akGameObj.gameObject);
for (var i = 0; i < ListenerList.Count; ++i)
AkUnitySoundEngine.AddListener(akGameObj.gameObject, ListenerList[i].gameObject);
}
else
{
var Ids = GetListenerIds();
AkUnitySoundEngine.SetListeners(akGameObj.gameObject, Ids, Ids == null ? 0 : (uint) Ids.Length);
}
}
}
public void Init(AkGameObj akGameObj)
{
this.akGameObj = akGameObj;
if (!useDefaultListeners)
AkUnitySoundEngine.SetListeners(akGameObj.gameObject, null, 0);
for (var ii = 0; ii < initialListenerList.Count; ++ii)
initialListenerList[ii].StartListeningToEmitter(akGameObj);
}
public override bool Add(AkAudioListener listener)
{
var ret = base.Add(listener);
if (ret && AkUnitySoundEngine.IsInitialized())
AkUnitySoundEngine.AddListener(akGameObj.gameObject, listener.gameObject);
return ret;
}
public override bool Remove(AkAudioListener listener)
{
var ret = base.Remove(listener);
if (ret && AkUnitySoundEngine.IsInitialized())
AkUnitySoundEngine.RemoveListener(akGameObj.gameObject, listener.gameObject);
return ret;
}
#if UNITY_EDITOR
public void AddToInitialListenerList(AkAudioListener listener)
{
if (!initialListenerList.Contains(listener))
initialListenerList.Add(listener);
}
public void RemoveFromInitialListenerList(AkAudioListener listener)
{
initialListenerList.Remove(listener);
}
#endif
}
#endif // #if !(UNITY_QNX) // Disable under unsupported platforms.
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 7d21f88ef110b7f4db9f0ab69030084e
@@ -0,0 +1,28 @@
#if !(UNITY_QNX) // Disable under unsupported platforms.
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
// *** THIS FILE IS KEPT FOR THE MIGRATION SYSTEM, DO NOT USE THIS CLASS !!! ***
// DEPRECATED
public class AkGameObjPosOffsetData : UnityEngine.ScriptableObject
{
public UnityEngine.Vector3 positionOffset;
}
#endif // #if !(UNITY_QNX) // Disable under unsupported platforms.
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: c1e48680c5dc123428385ce50f8e9cf9
@@ -0,0 +1,26 @@
#if !(UNITY_QNX) // Disable under unsupported platforms.
/*******************************************************************************
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
Technology released in source code form as part of the game integration package.
The content of this file may not be used without valid licenses to the
AUDIOKINETIC Wwise Technology.
Note that the use of the game engine is subject to the Unity(R) Terms of
Service at https://unity3d.com/legal/terms-of-service
License Usage
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
this file in accordance with the end user license agreement provided with the
software or, alternatively, in accordance with the terms contained
in a written agreement between you and Audiokinetic Inc.
Copyright (c) 2026 Audiokinetic Inc.
*******************************************************************************/
public class AkGameObjPositionData
{
public UnityEngine.Vector3 forward;
public UnityEngine.Vector3 position;
public UnityEngine.Vector3 up;
}
#endif // #if !(UNITY_QNX) // Disable under unsupported platforms.
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 602941824d606dc4bafa3188213fc76f

Some files were not shown because too many files have changed in this diff Show More