Skip to content

Instantly share code, notes, and snippets.

@JavadocMD
Last active July 21, 2025 21:17
Show Gist options
  • 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});
}
}
}
@JavadocMD
Copy link
Author

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. 👍

@dylanh724
Copy link

dylanh724 commented Jun 16, 2018

Do I actually need the

namespace Assets.Editor {

Getting some errs saying it's unexpected (5.6). It's in the editor dir.

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

@Kainkun
Copy link

Kainkun commented Jul 21, 2025

Forked and made it nicer. Feel free to use it
https://gist.github.com/Kainkun/9184d5e42ca26734e5889b8754edb5b2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment