You've already forked ParticleEffectForUGUI
mirror of
https://github.com/mob-sakai/ParticleEffectForUGUI.git
synced 2026-05-15 20:50:08 +00:00
demo: add performance demo
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace Coffee.MiniProfiler
|
||||
{
|
||||
internal class MiniProfilerSettings : ScriptableSettings<MiniProfilerSettings>
|
||||
{
|
||||
[Header("UI")]
|
||||
[SerializeField] private Font m_Font = null;
|
||||
|
||||
[Header("Instantiate On Boot")]
|
||||
[SerializeField] private GameObject miniProfilerPrefab = null;
|
||||
[SerializeField] private string[] m_SceneNames = new string[0];
|
||||
|
||||
public Font font => m_Font;
|
||||
public event Action onFontChanged;
|
||||
|
||||
protected override void OnBoot()
|
||||
{
|
||||
SceneManager.sceneLoaded -= OnSceneLoaded;
|
||||
SceneManager.sceneLoaded += OnSceneLoaded;
|
||||
}
|
||||
|
||||
public void OnSceneLoaded(Scene scene, LoadSceneMode __)
|
||||
{
|
||||
SceneManager.sceneLoaded -= OnSceneLoaded;
|
||||
if (!miniProfilerPrefab || !m_SceneNames.Contains(scene.name)) return;
|
||||
|
||||
var go = Instantiate(miniProfilerPrefab);
|
||||
if (Application.isPlaying)
|
||||
DontDestroyOnLoad(go);
|
||||
}
|
||||
|
||||
protected override bool bootOnPlayMode => true;
|
||||
protected override bool bootOnEditorMode => false;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnValidate()
|
||||
{
|
||||
onFontChanged?.Invoke();
|
||||
base.OnValidate();
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
m_Font = UnityEngine.Resources.GetBuiltinResource<Font>("Arial.ttf");
|
||||
}
|
||||
|
||||
[UnityEditor.SettingsProvider]
|
||||
private static UnityEditor.SettingsProvider CreateSettingsProvider() => new ScriptableSettingsProvider<MiniProfilerSettings>();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 647dad4f8226a49b9874b68b79413d64
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- miniProfilerPrefab: {fileID: 7211429669315726685, guid: 784696794bc6345bc80bf49623581c2e,
|
||||
type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,280 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Linq;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
|
||||
#endif
|
||||
|
||||
namespace Coffee.MiniProfiler
|
||||
{
|
||||
internal abstract class ScriptableSettings : ScriptableObject
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
public virtual string GetSettingPath()
|
||||
{
|
||||
return GetSettingPath(GetType());
|
||||
}
|
||||
|
||||
internal static string GetSettingPath(Type type)
|
||||
{
|
||||
return $"Project/{ObjectNames.NicifyVariableName(type.Name.Replace("ProjectSettings", ""))}";
|
||||
}
|
||||
#endif
|
||||
|
||||
public virtual string GetDefaultAssetPath()
|
||||
{
|
||||
return $"Assets/ProjectSettings/{GetType().Name}.asset";
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class ScriptableSettings<T> : ScriptableSettings
|
||||
where T : ScriptableSettings<T>
|
||||
{
|
||||
//################################
|
||||
// Public Members.
|
||||
//################################
|
||||
public static T Instance => _instance ? _instance : _instance = GetOrCreate();
|
||||
|
||||
private static T _instance;
|
||||
|
||||
protected virtual bool bootOnEditorMode => true;
|
||||
protected virtual bool bootOnPlayMode => true;
|
||||
|
||||
protected abstract void OnBoot();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
//################################
|
||||
// Private Members.
|
||||
//################################
|
||||
private bool enabled;
|
||||
|
||||
private static T GetOrCreate()
|
||||
{
|
||||
return PlayerSettings.GetPreloadedAssets()
|
||||
.OfType<T>()
|
||||
.FirstOrDefault() ?? CreateInstance<T>();
|
||||
}
|
||||
|
||||
private void OnPlayModeStateChanged(PlayModeStateChange state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case PlayModeStateChange.EnteredEditMode:
|
||||
enabled = true;
|
||||
Boot();
|
||||
break;
|
||||
case PlayModeStateChange.ExitingEditMode:
|
||||
case PlayModeStateChange.ExitingPlayMode:
|
||||
enabled = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void Boot()
|
||||
{
|
||||
var preloadedAssets = PlayerSettings.GetPreloadedAssets();
|
||||
var assets = preloadedAssets.OfType<T>().ToArray();
|
||||
var first = assets.FirstOrDefault() ?? this as T;
|
||||
|
||||
// If there are no preloaded assets, registry the first asset.
|
||||
// If there are multiple preloaded assets, unregisters all but the first one.
|
||||
if (assets.Length != 1)
|
||||
{
|
||||
// The first asset is not saved.
|
||||
if (string.IsNullOrEmpty(AssetDatabase.GetAssetPath(first)))
|
||||
{
|
||||
if (!AssetDatabase.IsValidFolder("Assets/ProjectSettings"))
|
||||
AssetDatabase.CreateFolder("Assets", "ProjectSettings");
|
||||
|
||||
var assetName = ObjectNames.NicifyVariableName(first.GetType().Name.Replace("ProjectSettings", ""));
|
||||
var assetPath = AssetDatabase.GenerateUniqueAssetPath($"Assets/ProjectSettings/{assetName}.asset");
|
||||
AssetDatabase.CreateAsset(first, assetPath);
|
||||
}
|
||||
|
||||
PlayerSettings.SetPreloadedAssets(preloadedAssets
|
||||
.Where(x => x)
|
||||
.Except(assets)
|
||||
.Concat(new[] {first})
|
||||
.ToArray());
|
||||
}
|
||||
|
||||
// Another asset is registered as a preload asset.
|
||||
if (first != this)
|
||||
{
|
||||
UnityEngine.Debug.LogError($"Another asset '{first}' is registered as a preload '{typeof(T).Name}' asset." +
|
||||
$"\nThis instance ('{this}') will be ignored. Check 'Project Settings > Player > Preload Assets'", this);
|
||||
return;
|
||||
}
|
||||
|
||||
_instance = first;
|
||||
|
||||
// Do nothing on editor mode.
|
||||
if (!bootOnEditorMode && !EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Do nothing on play mode.
|
||||
if (!bootOnPlayMode && EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OnBoot();
|
||||
}
|
||||
|
||||
|
||||
//################################
|
||||
// Unity Callbacks.
|
||||
//################################
|
||||
private void OnEnable()
|
||||
{
|
||||
enabled = true;
|
||||
Boot();
|
||||
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
|
||||
}
|
||||
|
||||
protected virtual void OnValidate()
|
||||
{
|
||||
if (enabled)
|
||||
Boot();
|
||||
}
|
||||
#else
|
||||
private static T GetOrCreate()
|
||||
{
|
||||
return CreateInstance<T>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (!bootOnPlayMode) return;
|
||||
|
||||
_instance = this as T;
|
||||
OnBoot();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
[CustomEditor(typeof(ScriptablePreferenceSettings<>), true)]
|
||||
internal class ScriptablePreferenceSettingsEditor : Editor
|
||||
{
|
||||
private static readonly GUIContent _button = new GUIContent("Open Project Settings");
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
if (GUILayout.Button(_button))
|
||||
{
|
||||
SettingsService.OpenProjectSettings(((ScriptableSettings) target).GetSettingPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class ScriptablePreferenceSettings<T> : ScriptableSingleton<T>
|
||||
where T : ScriptablePreferenceSettings<T>
|
||||
{
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[CustomEditor(typeof(ScriptableSettings), true)]
|
||||
internal class ScriptableSettingsEditor : Editor
|
||||
{
|
||||
private static readonly GUIContent _button = new GUIContent("Open Project Settings");
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
if (GUILayout.Button(_button))
|
||||
{
|
||||
SettingsService.OpenProjectSettings(((ScriptableSettings) target).GetSettingPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class ScriptableSettingsProvider<T> : SettingsProvider where T : ScriptableSettings<T>
|
||||
{
|
||||
public ScriptableSettingsProvider(string path) : base(path)
|
||||
{
|
||||
}
|
||||
|
||||
public ScriptableSettingsProvider() : base(ScriptableSettings.GetSettingPath(typeof(T)))
|
||||
{
|
||||
}
|
||||
|
||||
protected SerializedObject serializedObject { get; private set; }
|
||||
protected ScriptableSettings<T> target { get; private set; }
|
||||
|
||||
public sealed override void OnGUI(string searchContext)
|
||||
{
|
||||
if (!target)
|
||||
{
|
||||
target = ScriptableSettings<T>.Instance;
|
||||
serializedObject = new SerializedObject(target);
|
||||
}
|
||||
|
||||
OnGUI();
|
||||
}
|
||||
|
||||
protected virtual void OnGUI()
|
||||
{
|
||||
serializedObject.UpdateIfRequiredOrScript();
|
||||
var iterator = serializedObject.GetIterator();
|
||||
var enterChildren = true;
|
||||
while (iterator.NextVisible(enterChildren))
|
||||
{
|
||||
if (iterator.propertyPath != "m_Script")
|
||||
EditorGUILayout.PropertyField(iterator, true);
|
||||
|
||||
enterChildren = false;
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
internal class ScriptablePreferenceSettingsProvider<T> : SettingsProvider where T : ScriptableSettings<T>
|
||||
{
|
||||
public ScriptablePreferenceSettingsProvider(string path) : base(path, SettingsScope.User)
|
||||
{
|
||||
}
|
||||
|
||||
public ScriptablePreferenceSettingsProvider() : base(ScriptableSettings.GetSettingPath(typeof(T)), SettingsScope.User)
|
||||
{
|
||||
}
|
||||
|
||||
protected SerializedObject serializedObject { get; private set; }
|
||||
protected ScriptableSettings<T> target { get; private set; }
|
||||
|
||||
public sealed override void OnGUI(string searchContext)
|
||||
{
|
||||
if (!target)
|
||||
{
|
||||
target = ScriptableSettings<T>.Instance;
|
||||
serializedObject = new SerializedObject(target);
|
||||
}
|
||||
|
||||
OnGUI();
|
||||
}
|
||||
|
||||
protected virtual void OnGUI()
|
||||
{
|
||||
serializedObject.UpdateIfRequiredOrScript();
|
||||
var iterator = serializedObject.GetIterator();
|
||||
var enterChildren = true;
|
||||
while (iterator.NextVisible(enterChildren))
|
||||
{
|
||||
if (iterator.propertyPath != "m_Script")
|
||||
EditorGUILayout.PropertyField(iterator, true);
|
||||
|
||||
enterChildren = false;
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ea9606f69cee413e9f96f52de99fa5e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user