Repository URL to install this package:
|
Version:
1.3.2 ▾
|
using System;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Fluctio.FluctioSim.Core.Components.Base
{
/// <summary>
/// Base class for editor components with convenient functions
/// </summary>
[ExecuteAlways]
public abstract class EditorComponent : MonoBehaviour
{
#region Fields
[NonSerialized] private bool _hasInitializeHappened = false;
[SerializeField, HideInInspector] private bool hasInitializeOnceHappened = false;
private void InitializeOnceWithChecks()
{
if (!hasInitializeOnceHappened)
{
InitializeOnce();
hasInitializeOnceHappened = true;
}
}
private void InitializeWithChecks()
{
if (!_hasInitializeHappened)
{
Initialize();
_hasInitializeHappened = true;
}
}
private void InitializePrefabWithChecks()
{
#if UNITY_EDITOR
if (PrefabUtility.IsPartOfAnyPrefab(gameObject))
{
return;
}
#endif
InitializePrefab();
}
#endregion
#region Virtual functions
/**
* This function is executed in editor and in runtime.
* It is intended for retrieving and filling non-serialized references,
* which depend on other components, and needs to happen on assembly reload.
*/
protected virtual void Initialize() {}
/**
* This function is executed once when component is added in the editor.
* It is intended for creation of other objects/components
* and filling serialized references with default values.
*/
protected virtual void InitializeOnce()
{
#if UNITY_EDITOR
Undo.SetCurrentGroupName($"Add {GetType().Name}");
#endif
InitializePrefabWithChecks();
}
/**
* This function is executed for each component in prefab
* when player creates object via CreateMenu.
*/
public virtual void InitializePrefab() {}
public virtual void OnAnyChanged() {}
public virtual void OnSelfChanged() => OnAnyChanged();
public virtual void OnOtherChanged() => OnAnyChanged();
#endregion
#region Unity event functions
protected bool ShouldExecute(bool skipInitializedCheck = false, bool allowInPlayMode = false)
{
var initializedCheck = _hasInitializeHappened || skipInitializedCheck;
var runningCheck = !Application.isPlaying || allowInPlayMode;
var sceneCheck = gameObject.scene.IsValid();
return initializedCheck && runningCheck && sceneCheck;
}
protected virtual void Awake()
{
if (!ShouldExecute(skipInitializedCheck: true, allowInPlayMode: true))
{
return;
}
if (Application.isPlaying)
{
InitializeWithChecks();
}
else
{
InitializeOnceWithChecks();
InitializeWithChecks();
}
}
protected virtual void Reset()
{
if (!ShouldExecute(allowInPlayMode: true))
{
return;
}
InitializeOnceWithChecks();
InitializeWithChecks();
OnSelfChanged();
}
protected virtual void OnValidate()
{
if (!ShouldExecute(skipInitializedCheck: true, allowInPlayMode: true))
{
return;
}
InitializeWithChecks();
OnSelfChanged();
}
// ReSharper disable Unity.PerformanceAnalysis
protected virtual void Update()
{
if (!ShouldExecute())
{
return;
}
OnOtherChanged();
}
protected virtual void OnDestroy()
{
#if UNITY_EDITOR
Undo.SetCurrentGroupName($"Remove {GetType().Name}");
#endif
}
#endregion
}
#if UNITY_EDITOR
[CustomEditor(typeof(EditorComponent), true)]
public class EditorComponentEditor : Editor
{
protected virtual string[] PropertiesToExclude => new[] { "m_Script" };
public override void OnInspectorGUI()
{
serializedObject.Update();
DrawPropertiesExcluding(serializedObject, PropertiesToExclude);
serializedObject.ApplyModifiedProperties();
}
}
#endif
}