-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,10 @@ | ||
# SO.Architecture | ||
Scriptableobject Architecture for game Unity (Anti-Singleton) | ||
# ScriptableobjectArchitecture | ||
|
||
## How To Install | ||
|
||
### Add the lines below to `Packages/manifest.json` | ||
|
||
for version `1.0.0` | ||
```csharp | ||
"com.virtuesky.scriptableobject.architecture":"https://github.com/VirtueSky/SO.Architecture.git#1.0.0", | ||
``` |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
using UnityEditor; | ||
using UnityEngine; | ||
using VirtueSky.Utils; | ||
|
||
namespace VirtueSky.Attributes | ||
{ | ||
public class GUIDAttribute : PropertyAttribute | ||
{ | ||
public string prefix; | ||
|
||
public GUIDAttribute() | ||
{ | ||
this.prefix = string.Empty; | ||
} | ||
|
||
public GUIDAttribute(string prefix) | ||
{ | ||
this.prefix = prefix; | ||
} | ||
} | ||
|
||
#if UNITY_EDITOR | ||
[CustomPropertyDrawer(typeof(GUIDAttribute))] | ||
public class GuidAttributeDrawer : PropertyDrawer | ||
{ | ||
string Prefix => (attribute as GUIDAttribute).prefix; | ||
|
||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | ||
{ | ||
EditorGUI.BeginProperty(position, label, property); | ||
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); | ||
|
||
if (string.IsNullOrEmpty(property.stringValue)) | ||
{ | ||
property.stringValue = Prefix + SimpleMath.NewGuid(); | ||
} | ||
|
||
var w = position.width * 0.3f; | ||
|
||
position.width = position.width * 0.7f; | ||
GUI.enabled = false; | ||
EditorGUI.PropertyField(position, property, GUIContent.none); | ||
GUI.enabled = true; | ||
|
||
position.position += new Vector2(position.width, 0); | ||
position.width = w; | ||
if (GUI.Button(position, new GUIContent("Change"))) | ||
{ | ||
if (!property.serializedObject.isEditingMultipleObjects) | ||
property.stringValue = Prefix + SimpleMath.NewGuid(); | ||
} | ||
|
||
property.serializedObject.ApplyModifiedProperties(); | ||
|
||
EditorGUI.EndProperty(); | ||
} | ||
} | ||
#endif | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
using System.Text; | ||
using UnityEditor; | ||
using UnityEngine; | ||
using VirtueSky.EditorUtils; | ||
|
||
namespace VirtueSky.Attributes | ||
{ | ||
public class NamedIdAttribute : PropertyAttribute | ||
{ | ||
public NamedIdAttribute() | ||
{ | ||
} | ||
} | ||
|
||
#if UNITY_EDITOR | ||
[CustomPropertyDrawer(typeof(NamedIdAttribute))] | ||
public class NamedIdAttributeDrawer : PropertyDrawer | ||
{ | ||
NamedIdAttribute TargetAttribute => attribute as NamedIdAttribute; | ||
|
||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | ||
{ | ||
EditorGUI.BeginProperty(position, label, property); | ||
|
||
Context(position, property); | ||
|
||
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); | ||
|
||
var id = property.stringValue; | ||
if (string.IsNullOrEmpty(id)) | ||
{ | ||
id = ToSnakeCase(property.serializedObject.targetObject.name); | ||
property.stringValue = id; | ||
property.serializedObject.ApplyModifiedProperties(); | ||
} | ||
|
||
using (new EditorGUIUtils.DisabledGUI(true)) | ||
{ | ||
EditorGUI.TextField(position, id); | ||
} | ||
|
||
EditorGUI.EndProperty(); | ||
} | ||
|
||
void Context(Rect rect, SerializedProperty property) | ||
{ | ||
var current = Event.current; | ||
|
||
if (rect.Contains(current.mousePosition) && current.type == EventType.ContextClick) | ||
{ | ||
var menu = new GenericMenu(); | ||
|
||
menu.AddItem(new GUIContent("Reset"), false, | ||
() => | ||
{ | ||
property.stringValue = ToSnakeCase(property.serializedObject.targetObject.name); | ||
property.serializedObject.ApplyModifiedProperties(); | ||
}); | ||
menu.ShowAsContext(); | ||
|
||
current.Use(); | ||
} | ||
} | ||
|
||
public static string ToSnakeCase(string text) | ||
{ | ||
if (text.Length < 2) | ||
{ | ||
return text; | ||
} | ||
|
||
var sb = new StringBuilder(); | ||
sb.Append(char.ToLowerInvariant(text[0])); | ||
for (var i = 1; i < text.Length; ++i) | ||
{ | ||
var c = text[i]; | ||
if (char.IsUpper(c)) | ||
{ | ||
sb.Append('_'); | ||
sb.Append(char.ToLowerInvariant(c)); | ||
} | ||
else | ||
{ | ||
sb.Append(c); | ||
} | ||
} | ||
|
||
return sb.ToString(); | ||
} | ||
} | ||
#endif | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
using System; | ||
using System.Linq; | ||
using UnityEditor; | ||
using UnityEngine; | ||
using VirtueSky.Attributes; | ||
using VirtueSky.ObjectPooling; | ||
using VirtueSky.Utils; | ||
using System.IO; | ||
|
||
namespace VirtueSky.Core | ||
{ | ||
|
||
public class BaseMono : MonoBehaviour, IEntity | ||
{ | ||
[Header("Base")] [SerializeField, NamedId] | ||
string id; | ||
|
||
[SerializeField] public Pools pools; | ||
[SerializeField] public Ticker ticker; | ||
[SerializeField] bool earlyTick; | ||
[SerializeField] bool tick; | ||
[SerializeField] bool lateTick; | ||
[SerializeField] bool fixedTick; | ||
|
||
public string Id => id; | ||
|
||
#if UNITY_EDITOR | ||
[ContextMenu("ResetId")] | ||
public void ResetId() | ||
{ | ||
id = NamedIdAttributeDrawer.ToSnakeCase(name); | ||
EditorUtility.SetDirty(this); | ||
} | ||
#endif | ||
|
||
void OnEnable() | ||
{ | ||
BindVariable(); | ||
ListenEvents(); | ||
SubTick(); | ||
DoEnable(); | ||
} | ||
|
||
void OnDisable() | ||
{ | ||
DoDisable(); | ||
UnsubTick(); | ||
// StopListenEvents(); | ||
UnbindVariable(); | ||
} | ||
|
||
private void OnDestroy() | ||
{ | ||
DoDestroy(); | ||
} | ||
|
||
public virtual void BindVariable() | ||
{ | ||
} | ||
|
||
public virtual void ListenEvents() | ||
{ | ||
} | ||
|
||
void SubTick() | ||
{ | ||
if (earlyTick) ticker.SubEarlyTick(this); | ||
if (tick) ticker.SubTick(this); | ||
if (lateTick) ticker.SubLateTick(this); | ||
if (fixedTick) ticker.SubFixedTick(this); | ||
} | ||
|
||
public virtual void DoEnable() | ||
{ | ||
} | ||
|
||
public virtual void Initialize() | ||
{ | ||
} | ||
|
||
public virtual void EarlyTick() | ||
{ | ||
} | ||
|
||
public virtual void Tick() | ||
{ | ||
} | ||
|
||
public virtual void LateTick() | ||
{ | ||
} | ||
|
||
public virtual void FixedTick() | ||
{ | ||
} | ||
|
||
public virtual void CleanUp() | ||
{ | ||
} | ||
|
||
public virtual void DoDisable() | ||
{ | ||
} | ||
|
||
public virtual void DoDestroy() | ||
{ | ||
} | ||
|
||
void UnsubTick() | ||
{ | ||
if (earlyTick) ticker.UnsubEarlyTick(this); | ||
if (tick) ticker.UnsubTick(this); | ||
if (lateTick) ticker.UnsubLateTick(this); | ||
if (fixedTick) ticker.UnsubFixedTick(this); | ||
} | ||
|
||
public virtual void StopListenEvents() | ||
{ | ||
} | ||
|
||
public virtual void UnbindVariable() | ||
{ | ||
} | ||
|
||
#if UNITY_EDITOR | ||
void Reset() | ||
{ | ||
ticker = AssetUtils.FindAssetAtFolder<Ticker>(new string[] { "Assets" }).FirstOrDefault(); | ||
if (ticker == null) | ||
{ | ||
CreateSettingAssets<Ticker>(); | ||
ticker = AssetUtils.FindAssetAtFolder<Ticker>(new string[] { "Assets" }).FirstOrDefault(); | ||
} | ||
|
||
pools = AssetUtils.FindAssetAtFolder<Pools>(new string[] { "Assets" }).FirstOrDefault(); | ||
if (pools == null) | ||
{ | ||
CreateSettingAssets<Pools>(); | ||
pools = AssetUtils.FindAssetAtFolder<Pools>(new string[] { "Assets" }).FirstOrDefault(); | ||
} | ||
|
||
EditorUtility.SetDirty(this); | ||
} | ||
|
||
private void CreateSettingAssets<T>() where T : ScriptableObject | ||
{ | ||
var setting = UnityEngine.ScriptableObject.CreateInstance<T>(); | ||
UnityEditor.AssetDatabase.CreateAsset(setting, $"{DefaultResourcesPath()}/{typeof(T).Name}.asset"); | ||
UnityEditor.AssetDatabase.SaveAssets(); | ||
UnityEditor.AssetDatabase.Refresh(); | ||
|
||
Debug.Log($"{typeof(T).Name} was created ad {DefaultResourcesPath()}/{typeof(T).Name}.asset"); | ||
} | ||
|
||
private string DefaultResourcesPath() | ||
{ | ||
const string defaultResourcePath = "Assets/_Root/Resources"; | ||
if (!Directory.Exists(defaultResourcePath)) | ||
{ | ||
Directory.CreateDirectory(defaultResourcePath); | ||
} | ||
|
||
return defaultResourcePath; | ||
} | ||
#endif | ||
} | ||
} |