Feat : Wwise Integration
This commit is contained in:
@@ -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
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 392f44b722eebf9409adb5d5aa59907c
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 77675ff2dc9f8a54aaaa0d8d046795b0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+32
@@ -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
|
||||
+2
@@ -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
|
||||
+2
@@ -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
|
||||
Reference in New Issue
Block a user