Last active
June 23, 2023 18:39
-
-
Save JavadocMD/39c2197c2b4970ed06a5247bee386c72 to your computer and use it in GitHub Desktop.
A Unity script to play a sound effect when script compiling starts and ends.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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}); | |
} | |
} | |
} |
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 });
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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. 👍