UnitySettingsHelper.cs 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. using UnityEngine;
  2. using System.Reflection;
  3. using System;
  4. using System.Collections;
  5. using System.Runtime.CompilerServices;
  6. [assembly: InternalsVisibleTo("SingularityGroup.HotReload.Demo")]
  7. namespace SingularityGroup.HotReload.Editor {
  8. internal class UnitySettingsHelper {
  9. public static UnitySettingsHelper I = new UnitySettingsHelper();
  10. private bool initialized;
  11. private object pref;
  12. private PropertyInfo prefColorProp;
  13. private MethodInfo setMethod;
  14. private Type settingsType;
  15. private Type prefColorType;
  16. const string currentPlaymodeTintPrefKey = "Playmode tint";
  17. internal bool playmodeTintSupported => EditorCodePatcher.config.changePlaymodeTint && EnsureInitialized();
  18. private UnitySettingsHelper() {
  19. EnsureInitialized();
  20. }
  21. private bool EnsureInitialized() {
  22. if (initialized) {
  23. return true;
  24. }
  25. try {
  26. // cache members for performance
  27. settingsType = settingsType ?? (settingsType = typeof(UnityEditor.Editor).Assembly.GetType($"UnityEditor.PrefSettings"));
  28. prefColorType = prefColorType ?? (prefColorType = typeof(UnityEditor.Editor).Assembly.GetType($"UnityEditor.PrefColor"));
  29. prefColorProp = prefColorProp ?? (prefColorProp = prefColorType?.GetProperty("Color", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public));
  30. pref = pref ?? (pref = GetPref(settingsType: settingsType, prefColorType: prefColorType));
  31. setMethod = setMethod ?? (setMethod = GetSetMethod(settingsType: settingsType, prefColorType: prefColorType));
  32. if (prefColorProp == null
  33. || pref == null
  34. || setMethod == null
  35. ) {
  36. return false;
  37. }
  38. // clear cache for performance
  39. settingsType = null;
  40. prefColorType = null;
  41. initialized = true;
  42. return true;
  43. } catch {
  44. return false;
  45. }
  46. }
  47. private static MethodInfo GetSetMethod(Type settingsType, Type prefColorType) {
  48. var setMethodBase = settingsType?.GetMethod("Set", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
  49. return setMethodBase?.MakeGenericMethod(prefColorType);
  50. }
  51. private static object GetPref(Type settingsType, Type prefColorType) {
  52. var prefsMethodBase = settingsType?.GetMethod("Prefs", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
  53. var prefsMethod = prefsMethodBase?.MakeGenericMethod(prefColorType);
  54. var prefs = (IEnumerable)prefsMethod?.Invoke(null, Array.Empty<object>());
  55. if (prefs != null) {
  56. foreach (object kvp in prefs) {
  57. var key = kvp.GetType().GetProperty("Key", BindingFlags.Instance | BindingFlags.Public)?.GetMethod.Invoke(kvp, Array.Empty<object>());
  58. if (key?.ToString() == currentPlaymodeTintPrefKey) {
  59. return kvp.GetType().GetProperty("Value", BindingFlags.Instance | BindingFlags.Public)?.GetMethod.Invoke(kvp, Array.Empty<object>());
  60. }
  61. }
  62. }
  63. return null;
  64. }
  65. public Color? GetCurrentPlaymodeColor() {
  66. if (!playmodeTintSupported) {
  67. return null;
  68. }
  69. return (Color)prefColorProp.GetValue(pref);
  70. }
  71. public void SetPlaymodeTint(Color color) {
  72. if (!playmodeTintSupported) {
  73. return;
  74. }
  75. prefColorProp.SetValue(pref, color);
  76. setMethod.Invoke(null, new object[] { currentPlaymodeTintPrefKey, pref });
  77. }
  78. }
  79. }