Skip to content

Instantly share code, notes, and snippets.

@JavadocMD
Last active June 23, 2023 18:39
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JavadocMD/39c2197c2b4970ed06a5247bee386c72 to your computer and use it in GitHub Desktop.
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.
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});
}
}
}
@ChrisNZL
Copy link

ChrisNZL commented Jul 9, 2019

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;

@JavadocMD
Copy link
Author

Great catch @ChrisNZL! Updated.

@manotone
Copy link

manotone commented Jul 8, 2020

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!

@nicmar
Copy link

nicmar commented Nov 19, 2020

@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 }
			);
		}

(Found here: https://forum.unity.com/threads/way-to-play-audio-in-editor-using-an-editor-script.132042/?_ga=2.71159570.364268315.1605429586-738984339.1602493717#post-4767824)

@lreeves
Copy link

lreeves commented May 19, 2022

If anyone comes here in 2022 the reflected method is now named "PlayPreviewClip".

@bezoro
Copy link

bezoro commented Feb 13, 2023

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