1103 lines
34 KiB
C#
1103 lines
34 KiB
C#
|
|
/*******************************************************************************
|
||
|
|
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) 2024 Audiokinetic Inc.
|
||
|
|
*******************************************************************************/
|
||
|
|
|
||
|
|
#if UNITY_EDITOR
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.IO;
|
||
|
|
|
||
|
|
[UnityEditor.InitializeOnLoad]
|
||
|
|
public class AkPluginActivator : UnityEditor.AssetPostprocessor
|
||
|
|
{
|
||
|
|
public const string ALL_PLATFORMS = "All";
|
||
|
|
public const string CONFIG_DEBUG = "Debug";
|
||
|
|
public const string CONFIG_PROFILE = "Profile";
|
||
|
|
public const string CONFIG_RELEASE = "Release";
|
||
|
|
|
||
|
|
private const string EditorConfiguration = CONFIG_PROFILE;
|
||
|
|
|
||
|
|
private const string MENU_PATH = "Assets/Wwise/Activate Plugins/";
|
||
|
|
private const UnityEditor.BuildTarget INVALID_BUILD_TARGET = (UnityEditor.BuildTarget)(-1);
|
||
|
|
|
||
|
|
private const string WwisePluginFolder = "Runtime/Plugins";
|
||
|
|
|
||
|
|
// The following check is required until "BuildTarget.Switch" is available on all versions of Unity that we support.
|
||
|
|
private static readonly UnityEditor.BuildTarget SwitchBuildTarget = GetPlatformBuildTarget("Switch");
|
||
|
|
|
||
|
|
private static readonly System.Collections.Generic.Dictionary<string, System.DateTime> s_LastParsed =
|
||
|
|
new System.Collections.Generic.Dictionary<string, System.DateTime>();
|
||
|
|
|
||
|
|
private static readonly System.Collections.Generic.Dictionary<string, System.Collections.Generic.HashSet<AkPluginInfo>>
|
||
|
|
s_PerPlatformPlugins = new System.Collections.Generic.Dictionary<string, System.Collections.Generic.HashSet<AkPluginInfo>>();
|
||
|
|
|
||
|
|
private static readonly System.Collections.Generic.HashSet<PluginID> builtInPluginIDs =
|
||
|
|
new System.Collections.Generic.HashSet<PluginID>
|
||
|
|
{
|
||
|
|
PluginID.AkCompressor,
|
||
|
|
PluginID.AkDelay,
|
||
|
|
PluginID.AkExpander,
|
||
|
|
PluginID.AkGain,
|
||
|
|
PluginID.AkMatrixReverb,
|
||
|
|
PluginID.AkMeter,
|
||
|
|
PluginID.AkParametricEQ,
|
||
|
|
PluginID.AkPeakLimiter,
|
||
|
|
PluginID.AkRoomVerb,
|
||
|
|
PluginID.AkReflect,
|
||
|
|
#if !UNITY_2018_3_OR_NEWER
|
||
|
|
PluginID.VitaReverb,
|
||
|
|
PluginID.VitaCompressor,
|
||
|
|
PluginID.VitaDelay,
|
||
|
|
PluginID.VitaDistortion,
|
||
|
|
PluginID.VitaEQ,
|
||
|
|
#endif
|
||
|
|
};
|
||
|
|
|
||
|
|
private static readonly System.Collections.Generic.HashSet<PluginID> alwaysSkipPluginsIDs =
|
||
|
|
new System.Collections.Generic.HashSet<PluginID>
|
||
|
|
{
|
||
|
|
PluginID.SineGenerator,
|
||
|
|
PluginID.SinkAuxiliary,
|
||
|
|
PluginID.SinkCommunication,
|
||
|
|
PluginID.SinkControllerHeadphones,
|
||
|
|
PluginID.SinkControllerSpeaker,
|
||
|
|
PluginID.SinkDVRByPass,
|
||
|
|
PluginID.SinkNoOutput,
|
||
|
|
PluginID.SinkSystem,
|
||
|
|
PluginID.ToneGenerator,
|
||
|
|
PluginID.WwiseSilence,
|
||
|
|
PluginID.AkAudioInput,
|
||
|
|
};
|
||
|
|
|
||
|
|
private static readonly System.Collections.Generic.Dictionary<PluginID, string> PluginIDToStaticLibName =
|
||
|
|
new System.Collections.Generic.Dictionary<PluginID, string>
|
||
|
|
{
|
||
|
|
{ PluginID.Ak3DAudioBedMixer, "Ak3DAudioBedMixerFX" },
|
||
|
|
{ PluginID.AkAudioInput, "AkAudioInputSource" },
|
||
|
|
{ PluginID.AkCompressor, "AkCompressorFX" },
|
||
|
|
{ PluginID.AkRouterMixer, "AkRouterMixerFX" },
|
||
|
|
{ PluginID.AkChannelRouter, "AkChannelRouterFX" },
|
||
|
|
{ PluginID.AkConvolutionReverb, "AkConvolutionReverbFX" },
|
||
|
|
{ PluginID.AkDelay, "AkDelayFX" },
|
||
|
|
{ PluginID.AkExpander, "AkExpanderFX" },
|
||
|
|
{ PluginID.AkFlanger, "AkFlangerFX" },
|
||
|
|
{ PluginID.AkGain, "AkGainFX" },
|
||
|
|
{ PluginID.AkGuitarDistortion, "AkGuitarDistortionFX" },
|
||
|
|
{ PluginID.AkHarmonizer, "AkHarmonizerFX" },
|
||
|
|
{ PluginID.AkMatrixReverb, "AkMatrixReverbFX" },
|
||
|
|
{ PluginID.AkMeter, "AkMeterFX" },
|
||
|
|
{ PluginID.AkMotionSink, "AkMotionSink" },
|
||
|
|
{ PluginID.AkMotionSource, "AkMotionSourceSource" },
|
||
|
|
{ PluginID.AkParametricEQ, "AkParametricEQFX" },
|
||
|
|
{ PluginID.AkPeakLimiter, "AkPeakLimiterFX" },
|
||
|
|
{ PluginID.AkPitchShifter, "AkPitchShifterFX" },
|
||
|
|
{ PluginID.AkRecorder, "AkRecorderFX" },
|
||
|
|
{ PluginID.AkReflect, "AkReflectFX" },
|
||
|
|
{ PluginID.AkRoomVerb, "AkRoomVerbFX" },
|
||
|
|
{ PluginID.AkSoundSeedGrain, "AkSoundSeedGrainSource" },
|
||
|
|
{ PluginID.AkSoundSeedWind, "AkSoundSeedWindSource" },
|
||
|
|
{ PluginID.AkSoundSeedWoosh, "AkSoundSeedWooshSource" },
|
||
|
|
{ PluginID.AkStereoDelay, "AkStereoDelayFX" },
|
||
|
|
{ PluginID.AkSynthOne, "AkSynthOneSource" },
|
||
|
|
{ PluginID.AkTimeStretch, "AkTimeStretchFX" },
|
||
|
|
{ PluginID.AkTremolo, "AkTremoloFX" },
|
||
|
|
{ PluginID.AuroHeadphone, "AuroHeadphoneFX" },
|
||
|
|
{ PluginID.CrankcaseAudioREVModelPlayer, "CrankcaseAudioREVModelPlayerSource" },
|
||
|
|
{ PluginID.iZHybridReverb, "iZHybridReverbFX" },
|
||
|
|
{ PluginID.iZTrashBoxModeler, "iZTrashBoxModelerFX" },
|
||
|
|
{ PluginID.iZTrashDelay, "iZTrashDelayFX" },
|
||
|
|
{ PluginID.iZTrashDistortion, "iZTrashDistortionFX" },
|
||
|
|
{ PluginID.iZTrashDynamics, "iZTrashDynamicsFX" },
|
||
|
|
{ PluginID.iZTrashFilters, "iZTrashFiltersFX" },
|
||
|
|
{ PluginID.iZTrashMultibandDistortion, "iZTrashMultibandDistortionFX" },
|
||
|
|
{ PluginID.MasteringSuite, "MasteringSuiteFX" },
|
||
|
|
{ PluginID.AkImpacterSource, "AkImpacterSource" },
|
||
|
|
{ PluginID.McDSPFutzBox, "McDSPFutzBoxFX" },
|
||
|
|
{ PluginID.McDSPLimiter, "McDSPLimiterFX" },
|
||
|
|
{ PluginID.ResonanceAudioRenderer, "ResonanceAudioFX" },
|
||
|
|
{ PluginID.ResonanceAudioRoomEffect, "ResonanceAudioFX" },
|
||
|
|
{ PluginID.IgniterLive, "IgniterLiveSource" },
|
||
|
|
{ PluginID.IgniterLiveSynth, "IgniterLiveSource" }
|
||
|
|
};
|
||
|
|
|
||
|
|
// Support libraries are DLLs that do not have an associated Wwise plug-in ID; they are meant to be loaded manually by the application
|
||
|
|
private static readonly System.Collections.Generic.List<string> SupportLibraries =
|
||
|
|
new System.Collections.Generic.List<string>
|
||
|
|
{
|
||
|
|
"AkVorbisHwAccelerator"
|
||
|
|
};
|
||
|
|
|
||
|
|
public delegate void FilterOutPlatformDelegate(UnityEditor.BuildTarget target, UnityEditor.PluginImporter pluginImporter, string pluginPlatform);
|
||
|
|
public static FilterOutPlatformDelegate FilterOutPlatformIfNeeded = FilterOutPlatformIfNeeded_Default;
|
||
|
|
|
||
|
|
|
||
|
|
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths, bool didDomainReload)
|
||
|
|
{
|
||
|
|
if (UnityEditor.AssetDatabase.IsAssetImportWorkerProcess())
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (didDomainReload)
|
||
|
|
{
|
||
|
|
ActivatePluginsForEditor();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Use reflection because projects that were created in Unity 4 won't have the CurrentPluginConfig field
|
||
|
|
public static string GetCurrentConfig()
|
||
|
|
{
|
||
|
|
var CurrentPluginConfigField = typeof(AkWwiseProjectData).GetField("CurrentPluginConfig");
|
||
|
|
var CurrentConfig = string.Empty;
|
||
|
|
var data = AkWwiseProjectInfo.GetData();
|
||
|
|
|
||
|
|
if (CurrentPluginConfigField != null && data != null)
|
||
|
|
{
|
||
|
|
CurrentConfig = (string)CurrentPluginConfigField.GetValue(data);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (string.IsNullOrEmpty(CurrentConfig))
|
||
|
|
{
|
||
|
|
CurrentConfig = CONFIG_PROFILE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return CurrentConfig;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void SetCurrentConfig(string config)
|
||
|
|
{
|
||
|
|
var CurrentPluginConfigField = typeof(AkWwiseProjectData).GetField("CurrentPluginConfig");
|
||
|
|
var data = AkWwiseProjectInfo.GetData();
|
||
|
|
if (CurrentPluginConfigField != null)
|
||
|
|
{
|
||
|
|
CurrentPluginConfigField.SetValue(data, config);
|
||
|
|
UnityEngine.Debug.LogFormat("WwiseUnity: Changed plugin configuration for game runtime to {0}", config);
|
||
|
|
}
|
||
|
|
|
||
|
|
UnityEditor.EditorUtility.SetDirty(AkWwiseProjectInfo.GetData());
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void ActivateConfig(string config)
|
||
|
|
{
|
||
|
|
SetCurrentConfig(config);
|
||
|
|
CheckMenuItems(config);
|
||
|
|
}
|
||
|
|
|
||
|
|
[UnityEditor.MenuItem(MENU_PATH + CONFIG_DEBUG)]
|
||
|
|
public static void ActivateDebug()
|
||
|
|
{
|
||
|
|
ActivateConfig(CONFIG_DEBUG);
|
||
|
|
}
|
||
|
|
|
||
|
|
[UnityEditor.MenuItem(MENU_PATH + CONFIG_PROFILE)]
|
||
|
|
public static void ActivateProfile()
|
||
|
|
{
|
||
|
|
ActivateConfig(CONFIG_PROFILE);
|
||
|
|
}
|
||
|
|
|
||
|
|
[UnityEditor.MenuItem(MENU_PATH + CONFIG_RELEASE)]
|
||
|
|
public static void ActivateRelease()
|
||
|
|
{
|
||
|
|
ActivateConfig(CONFIG_RELEASE);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static UnityEditor.BuildTarget GetPlatformBuildTarget(string platform)
|
||
|
|
{
|
||
|
|
var targets = System.Enum.GetNames(typeof(UnityEditor.BuildTarget));
|
||
|
|
var values = System.Enum.GetValues(typeof(UnityEditor.BuildTarget));
|
||
|
|
|
||
|
|
for (var ii = 0; ii < targets.Length; ++ii)
|
||
|
|
{
|
||
|
|
if (platform.Equals(targets[ii]))
|
||
|
|
return (UnityEditor.BuildTarget)values.GetValue(ii);
|
||
|
|
}
|
||
|
|
|
||
|
|
return INVALID_BUILD_TARGET;
|
||
|
|
}
|
||
|
|
|
||
|
|
public class PlatformConfiguration
|
||
|
|
{
|
||
|
|
public string WwisePlatformName;
|
||
|
|
public string PluginDirectoryName;
|
||
|
|
public ISet<string> Architectures = null;
|
||
|
|
public string DSPDirectoryPath = "";
|
||
|
|
public string StaticPluginRegistrationName = null;
|
||
|
|
public string StaticPluginDefine = null;
|
||
|
|
public bool RequiresStaticPluginRegistration = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Dictionary<UnityEditor.BuildTarget, PlatformConfiguration> BuildTargetToPlatformConfiguration = new Dictionary<UnityEditor.BuildTarget, PlatformConfiguration>();
|
||
|
|
|
||
|
|
public static void RegisterBuildTarget(UnityEditor.BuildTarget target, PlatformConfiguration config)
|
||
|
|
{
|
||
|
|
BuildTargetToPlatformConfiguration.Add(target, config);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static string[] GetPluginInfoFromPath(string path)
|
||
|
|
{
|
||
|
|
var indexOfPluginFolder = path.IndexOf(WwisePluginFolder, System.StringComparison.OrdinalIgnoreCase);
|
||
|
|
if (indexOfPluginFolder == -1)
|
||
|
|
{
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
return path.Substring(indexOfPluginFolder + WwisePluginFolder.Length + 1).Split('/');
|
||
|
|
}
|
||
|
|
|
||
|
|
private static List<UnityEditor.PluginImporter> GetWwisePluginImporters()
|
||
|
|
{
|
||
|
|
UnityEditor.PluginImporter[] pluginImporters = UnityEditor.PluginImporter.GetAllImporters();
|
||
|
|
List<UnityEditor.PluginImporter> wwisePlugins = new List<UnityEditor.PluginImporter>();
|
||
|
|
foreach (var pluginImporter in pluginImporters)
|
||
|
|
{
|
||
|
|
if (pluginImporter.assetPath.Contains("Wwise/API/"))
|
||
|
|
{
|
||
|
|
wwisePlugins.Add(pluginImporter);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return wwisePlugins;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void SetupStaticPluginRegistration(UnityEditor.BuildTarget target, PlatformConfiguration config)
|
||
|
|
{
|
||
|
|
if (!config.RequiresStaticPluginRegistration)
|
||
|
|
return;
|
||
|
|
|
||
|
|
string deploymentTargetName = config.WwisePlatformName;
|
||
|
|
|
||
|
|
var staticPluginRegistration = new StaticPluginRegistration(target);
|
||
|
|
var importers = GetWwisePluginImporters();
|
||
|
|
foreach (var pluginImporter in importers)
|
||
|
|
{
|
||
|
|
var splitPath = GetPluginInfoFromPath(pluginImporter.assetPath);
|
||
|
|
if (splitPath == null)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
var pluginPlatform = splitPath[0];
|
||
|
|
if (pluginPlatform != config.PluginDirectoryName)
|
||
|
|
continue;
|
||
|
|
|
||
|
|
var pluginConfig = string.Empty;
|
||
|
|
|
||
|
|
if (config.Architectures == null || config.Architectures.Count == 0)
|
||
|
|
{
|
||
|
|
// No architectures, so path is /<platform>/<config>/
|
||
|
|
pluginConfig = splitPath[1];
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
// Path is /<platform>/<arch>/<config>/
|
||
|
|
pluginConfig = splitPath[2];
|
||
|
|
|
||
|
|
var pluginArch = splitPath[1];
|
||
|
|
if (!config.Architectures.Contains(pluginArch))
|
||
|
|
{
|
||
|
|
UnityEngine.Debug.Log("WwiseUnity: Architecture not found: " + pluginArch);
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (pluginConfig != "DSP")
|
||
|
|
continue;
|
||
|
|
|
||
|
|
if (!IsPluginUsed(config, pluginPlatform, System.IO.Path.GetFileNameWithoutExtension(pluginImporter.assetPath)))
|
||
|
|
continue;
|
||
|
|
|
||
|
|
staticPluginRegistration.TryAddLibrary(config, pluginImporter.assetPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
System.Collections.Generic.HashSet<AkPluginInfo> plugins;
|
||
|
|
s_PerPlatformPlugins.TryGetValue(deploymentTargetName, out plugins);
|
||
|
|
var missingPlugins = staticPluginRegistration.GetMissingPlugins(plugins);
|
||
|
|
if (missingPlugins.Count == 0)
|
||
|
|
{
|
||
|
|
if (plugins == null)
|
||
|
|
UnityEngine.Debug.LogWarningFormat("WwiseUnity: The activated Wwise plug-ins may not be correct. Could not read PluginInfo.xml for platform: {0}", deploymentTargetName);
|
||
|
|
|
||
|
|
staticPluginRegistration.TryWriteToFile(config);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
UnityEngine.Debug.LogErrorFormat(
|
||
|
|
"WwiseUnity: These plugins used by the Wwise project are missing from the Unity project: {0}. Please check folder Assets/Wwise/API/Runtime/Plugin/{1}.",
|
||
|
|
string.Join(", ", missingPlugins.ToArray()), deploymentTargetName);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void SetStandalonePlatformData(UnityEditor.PluginImporter pluginImporter, string platformName, string architecture)
|
||
|
|
{
|
||
|
|
var isLinux = platformName == "Linux";
|
||
|
|
var isWindows = platformName == "Windows";
|
||
|
|
var isMac = platformName == "Mac";
|
||
|
|
var isX86 = architecture == "x86";
|
||
|
|
var isX64 = architecture == "x86_64";
|
||
|
|
|
||
|
|
#if !UNITY_2019_2_OR_NEWER
|
||
|
|
pluginImporter.SetPlatformData(UnityEditor.BuildTarget.StandaloneLinux, "CPU", isLinux && isX86 ? "x86" : "None");
|
||
|
|
pluginImporter.SetPlatformData(UnityEditor.BuildTarget.StandaloneLinuxUniversal, "CPU", !isLinux ? "None" : isX86 ? "x86" : isX64 ? "x86_64" : "None");
|
||
|
|
#endif
|
||
|
|
pluginImporter.SetPlatformData(UnityEditor.BuildTarget.StandaloneLinux64, "CPU", isLinux && isX64 ? "x86_64" : "None");
|
||
|
|
pluginImporter.SetPlatformData(UnityEditor.BuildTarget.StandaloneWindows, "CPU", isWindows && isX86 ? "AnyCPU" : "None");
|
||
|
|
pluginImporter.SetPlatformData(UnityEditor.BuildTarget.StandaloneWindows64, "CPU", isWindows && isX64 ? "AnyCPU" : "None");
|
||
|
|
pluginImporter.SetPlatformData(UnityEditor.BuildTarget.StandaloneOSX, "CPU", isMac ? "AnyCPU" : "None");
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void ActivatePluginsForDeployment(UnityEditor.BuildTarget target, bool Activate)
|
||
|
|
{
|
||
|
|
if (!BuildTargetToPlatformConfiguration.TryGetValue(target, out var platformConfiguration))
|
||
|
|
{
|
||
|
|
UnityEngine.Debug.Log("WwiseUnity: Build Target " + target + " not supported.");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (Activate)
|
||
|
|
{
|
||
|
|
SetupStaticPluginRegistration(target, platformConfiguration);
|
||
|
|
}
|
||
|
|
|
||
|
|
var importers = GetWwisePluginImporters();
|
||
|
|
foreach (var pluginImporter in importers)
|
||
|
|
{
|
||
|
|
var splitPath = GetPluginInfoFromPath(pluginImporter.assetPath);
|
||
|
|
if (splitPath == null)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
var pluginPlatform = splitPath[0];
|
||
|
|
if (pluginPlatform != platformConfiguration.PluginDirectoryName)
|
||
|
|
{
|
||
|
|
if (Activate)
|
||
|
|
{
|
||
|
|
FilterOutPlatformIfNeeded(target, pluginImporter, pluginPlatform);
|
||
|
|
}
|
||
|
|
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
var pluginName = splitPath[splitPath.Length - 1].Split('.')[0];
|
||
|
|
var pluginArch = string.Empty;
|
||
|
|
var pluginConfig = string.Empty;
|
||
|
|
var bIsSupportLibrary = SupportLibraries.Contains(pluginName);
|
||
|
|
|
||
|
|
switch (pluginPlatform)
|
||
|
|
{
|
||
|
|
case "WebGL":
|
||
|
|
case "iOS":
|
||
|
|
case "tvOS":
|
||
|
|
case "PS4":
|
||
|
|
case "PS5":
|
||
|
|
case "XboxSeriesX":
|
||
|
|
case "XboxOneGC":
|
||
|
|
pluginConfig = splitPath[1];
|
||
|
|
break;
|
||
|
|
|
||
|
|
case "Android":
|
||
|
|
pluginArch = splitPath[1];
|
||
|
|
pluginConfig = splitPath[2];
|
||
|
|
|
||
|
|
if (pluginArch == "armeabi-v7a")
|
||
|
|
{
|
||
|
|
pluginImporter.SetPlatformData(UnityEditor.BuildTarget.Android, "CPU", "ARMv7");
|
||
|
|
}
|
||
|
|
else if (pluginArch == "arm64-v8a")
|
||
|
|
{
|
||
|
|
pluginImporter.SetPlatformData(UnityEditor.BuildTarget.Android, "CPU", "ARM64");
|
||
|
|
}
|
||
|
|
else if (pluginArch == "x86")
|
||
|
|
{
|
||
|
|
pluginImporter.SetPlatformData(UnityEditor.BuildTarget.Android, "CPU", "x86");
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
UnityEngine.Debug.Log("WwiseUnity: Architecture not found: " + pluginArch);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case "Linux":
|
||
|
|
pluginArch = splitPath[1];
|
||
|
|
pluginConfig = splitPath[2];
|
||
|
|
|
||
|
|
if (pluginArch != "x86" && pluginArch != "x86_64")
|
||
|
|
{
|
||
|
|
UnityEngine.Debug.Log("WwiseUnity: Architecture not found: " + pluginArch);
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
SetStandalonePlatformData(pluginImporter, pluginPlatform, pluginArch);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case "Mac":
|
||
|
|
pluginConfig = splitPath[1];
|
||
|
|
SetStandalonePlatformData(pluginImporter, pluginPlatform, pluginArch);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case "Windows":
|
||
|
|
pluginArch = splitPath[1];
|
||
|
|
pluginConfig = splitPath[2];
|
||
|
|
|
||
|
|
if (pluginArch != "x86" && pluginArch != "x86_64")
|
||
|
|
{
|
||
|
|
UnityEngine.Debug.Log("WwiseUnity: Architecture not found: " + pluginArch);
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
SetStandalonePlatformData(pluginImporter, pluginPlatform, pluginArch);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case "Switch":
|
||
|
|
pluginArch = splitPath[1];
|
||
|
|
pluginConfig = splitPath[2];
|
||
|
|
|
||
|
|
if (SwitchBuildTarget == INVALID_BUILD_TARGET)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (pluginArch != "NX32" && pluginArch != "NX64")
|
||
|
|
{
|
||
|
|
UnityEngine.Debug.Log("WwiseUnity: Architecture not found: " + pluginArch);
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
default:
|
||
|
|
UnityEngine.Debug.Log("WwiseUnity: Unknown platform: " + pluginPlatform);
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
var AssetChanged = false;
|
||
|
|
if (pluginImporter.GetCompatibleWithAnyPlatform())
|
||
|
|
{
|
||
|
|
pluginImporter.SetCompatibleWithAnyPlatform(false);
|
||
|
|
AssetChanged = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
var bActivate = true;
|
||
|
|
if (pluginConfig == "DSP")
|
||
|
|
{
|
||
|
|
if (!bIsSupportLibrary && !IsPluginUsed(platformConfiguration, pluginPlatform, System.IO.Path.GetFileNameWithoutExtension(pluginImporter.assetPath)))
|
||
|
|
{
|
||
|
|
bActivate = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (pluginConfig != GetCurrentConfig())
|
||
|
|
{
|
||
|
|
bActivate = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool isCompatibleWithPlatform = bActivate && Activate;
|
||
|
|
AssetChanged |= pluginImporter.GetCompatibleWithPlatform(target) != isCompatibleWithPlatform;
|
||
|
|
|
||
|
|
pluginImporter.SetCompatibleWithPlatform(target, isCompatibleWithPlatform);
|
||
|
|
|
||
|
|
if (AssetChanged)
|
||
|
|
{
|
||
|
|
pluginImporter.SaveAndReimport();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void FilterOutPlatformIfNeeded_Default(UnityEditor.BuildTarget target, UnityEditor.PluginImporter pluginImporter, string pluginPlatform)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void ActivatePluginsForEditor()
|
||
|
|
{
|
||
|
|
var importers = GetWwisePluginImporters();
|
||
|
|
var ChangedSomeAssets = false;
|
||
|
|
|
||
|
|
foreach (var pluginImporter in importers)
|
||
|
|
{
|
||
|
|
var splitPath = GetPluginInfoFromPath(pluginImporter.assetPath);
|
||
|
|
if (splitPath == null)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
var pluginPlatform = splitPath[0];
|
||
|
|
var pluginConfig = string.Empty;
|
||
|
|
var editorCPU = string.Empty;
|
||
|
|
var editorOS = string.Empty;
|
||
|
|
|
||
|
|
PlatformConfiguration platformConfiguration = null;
|
||
|
|
switch (pluginPlatform)
|
||
|
|
{
|
||
|
|
case "Mac":
|
||
|
|
pluginConfig = splitPath[1];
|
||
|
|
editorCPU = "AnyCPU";
|
||
|
|
editorOS = "OSX";
|
||
|
|
if (!BuildTargetToPlatformConfiguration.TryGetValue(UnityEditor.BuildTarget.StandaloneOSX, out platformConfiguration))
|
||
|
|
platformConfiguration = null;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case "Windows":
|
||
|
|
editorCPU = splitPath[1];
|
||
|
|
pluginConfig = splitPath[2];
|
||
|
|
editorOS = "Windows";
|
||
|
|
if (!BuildTargetToPlatformConfiguration.TryGetValue(UnityEditor.BuildTarget.StandaloneWindows64, out platformConfiguration))
|
||
|
|
platformConfiguration = null;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
var AssetChanged = false;
|
||
|
|
if (pluginImporter.GetCompatibleWithAnyPlatform())
|
||
|
|
{
|
||
|
|
pluginImporter.SetCompatibleWithAnyPlatform(false);
|
||
|
|
AssetChanged = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
var bActivate = false;
|
||
|
|
if (!string.IsNullOrEmpty(editorOS))
|
||
|
|
{
|
||
|
|
// If we can't find the platform configuration, it simply just might not have bene registered yet.
|
||
|
|
// Better to do nothing than to deactivate the found plugins. If the plugin was activated, it will
|
||
|
|
// stay activated.
|
||
|
|
if (platformConfiguration != null)
|
||
|
|
{
|
||
|
|
if (pluginConfig == "DSP")
|
||
|
|
{
|
||
|
|
if (!s_PerPlatformPlugins.ContainsKey(platformConfiguration.WwisePlatformName))
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
bActivate = IsPluginUsed(platformConfiguration, pluginPlatform,
|
||
|
|
System.IO.Path.GetFileNameWithoutExtension(pluginImporter.assetPath));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
bActivate = pluginConfig == EditorConfiguration;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (bActivate)
|
||
|
|
{
|
||
|
|
pluginImporter.SetEditorData("CPU", editorCPU);
|
||
|
|
pluginImporter.SetEditorData("OS", editorOS);
|
||
|
|
}
|
||
|
|
|
||
|
|
AssetChanged |= pluginImporter.GetCompatibleWithEditor() != bActivate;
|
||
|
|
pluginImporter.SetCompatibleWithEditor(bActivate);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (AssetChanged)
|
||
|
|
{
|
||
|
|
ChangedSomeAssets = true;
|
||
|
|
UnityEditor.AssetDatabase.ImportAsset(pluginImporter.assetPath);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (ChangedSomeAssets)
|
||
|
|
{
|
||
|
|
UnityEngine.Debug.Log("WwiseUnity: Plugins successfully activated for " + EditorConfiguration + " in Editor.");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void CheckMenuItems(string config)
|
||
|
|
{
|
||
|
|
UnityEditor.Menu.SetChecked(MENU_PATH + CONFIG_DEBUG, config == CONFIG_DEBUG);
|
||
|
|
UnityEditor.Menu.SetChecked(MENU_PATH + CONFIG_PROFILE, config == CONFIG_PROFILE);
|
||
|
|
UnityEditor.Menu.SetChecked(MENU_PATH + CONFIG_RELEASE, config == CONFIG_RELEASE);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void DeactivateAllPlugins()
|
||
|
|
{
|
||
|
|
var importers = GetWwisePluginImporters();
|
||
|
|
foreach (var pluginImporter in importers)
|
||
|
|
{
|
||
|
|
if (pluginImporter.assetPath.IndexOf(WwisePluginFolder, System.StringComparison.OrdinalIgnoreCase) == -1)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
pluginImporter.SetCompatibleWithAnyPlatform(false);
|
||
|
|
UnityEditor.AssetDatabase.ImportAsset(pluginImporter.assetPath);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static bool IsPluginUsed(PlatformConfiguration in_config, string in_UnityPlatform, string in_PluginName)
|
||
|
|
{
|
||
|
|
var pluginDSPPlatform = in_config.WwisePlatformName;
|
||
|
|
|
||
|
|
if (!s_PerPlatformPlugins.ContainsKey(pluginDSPPlatform))
|
||
|
|
{
|
||
|
|
return false; //XML not parsed, don't touch anything.
|
||
|
|
}
|
||
|
|
|
||
|
|
if (in_PluginName.Contains("AkSoundEngine"))
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
var pluginName = in_PluginName;
|
||
|
|
if (in_PluginName.StartsWith("lib"))
|
||
|
|
{
|
||
|
|
pluginName = in_PluginName.Substring(3);
|
||
|
|
}
|
||
|
|
|
||
|
|
int indexOfFactory = in_PluginName.IndexOf("Factory");
|
||
|
|
if (indexOfFactory != -1)
|
||
|
|
{
|
||
|
|
pluginName = in_PluginName.Substring(0, indexOfFactory);
|
||
|
|
}
|
||
|
|
|
||
|
|
System.Collections.Generic.HashSet<AkPluginInfo> plugins;
|
||
|
|
if (s_PerPlatformPlugins.TryGetValue(pluginDSPPlatform, out plugins))
|
||
|
|
{
|
||
|
|
if (!in_config.RequiresStaticPluginRegistration)
|
||
|
|
{
|
||
|
|
foreach (var pluginInfo in plugins)
|
||
|
|
{
|
||
|
|
if (pluginInfo.DllName == pluginName)
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//Exceptions
|
||
|
|
if (!string.IsNullOrEmpty(in_config.StaticPluginRegistrationName) && pluginName.Contains(in_config.StaticPluginRegistrationName))
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
//WebGL, iOS, tvOS, and Switch deal with the static libs directly, unlike all other platforms.
|
||
|
|
//Luckily the DLL name is always a subset of the lib name.
|
||
|
|
foreach (var pluginInfo in plugins)
|
||
|
|
{
|
||
|
|
if (pluginInfo.StaticLibName == pluginName)
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void Update(bool forceUpdate = false)
|
||
|
|
{
|
||
|
|
//Gather all GeneratedSoundBanks folder from the project
|
||
|
|
var allPaths = AkUtilities.GetAllBankPaths();
|
||
|
|
var bNeedRefresh = false;
|
||
|
|
var projectDir = AkBasePathGetter.GetWwiseProjectDirectory();
|
||
|
|
var baseSoundBankPath = AkBasePathGetter.GetFullSoundBankPathEditor();
|
||
|
|
|
||
|
|
AkWwiseInitializationSettings.UpdatePlatforms();
|
||
|
|
|
||
|
|
//make a copy of the platform map and handle "special" custom platforms
|
||
|
|
var platformMap = new Dictionary<string, List<string>>();
|
||
|
|
foreach (var key in AkUtilities.PlatformMapping.Keys)
|
||
|
|
{
|
||
|
|
platformMap.Add(key, new List<string>(AkUtilities.PlatformMapping[key]));
|
||
|
|
foreach (var customPF in AkUtilities.PlatformMapping[key])
|
||
|
|
{
|
||
|
|
if (customPF != key && (AkWwiseInitializationSettings.PlatformSettings.IsDistinctPlatform(customPF)))
|
||
|
|
{
|
||
|
|
platformMap.Add(customPF, new List<string> { customPF });
|
||
|
|
platformMap[key].Remove(customPF);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (platformMap[key].Count==0)
|
||
|
|
{
|
||
|
|
platformMap.Remove(key);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
//Go through all BasePlatforms
|
||
|
|
foreach (var pairPF in platformMap)
|
||
|
|
{
|
||
|
|
//Go through all custom platforms related to that base platform and check if any of the bank files were updated.
|
||
|
|
var bParse = forceUpdate;
|
||
|
|
var fullPaths = new System.Collections.Generic.List<string>();
|
||
|
|
foreach (var customPF in pairPF.Value)
|
||
|
|
{
|
||
|
|
string bankPath;
|
||
|
|
if (!allPaths.TryGetValue(customPF, out bankPath))
|
||
|
|
continue;
|
||
|
|
|
||
|
|
var pluginFile = "";
|
||
|
|
try
|
||
|
|
{
|
||
|
|
pluginFile = System.IO.Path.Combine(projectDir, System.IO.Path.Combine(bankPath, "PluginInfo.xml"));
|
||
|
|
pluginFile = pluginFile.Replace('/', System.IO.Path.DirectorySeparatorChar);
|
||
|
|
if (!System.IO.File.Exists(pluginFile))
|
||
|
|
{
|
||
|
|
//Try in StreamingAssets too.
|
||
|
|
pluginFile = System.IO.Path.Combine(System.IO.Path.Combine(baseSoundBankPath, customPF), "PluginInfo.xml");
|
||
|
|
if (!System.IO.File.Exists(pluginFile))
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
fullPaths.Add(pluginFile);
|
||
|
|
|
||
|
|
var t = System.IO.File.GetLastWriteTime(pluginFile);
|
||
|
|
var lastTime = System.DateTime.MinValue;
|
||
|
|
bool bParsedBefore = s_LastParsed.TryGetValue(customPF, out lastTime);
|
||
|
|
if (!bParsedBefore || lastTime < t)
|
||
|
|
{
|
||
|
|
bParse = true;
|
||
|
|
s_LastParsed[customPF] = t;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
catch (System.Exception ex)
|
||
|
|
{
|
||
|
|
UnityEngine.Debug.LogError("WwiseUnity: " + pluginFile + " could not be parsed. " + ex.Message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (bParse)
|
||
|
|
{
|
||
|
|
var platform = pairPF.Key;
|
||
|
|
|
||
|
|
var newDlls = ParsePluginsXML(platform, fullPaths);
|
||
|
|
System.Collections.Generic.HashSet<AkPluginInfo> oldDlls = null;
|
||
|
|
|
||
|
|
//Remap base Wwise platforms to Unity platform folders names
|
||
|
|
#if !UNITY_2018_3_OR_NEWER
|
||
|
|
if (platform.Contains("Vita"))
|
||
|
|
{
|
||
|
|
platform = "Vita";
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
s_PerPlatformPlugins.TryGetValue(platform, out oldDlls);
|
||
|
|
s_PerPlatformPlugins[platform] = newDlls;
|
||
|
|
|
||
|
|
//Check if there was any change.
|
||
|
|
if (!bNeedRefresh && oldDlls != null)
|
||
|
|
{
|
||
|
|
if (oldDlls.Count == newDlls.Count)
|
||
|
|
{
|
||
|
|
oldDlls.IntersectWith(newDlls);
|
||
|
|
}
|
||
|
|
|
||
|
|
bNeedRefresh |= oldDlls.Count != newDlls.Count;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
bNeedRefresh |= newDlls.Count > 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (bNeedRefresh)
|
||
|
|
{
|
||
|
|
ActivatePluginsForEditor();
|
||
|
|
}
|
||
|
|
|
||
|
|
var currentConfig = GetCurrentConfig();
|
||
|
|
CheckMenuItems(currentConfig);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static System.Collections.Generic.HashSet<AkPluginInfo> ParsePluginsXML(string platform,
|
||
|
|
System.Collections.Generic.List<string> in_pluginFiles)
|
||
|
|
{
|
||
|
|
var newPlugins = new System.Collections.Generic.HashSet<AkPluginInfo>();
|
||
|
|
|
||
|
|
foreach (var pluginFile in in_pluginFiles)
|
||
|
|
{
|
||
|
|
if (!System.IO.File.Exists(pluginFile))
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var doc = new System.Xml.XmlDocument();
|
||
|
|
doc.Load(pluginFile);
|
||
|
|
var Navigator = doc.CreateNavigator();
|
||
|
|
var pluginInfoNode = Navigator.SelectSingleNode("//PluginInfo");
|
||
|
|
var boolMotion = pluginInfoNode.GetAttribute("Motion", "");
|
||
|
|
|
||
|
|
var it = Navigator.Select("//PluginLib");
|
||
|
|
|
||
|
|
if (boolMotion == "true")
|
||
|
|
{
|
||
|
|
AkPluginInfo motionPluginInfo = new AkPluginInfo();
|
||
|
|
motionPluginInfo.DllName = "AkMotion";
|
||
|
|
newPlugins.Add(motionPluginInfo);
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach (System.Xml.XPath.XPathNavigator node in it)
|
||
|
|
{
|
||
|
|
var rawPluginID = uint.Parse(node.GetAttribute("LibId", ""));
|
||
|
|
if (rawPluginID == 0)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
PluginID pluginID = (PluginID)rawPluginID;
|
||
|
|
|
||
|
|
if (alwaysSkipPluginsIDs.Contains(pluginID))
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
var dll = string.Empty;
|
||
|
|
|
||
|
|
if (platform == "Switch" || platform == "Web")
|
||
|
|
{
|
||
|
|
if (pluginID == PluginID.AkMeter)
|
||
|
|
{
|
||
|
|
dll = "AkMeter";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (builtInPluginIDs.Contains(pluginID))
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (string.IsNullOrEmpty(dll))
|
||
|
|
{
|
||
|
|
dll = node.GetAttribute("DLL", "");
|
||
|
|
}
|
||
|
|
|
||
|
|
var staticLibName = node.GetAttribute("StaticLib", "");
|
||
|
|
|
||
|
|
AkPluginInfo newPluginInfo = new AkPluginInfo();
|
||
|
|
newPluginInfo.PluginID = rawPluginID;
|
||
|
|
newPluginInfo.DllName = dll;
|
||
|
|
newPluginInfo.StaticLibName = staticLibName;
|
||
|
|
|
||
|
|
if (string.IsNullOrEmpty(newPluginInfo.StaticLibName) && !PluginIDToStaticLibName.TryGetValue(pluginID, out newPluginInfo.StaticLibName))
|
||
|
|
{
|
||
|
|
newPluginInfo.StaticLibName = dll;
|
||
|
|
}
|
||
|
|
|
||
|
|
newPlugins.Add(newPluginInfo);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
catch (System.Exception ex)
|
||
|
|
{
|
||
|
|
UnityEngine.Debug.LogError("WwiseUnity: " + pluginFile + " could not be parsed. " + ex.Message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return newPlugins;
|
||
|
|
}
|
||
|
|
|
||
|
|
private class StaticPluginRegistration
|
||
|
|
{
|
||
|
|
private readonly System.Collections.Generic.HashSet<string> FactoriesHeaderFilenames =
|
||
|
|
new System.Collections.Generic.HashSet<string>();
|
||
|
|
|
||
|
|
private readonly UnityEditor.BuildTarget Target;
|
||
|
|
|
||
|
|
public StaticPluginRegistration(UnityEditor.BuildTarget target)
|
||
|
|
{
|
||
|
|
Target = target;
|
||
|
|
}
|
||
|
|
|
||
|
|
public void TryAddLibrary(PlatformConfiguration config, string AssetPath)
|
||
|
|
{
|
||
|
|
if (AssetPath.Contains(".a"))
|
||
|
|
{
|
||
|
|
//Extract the lib name, generate the registration code.
|
||
|
|
var begin = AssetPath.LastIndexOf('/') + 4;
|
||
|
|
var end = AssetPath.LastIndexOf('.') - begin;
|
||
|
|
var LibName = AssetPath.Substring(begin, end); //Remove the lib prefix and the .a extension
|
||
|
|
|
||
|
|
if (!LibName.Contains("AkSoundEngine"))
|
||
|
|
{
|
||
|
|
string headerFilename = LibName + "Factory.h";
|
||
|
|
|
||
|
|
string fullPath = System.IO.Path.GetFullPath(AkUtilities.GetPathInPackage(WwisePluginFolder + config.DSPDirectoryPath + headerFilename));
|
||
|
|
|
||
|
|
if (System.IO.File.Exists(fullPath))
|
||
|
|
{
|
||
|
|
FactoriesHeaderFilenames.Add(headerFilename);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
UnityEngine.Debug.LogErrorFormat("WwiseUnity: Could not find '{0}', required for building plugin.", fullPath);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (AssetPath.Contains("Factory.h"))
|
||
|
|
{
|
||
|
|
FactoriesHeaderFilenames.Add(System.IO.Path.GetFileName(AssetPath));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public void TryWriteToFile(PlatformConfiguration config)
|
||
|
|
{
|
||
|
|
System.Text.StringBuilder CppText = new System.Text.StringBuilder(2000);
|
||
|
|
|
||
|
|
string RelativePath = config.DSPDirectoryPath + config.StaticPluginRegistrationName + ".cpp";
|
||
|
|
CppText.AppendLine("#define " + config.StaticPluginDefine);
|
||
|
|
|
||
|
|
// The purpose of this cpp file is to force the linker to recognize the usage of AK::PluginRegistration global objects
|
||
|
|
// so that the static constructors for these objects are executed when the binary is being loaded in.
|
||
|
|
// However, some platforms (e.g. WebGL) have a really aggressive LTO (link-time optimization) pass that will strip these
|
||
|
|
// symbols even when they are defined as extern here.
|
||
|
|
// To avoid any stripping, we call from C# a native function (AkVerifyPluginRegistration)
|
||
|
|
// that looks at these symbols, forcing the linker to recognize that these symbols are required for proper program execution.
|
||
|
|
|
||
|
|
CppText.AppendLine(@"namespace AK { class PluginRegistration; };");
|
||
|
|
CppText.AppendLine(@"class AkUnityStaticPlugin;");
|
||
|
|
CppText.AppendLine(@"AkUnityStaticPlugin * g_pAkUnityStaticPluginList = nullptr;");
|
||
|
|
CppText.AppendLine(@"class AkUnityStaticPlugin {");
|
||
|
|
CppText.AppendLine("\tpublic:");
|
||
|
|
CppText.AppendLine("\tAkUnityStaticPlugin(AK::PluginRegistration* pReg) : m_pNext(g_pAkUnityStaticPluginList), m_pReg(pReg) { g_pAkUnityStaticPluginList = this; }");
|
||
|
|
CppText.AppendLine("\tAkUnityStaticPlugin *m_pNext;");
|
||
|
|
CppText.AppendLine("\tAK::PluginRegistration * m_pReg;");
|
||
|
|
CppText.AppendLine(@"};");
|
||
|
|
|
||
|
|
CppText.AppendLine(@"#define AK_STATIC_LINK_PLUGIN(_pluginName_) \");
|
||
|
|
CppText.AppendLine(@"extern AK::PluginRegistration _pluginName_##Registration; \");
|
||
|
|
CppText.AppendLine(@"AkUnityStaticPlugin _pluginName_##UnityStaticPlugin(&_pluginName_##Registration);");
|
||
|
|
|
||
|
|
foreach (var filename in FactoriesHeaderFilenames)
|
||
|
|
{
|
||
|
|
CppText.AppendLine("#include \"" + filename + "\"");
|
||
|
|
}
|
||
|
|
CppText.AppendLine("extern \"C\" {");
|
||
|
|
CppText.AppendLine("\t__attribute__ ((visibility(\"default\"))) bool AkVerifyPluginRegistration() {");
|
||
|
|
CppText.AppendLine("\t\tbool bReg = true;");
|
||
|
|
CppText.AppendLine("\t\tAkUnityStaticPlugin * pNext = g_pAkUnityStaticPluginList;");
|
||
|
|
CppText.AppendLine("\t\twhile (pNext != nullptr) { bReg = bReg && pNext->m_pReg != nullptr; pNext = pNext->m_pNext; }");
|
||
|
|
CppText.AppendLine("\t\treturn bReg;");
|
||
|
|
CppText.AppendLine("\t}");
|
||
|
|
CppText.AppendLine("}");
|
||
|
|
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var FullPath = System.IO.Path.GetFullPath(AkUtilities.GetPathInPackage(WwisePluginFolder + RelativePath));
|
||
|
|
System.IO.File.WriteAllText(FullPath, CppText.ToString());
|
||
|
|
}
|
||
|
|
catch (System.Exception e)
|
||
|
|
{
|
||
|
|
UnityEngine.Debug.LogError("WwiseUnity: Could not write <" + RelativePath + ">. Exception: " + e.Message);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
UnityEditor.AssetDatabase.Refresh();
|
||
|
|
}
|
||
|
|
|
||
|
|
public System.Collections.Generic.List<string> GetMissingPlugins(System.Collections.Generic.HashSet<AkPluginInfo> usedPlugins)
|
||
|
|
{
|
||
|
|
var pluginList = new System.Collections.Generic.List<string>();
|
||
|
|
if (usedPlugins == null)
|
||
|
|
return pluginList;
|
||
|
|
|
||
|
|
foreach (var plugin in usedPlugins)
|
||
|
|
{
|
||
|
|
if (string.IsNullOrEmpty(plugin.StaticLibName))
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
string includeFilename = plugin.StaticLibName + "Factory.h";
|
||
|
|
if (!FactoriesHeaderFilenames.Contains(includeFilename))
|
||
|
|
{
|
||
|
|
pluginList.Add(plugin.StaticLibName);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return pluginList;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private enum PluginID
|
||
|
|
{
|
||
|
|
// Built-in plugins
|
||
|
|
Ak3DAudioBedMixer = 0x00BE0003, // Wwise 3D Audio Bed Mixer
|
||
|
|
AkCompressor = 0x006C0003, //Wwise Compressor
|
||
|
|
AkRouterMixer = 0x00AC0006, //Wwise RouterMixer
|
||
|
|
AkChannelRouter = 0x00BF0003, // Wwise Channel Router
|
||
|
|
AkDelay = 0x006A0003, //Delay
|
||
|
|
AkExpander = 0x006D0003, //Wwise Expander
|
||
|
|
AkGain = 0x008B0003, //Gain
|
||
|
|
AkMatrixReverb = 0x00730003, //Matrix Reverb
|
||
|
|
AkMeter = 0x00810003, //Wwise Meter
|
||
|
|
AkParametricEQ = 0x00690003, //Wwise Parametric EQ
|
||
|
|
AkPeakLimiter = 0x006E0003, //Wwise Peak Limiter
|
||
|
|
AkRoomVerb = 0x00760003, //Wwise RoomVerb
|
||
|
|
SineGenerator = 0x00640002, //Sine
|
||
|
|
SinkAuxiliary = 0xB40007,
|
||
|
|
SinkCommunication = 0xB00007,
|
||
|
|
SinkControllerHeadphones = 0xB10007,
|
||
|
|
SinkControllerSpeaker = 0xB30007,
|
||
|
|
SinkDVRByPass = 0xAF0007,
|
||
|
|
SinkNoOutput = 0xB50007,
|
||
|
|
SinkSystem = 0xAE0007,
|
||
|
|
ToneGenerator = 0x00660002, //Tone Generator
|
||
|
|
WwiseSilence = 0x00650002, //Wwise Silence
|
||
|
|
#if !UNITY_2018_3_OR_NEWER
|
||
|
|
VitaReverb = 0x008C0003, //Vita Reverb
|
||
|
|
VitaCompressor = 0x008D0003, //Vita Compressor
|
||
|
|
VitaDelay = 0x008E0003, //Vita Delay
|
||
|
|
VitaDistortion = 0x008F0003, //Vita Distortion
|
||
|
|
VitaEQ = 0x00900003, //Vita EQ
|
||
|
|
#endif
|
||
|
|
|
||
|
|
// Static or DLL plugins
|
||
|
|
AkAudioInput = 0xC80002,
|
||
|
|
AkConvolutionReverb = 0x7F0003,
|
||
|
|
AkFlanger = 0x7D0003,
|
||
|
|
AkGuitarDistortion = 0x7E0003,
|
||
|
|
AkHarmonizer = 0x8A0003,
|
||
|
|
AkMotionSink = 0x1FB0007,
|
||
|
|
AkMotionSource = 0x1990002,
|
||
|
|
AkPitchShifter = 0x880003,
|
||
|
|
AkRecorder = 0x840003,
|
||
|
|
AkReflect = 0xAB0003,
|
||
|
|
AkSoundSeedGrain = 0xB70002,
|
||
|
|
AkSoundSeedWind = 0x770002,
|
||
|
|
AkSoundSeedWoosh = 0x780002,
|
||
|
|
AkStereoDelay = 0x870003,
|
||
|
|
AkSynthOne = 0x940002,
|
||
|
|
AkTimeStretch = 0x820003,
|
||
|
|
AkTremolo = 0x830003,
|
||
|
|
AuroHeadphone = 0x44C1073,
|
||
|
|
CrankcaseAudioREVModelPlayer = 0x1A01052,
|
||
|
|
iZHybridReverb = 0x21033,
|
||
|
|
iZTrashBoxModeler = 0x71033,
|
||
|
|
iZTrashDelay = 0x41033,
|
||
|
|
iZTrashDistortion = 0x31033,
|
||
|
|
iZTrashDynamics = 0x51033,
|
||
|
|
iZTrashFilters = 0x61033,
|
||
|
|
iZTrashMultibandDistortion = 0x91033,
|
||
|
|
MasteringSuite = 0xBA0003,
|
||
|
|
AkImpacterSource = 0xB80002,
|
||
|
|
McDSPFutzBox = 0x6E1003,
|
||
|
|
McDSPLimiter = 0x671003,
|
||
|
|
ResonanceAudioRenderer = 0x641103,
|
||
|
|
ResonanceAudioRoomEffect = 0xC81106,
|
||
|
|
IgniterLive = 0x5110D2,
|
||
|
|
IgniterLiveSynth = 0x5210D2
|
||
|
|
}
|
||
|
|
|
||
|
|
private class AkPluginInfo
|
||
|
|
{
|
||
|
|
public uint PluginID;
|
||
|
|
public string DllName;
|
||
|
|
public string StaticLibName;
|
||
|
|
|
||
|
|
public override int GetHashCode()
|
||
|
|
{
|
||
|
|
return PluginID.GetHashCode();
|
||
|
|
}
|
||
|
|
|
||
|
|
public override bool Equals(object obj)
|
||
|
|
{
|
||
|
|
return PluginID.Equals(obj);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif
|