-
-
Save JavadocMD/39c2197c2b4970ed06a5247bee386c72 to your computer and use it in GitHub Desktop.
using System; | |
using System.Reflection; | |
using UnityEditor; | |
using UnityEngine; | |
// I recommend dropping this script in an Editor folder. | |
// You should have two audio clips somewhere in the project. | |
// You'll need to edit-in the paths of those clips (from your project root folder) in the static initializer below. | |
// Example path: "Assets/Editor/CompileIndicator/start.mp3" | |
namespace Assets.Editor { | |
/// <summary> | |
/// Plays a sound effect when script compiling starts and ends. | |
/// </summary> | |
[InitializeOnLoad] | |
public static class CompileIndicator { | |
private const string CompileStatePrefsKey = "CompileIndicator.WasCompiling"; | |
private static readonly AudioClip StartClip; | |
private static readonly AudioClip EndClip; | |
static CompileIndicator() { | |
EditorApplication.update += OnUpdate; | |
StartClip = AssetDatabase.LoadAssetAtPath<AudioClip>("REPLACE_WITH_PATH_TO_YOUR_START_CLIP"); | |
EndClip = AssetDatabase.LoadAssetAtPath<AudioClip>("REPLACE_WITH_PATH_TO_YOUR_END_CLIP"); | |
} | |
private static void OnUpdate() { | |
var wasCompiling = EditorPrefs.GetBool(CompileStatePrefsKey); | |
var isCompiling = EditorApplication.isCompiling; | |
// Return early if compile status hasn't changed. | |
if (wasCompiling == isCompiling) | |
return; | |
if (isCompiling) | |
OnStartCompiling(); | |
else | |
OnEndCompiling(); | |
EditorPrefs.SetBool(CompileStatePrefsKey, isCompiling); | |
} | |
private static void OnStartCompiling() { | |
PlayClip(StartClip); | |
} | |
private static void OnEndCompiling() { | |
PlayClip(EndClip); | |
} | |
private static void PlayClip(AudioClip clip) { | |
Assembly unityEditorAssembly = typeof(AudioImporter).Assembly; | |
Type audioUtilClass = unityEditorAssembly.GetType("UnityEditor.AudioUtil"); | |
MethodInfo method = audioUtilClass.GetMethod( | |
"PlayClip", | |
BindingFlags.Static | BindingFlags.Public, | |
null, | |
new []{typeof(AudioClip)}, | |
null | |
); | |
method.Invoke(null, new object[]{clip}); | |
} | |
} | |
} |
DietChugg on reddit suggests using AssetDatabase rather than Resources is preferable to avoid bloating your builds. Script updated to reflect that. Or you can use Yourstress' advice above to find the clips by name. 👍
Do I actually need the
namespace Assets.Editor {
Getting some errs saying it's unexpected (5.6). It's in the editor dir.
Works in Unity 2019.1.9f1, thanks for posting this 👍
One suggestion I'd make -- to not interfere with other scripts that subscribe to editor update event, I'd advise changing:
EditorApplication.update = OnUpdate;
to
EditorApplication.update += OnUpdate;
Great catch @ChrisNZL! Updated.
Hey, is this working in Unity 2019.3 onwards? I'm using 2019.3.11 and I can't get the sound to play. I added a null check to make sure it was finding the audio clip, so I know the audio is in the right place.
Thanks!
@manotone Since 2019 you need to use this instead:
public static void PlayClip(AudioClip clip, int startSample = 0, bool loop = false)
{
System.Reflection.Assembly unityEditorAssembly = typeof(AudioImporter).Assembly;
System.Type audioUtilClass = unityEditorAssembly.GetType("UnityEditor.AudioUtil");
System.Reflection.MethodInfo method = audioUtilClass.GetMethod(
"PlayClip",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public,
null,
new System.Type[] { typeof(AudioClip), typeof(int), typeof(bool) },
null
);
method.Invoke(
null,
new object[] { clip, startSample, loop }
);
}
If anyone comes here in 2022 the reflected method is now named "PlayPreviewClip".
Use the following in Unity 2021
private static void PlayClip(AudioClip clip, int startSample = 0, bool loop = false)
{
var unityEditorAssembly = typeof(AudioImporter).Assembly;
var audioUtilClass = unityEditorAssembly.GetType("UnityEditor.AudioUtil");
var method = audioUtilClass.GetMethod("PlayPreviewClip",
BindingFlags.Static | BindingFlags.Public,
null,
new[]
{
typeof(AudioClip), typeof(int),
typeof(bool)
},
null);
method.Invoke(null, new object[] { clip, startSample, loop });
}
Awesome script. Thanks for the effort. I've modified it a quick-and-dirty way to load AudioClips not in the Resources folder. It might be useful to others that don't want to move clips between folders.
static CompileIndicator() {
EditorApplication.update = OnUpdate;
string guid = AssetDatabase.FindAssets("t:AudioClip YOUR_START_CLIP_NAME")[0];
StartClip = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid));
guid = AssetDatabase.FindAssets("t:AudioClip YOUR_END_CLIP_NAME")[0];
EndClip = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid));
}