-
-
Save Kainkun/9184d5e42ca26734e5889b8754edb5b2 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 hidden or 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
#if UNITY_EDITOR | |
using System; | |
using System.Reflection; | |
using UnityEditor; | |
using UnityEngine; | |
namespace Editor | |
{ | |
[InitializeOnLoad] | |
public static class CompileIndicator | |
{ | |
private const string DefaultStartPath = "Assets/YOUR_START_AUDIO_PATH_HERE"; | |
private const string DefaultEndPath = "Assets/YOUR_END_AUDIO_PATH_HERE"; | |
private const string MenuRoot = "Tools/Compile Indicator"; | |
private const string CompileStateKey = "CompileIndicator.WasCompiling"; | |
private const string StartSoundPathKey = "CompileIndicator.StartSoundPath"; | |
private const string EndSoundPathKey = "CompileIndicator.EndSoundPath"; | |
private const string EnableStartSoundKey = "CompileIndicator.EnableStartSound"; | |
private const string EnableEndSoundKey = "CompileIndicator.EnableEndSound"; | |
private static AudioClip _startClip; | |
private static AudioClip _endClip; | |
static CompileIndicator() | |
{ | |
InitializePrefsOnce(); | |
EditorApplication.update += OnUpdate; | |
LoadClips(); | |
} | |
private static void InitializePrefsOnce() | |
{ | |
if (!PlayerPrefs.HasKey(StartSoundPathKey)) | |
PlayerPrefs.SetString(StartSoundPathKey, DefaultStartPath); | |
if (!PlayerPrefs.HasKey(EndSoundPathKey)) | |
PlayerPrefs.SetString(EndSoundPathKey, DefaultEndPath); | |
if (!PlayerPrefs.HasKey(EnableStartSoundKey)) | |
PlayerPrefs.SetInt(EnableStartSoundKey, 1); | |
if (!PlayerPrefs.HasKey(EnableEndSoundKey)) | |
PlayerPrefs.SetInt(EnableEndSoundKey, 1); | |
} | |
private static void OnUpdate() | |
{ | |
bool wasCompiling = PlayerPrefs.GetInt(CompileStateKey, 0) == 1; | |
bool isCompiling = EditorApplication.isCompiling; | |
if (wasCompiling == isCompiling) | |
return; | |
switch (isCompiling) | |
{ | |
case true when GetBool(EnableStartSoundKey): | |
PlayClip(_startClip); | |
break; | |
case false when GetBool(EnableEndSoundKey): | |
PlayClip(_endClip); | |
break; | |
} | |
SetBool(CompileStateKey, isCompiling); | |
} | |
private static void PlayClip(AudioClip clip, int startSample = 0, bool loop = false) | |
{ | |
if (clip == null) return; | |
try | |
{ | |
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 }); | |
} | |
catch (Exception e) | |
{ | |
Debug.LogWarning("CompileIndicator: Failed to play clip.\n" + e); | |
} | |
} | |
private static void LoadClips() | |
{ | |
_startClip = AssetDatabase.LoadAssetAtPath<AudioClip>(PlayerPrefs.GetString(StartSoundPathKey, | |
DefaultStartPath)); | |
_endClip = AssetDatabase.LoadAssetAtPath<AudioClip>(PlayerPrefs.GetString(EndSoundPathKey, DefaultEndPath)); | |
} | |
private static string GetRelativeAssetPath(string fullPath) | |
{ | |
string assetsPath = Application.dataPath; | |
if (fullPath.StartsWith(assetsPath)) | |
{ | |
return "Assets" + fullPath.Substring(assetsPath.Length).Replace("\\", "/"); | |
} | |
Debug.LogWarning("CompileIndicator: Selected file is not inside the Assets folder."); | |
return ""; | |
} | |
// ==== Menu Items ==== | |
[MenuItem(MenuRoot + "/Enable Start Sound", priority = 0)] | |
private static void ToggleStartSound() | |
{ | |
bool newState = !GetBool(EnableStartSoundKey); | |
SetBool(EnableStartSoundKey, newState); | |
Debug.LogFormat("CompileIndicator: Start sound {0}.", newState ? "enabled" : "disabled"); | |
} | |
[MenuItem(MenuRoot + "/Enable Start Sound", true)] | |
private static bool ToggleStartSoundValidate() | |
{ | |
Menu.SetChecked(MenuRoot + "/Enable Start Sound", GetBool(EnableStartSoundKey)); | |
return true; | |
} | |
[MenuItem(MenuRoot + "/Enable End Sound", priority = 1)] | |
private static void ToggleEndSound() | |
{ | |
bool newState = !GetBool(EnableEndSoundKey); | |
SetBool(EnableEndSoundKey, newState); | |
Debug.LogFormat("CompileIndicator: End sound {0}.", newState ? "enabled" : "disabled"); | |
} | |
[MenuItem(MenuRoot + "/Enable End Sound", true)] | |
private static bool ToggleEndSoundValidate() | |
{ | |
Menu.SetChecked(MenuRoot + "/Enable End Sound", GetBool(EnableEndSoundKey)); | |
return true; | |
} | |
[MenuItem(MenuRoot + "/Set Start Sound...", priority = 50)] | |
private static void SetStartSound() | |
{ | |
string path = EditorUtility.OpenFilePanel("Select Start Sound", "Assets", "wav,mp3,aiff"); | |
if (!string.IsNullOrEmpty(path)) | |
{ | |
string relativePath = GetRelativeAssetPath(path); | |
if (string.IsNullOrEmpty(relativePath)) return; | |
PlayerPrefs.SetString(StartSoundPathKey, relativePath); | |
_startClip = AssetDatabase.LoadAssetAtPath<AudioClip>(relativePath); | |
Debug.LogFormat("CompileIndicator: Start sound set to: {0}", relativePath); | |
} | |
else | |
{ | |
Debug.Log("CompileIndicator: Start sound selection canceled."); | |
} | |
} | |
[MenuItem(MenuRoot + "/Set End Sound...", priority = 51)] | |
private static void SetEndSound() | |
{ | |
string path = EditorUtility.OpenFilePanel("Select End Sound", "Assets", "wav,mp3,aiff"); | |
if (!string.IsNullOrEmpty(path)) | |
{ | |
string relativePath = GetRelativeAssetPath(path); | |
if (string.IsNullOrEmpty(relativePath)) return; | |
PlayerPrefs.SetString(EndSoundPathKey, relativePath); | |
_endClip = AssetDatabase.LoadAssetAtPath<AudioClip>(relativePath); | |
Debug.LogFormat("CompileIndicator: End sound set to: {0}", relativePath); | |
} | |
else | |
{ | |
Debug.Log("CompileIndicator: End sound selection canceled."); | |
} | |
} | |
[MenuItem(MenuRoot + "/Reset to Defaults", priority = 100)] | |
private static void ResetToDefaults() | |
{ | |
if (EditorUtility.DisplayDialog("Reset Compile Indicator", | |
"Are you sure you want to reset to default settings?", "Yes", "Cancel")) | |
{ | |
PlayerPrefs.SetString(StartSoundPathKey, DefaultStartPath); | |
PlayerPrefs.SetString(EndSoundPathKey, DefaultEndPath); | |
SetBool(EnableStartSoundKey, true); | |
SetBool(EnableEndSoundKey, true); | |
LoadClips(); | |
Debug.Log("CompileIndicator: Settings reset to defaults."); | |
} | |
else | |
{ | |
Debug.Log("CompileIndicator: Reset to defaults canceled."); | |
} | |
} | |
// ==== PlayerPrefs Helpers ==== | |
private static bool GetBool(string key) => PlayerPrefs.GetInt(key, 0) == 1; | |
private static void SetBool(string key, bool value) => | |
PlayerPrefs.SetInt(key, value ? 1 : 0); | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment