diff --git a/README.md b/README.md index 87616bb0..f2a8f75e 100644 --- a/README.md +++ b/README.md @@ -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", +``` \ No newline at end of file diff --git a/README.md.meta b/README.md.meta new file mode 100644 index 00000000..d47ae48e --- /dev/null +++ b/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7b4ab53c22cea684aa8898738b406520 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky.meta b/VirtueSky.meta new file mode 100644 index 00000000..5db4ee02 --- /dev/null +++ b/VirtueSky.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 284b2e8243e944a4782887d76e984d71 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Attributes.meta b/VirtueSky/Attributes.meta new file mode 100644 index 00000000..14663866 --- /dev/null +++ b/VirtueSky/Attributes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9b6ce13cae9bc7b49a0fb0d24d96e0e6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Attributes/GUIDAttribute.cs b/VirtueSky/Attributes/GUIDAttribute.cs new file mode 100644 index 00000000..4b4cb83d --- /dev/null +++ b/VirtueSky/Attributes/GUIDAttribute.cs @@ -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 +} \ No newline at end of file diff --git a/VirtueSky/Attributes/GUIDAttribute.cs.meta b/VirtueSky/Attributes/GUIDAttribute.cs.meta new file mode 100644 index 00000000..3e6c40da --- /dev/null +++ b/VirtueSky/Attributes/GUIDAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: af21dbdd68a58c54b9e7cac394dd19f2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Attributes/NamedIdAttribute.cs b/VirtueSky/Attributes/NamedIdAttribute.cs new file mode 100644 index 00000000..85e6efd0 --- /dev/null +++ b/VirtueSky/Attributes/NamedIdAttribute.cs @@ -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 +} \ No newline at end of file diff --git a/VirtueSky/Attributes/NamedIdAttribute.cs.meta b/VirtueSky/Attributes/NamedIdAttribute.cs.meta new file mode 100644 index 00000000..4fd3cbd2 --- /dev/null +++ b/VirtueSky/Attributes/NamedIdAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 14c317c6f93a4a74f8a96614615d0986 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Core.meta b/VirtueSky/Core.meta new file mode 100644 index 00000000..e59811b3 --- /dev/null +++ b/VirtueSky/Core.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0ad9f466005576c409d885df4181be0e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Core/BaseMono.cs b/VirtueSky/Core/BaseMono.cs new file mode 100644 index 00000000..c1ae1eb2 --- /dev/null +++ b/VirtueSky/Core/BaseMono.cs @@ -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(new string[] { "Assets" }).FirstOrDefault(); + if (ticker == null) + { + CreateSettingAssets(); + ticker = AssetUtils.FindAssetAtFolder(new string[] { "Assets" }).FirstOrDefault(); + } + + pools = AssetUtils.FindAssetAtFolder(new string[] { "Assets" }).FirstOrDefault(); + if (pools == null) + { + CreateSettingAssets(); + pools = AssetUtils.FindAssetAtFolder(new string[] { "Assets" }).FirstOrDefault(); + } + + EditorUtility.SetDirty(this); + } + + private void CreateSettingAssets() where T : ScriptableObject + { + var setting = UnityEngine.ScriptableObject.CreateInstance(); + 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 + } +} \ No newline at end of file diff --git a/VirtueSky/Core/BaseMono.cs.meta b/VirtueSky/Core/BaseMono.cs.meta new file mode 100644 index 00000000..07009889 --- /dev/null +++ b/VirtueSky/Core/BaseMono.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d730116726f0ce342bfe91266ac72fdf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Core/BaseSO.cs b/VirtueSky/Core/BaseSO.cs new file mode 100644 index 00000000..b8aae3d0 --- /dev/null +++ b/VirtueSky/Core/BaseSO.cs @@ -0,0 +1,155 @@ +using System.IO; +using System.Linq; +using UnityEditor; +using UnityEngine; +using VirtueSky.Attributes; +using VirtueSky.ObjectPooling; +using VirtueSky.Utils; + +namespace VirtueSky.Core +{ + public class BaseSO : ScriptableObject, IEntity + { + [SerializeField, NamedId] string id; + [Header("Base")] [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 + + public void Enable() + { + BindVariable(); + ListenEvents(); + SubTick(); + DoEnable(); + } + + public void Disable() + { + DoDisable(); + UnsubTick(); + //StopListenEvents(); + UnbindVariable(); + } + + public virtual void BindVariable() + { + } + + public virtual void ListenEvents() + { + } + + public void DoEnable() + { + } + + 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 Initialize() + { + } + + public virtual void EarlyTick() + { + } + + public virtual void Tick() + { + } + + public virtual void LateTick() + { + } + + public virtual void FixedTick() + { + } + + public virtual void CleanUp() + { + } + + public void DoDisable() + { + } + + 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(new string[] { "Assets" }).FirstOrDefault(); + if (ticker == null) + { + CreateSettingAssets(); + ticker = AssetUtils.FindAssetAtFolder(new string[] { "Assets" }).FirstOrDefault(); + } + + pools = AssetUtils.FindAssetAtFolder(new string[] { "Assets" }).FirstOrDefault(); + if (pools == null) + { + CreateSettingAssets(); + pools = AssetUtils.FindAssetAtFolder(new string[] { "Assets" }).FirstOrDefault(); + } + + EditorUtility.SetDirty(this); + } + + private void CreateSettingAssets() where T : ScriptableObject + { + var setting = UnityEngine.ScriptableObject.CreateInstance(); + 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 + } +} \ No newline at end of file diff --git a/VirtueSky/Core/BaseSO.cs.meta b/VirtueSky/Core/BaseSO.cs.meta new file mode 100644 index 00000000..519a3798 --- /dev/null +++ b/VirtueSky/Core/BaseSO.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8e70f299e69a94d48863d0a992365d4f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Core/IEntity.cs b/VirtueSky/Core/IEntity.cs new file mode 100644 index 00000000..e5e9e7aa --- /dev/null +++ b/VirtueSky/Core/IEntity.cs @@ -0,0 +1,18 @@ +namespace VirtueSky.Core +{ + public interface IEntity + { + void BindVariable(); + void ListenEvents(); + void DoEnable(); + void Initialize(); + void EarlyTick(); + void Tick(); + void LateTick(); + void FixedTick(); + void CleanUp(); + void DoDisable(); + void StopListenEvents(); + void UnbindVariable(); + } +} \ No newline at end of file diff --git a/VirtueSky/Core/IEntity.cs.meta b/VirtueSky/Core/IEntity.cs.meta new file mode 100644 index 00000000..b0a98b49 --- /dev/null +++ b/VirtueSky/Core/IEntity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef029fe4bbaf08c458fe914d4788a11e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Core/Ticker.cs b/VirtueSky/Core/Ticker.cs new file mode 100644 index 00000000..7d21255d --- /dev/null +++ b/VirtueSky/Core/Ticker.cs @@ -0,0 +1,117 @@ +using System; +using UnityEditor; +using UnityEngine; +using VirtueSky.Utils; + +namespace VirtueSky.Core +{ + //[CreateAssetMenu] + public class Ticker : ScriptableObject + { + event Action OnEarlyTickEvent; + event Action OnTickEvent; + event Action OnFixedTickEvent; + event Action OnLateTickEvent; + + TickerMono tickerMono; + + public void SubEarlyTick(IEntity entity) + { + Validate(); + OnEarlyTickEvent += entity.EarlyTick; + } + + public void UnsubEarlyTick(IEntity entity) + { + OnEarlyTickEvent -= entity.EarlyTick; + } + + public void SubTick(IEntity entity) + { + Validate(); + OnTickEvent += entity.Tick; + } + + public void UnsubTick(IEntity entity) + { + OnTickEvent -= entity.Tick; + } + + public void SubLateTick(IEntity entity) + { + Validate(); + OnLateTickEvent += entity.LateTick; + } + + public void UnsubLateTick(IEntity entity) + { + OnLateTickEvent -= entity.LateTick; + } + + public void SubFixedTick(IEntity entity) + { + Validate(); + OnFixedTickEvent += entity.FixedTick; + } + + public void UnsubFixedTick(IEntity entity) + { + OnFixedTickEvent -= entity.FixedTick; + } + + public void EarlyTick() + { + OnEarlyTickEvent?.Invoke(); + } + + public void Tick() + { + OnTickEvent?.Invoke(); + // DOTween.ManualUpdate(Time.deltaTime, Time.unscaledDeltaTime); + } + + public void LateTick() + { + OnLateTickEvent?.Invoke(); + } + + public void FixedTick() + { + OnFixedTickEvent?.Invoke(); + } + + void Validate() + { + if (!tickerMono) + { + GameObject obj = new GameObject("Ticker"); + tickerMono = obj.AddComponent(); + tickerMono.Ticker = this; + } + } + +#if UNITY_EDITOR + [ContextMenu("Auto Bind")] + public void AutoBind() + { + var soes = AssetUtils.FindAssetAtFolder(new string[] { "Assets" }); + foreach (var so in soes) + { + so.ticker = this; + EditorUtility.SetDirty(so); + } + + var goes = AssetUtils.FindAssetAtFolder(new string[] { "Assets" }); + foreach (var go in goes) + { + var monoes = go.GetComponentsInChildren(true); + foreach (var mono in monoes) + { + mono.ticker = this; + EditorUtility.SetDirty(mono); + } + } + } +#endif + } +} \ No newline at end of file diff --git a/VirtueSky/Core/Ticker.cs.meta b/VirtueSky/Core/Ticker.cs.meta new file mode 100644 index 00000000..5fc5c292 --- /dev/null +++ b/VirtueSky/Core/Ticker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9e0774d8e4d45904f8721ba0ce2e46e7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Core/TickerMono.cs b/VirtueSky/Core/TickerMono.cs new file mode 100644 index 00000000..d0167c3c --- /dev/null +++ b/VirtueSky/Core/TickerMono.cs @@ -0,0 +1,30 @@ +using UnityEngine; + +namespace VirtueSky.Core +{ + public class TickerMono : MonoBehaviour + { + public Ticker Ticker { get; set; } + + void Start() + { + DontDestroyOnLoad(gameObject); + } + + void Update() + { + Ticker.EarlyTick(); + Ticker.Tick(); + } + + void FixedUpdate() + { + Ticker.FixedTick(); + } + + void LateUpdate() + { + Ticker.LateTick(); + } + } +} \ No newline at end of file diff --git a/VirtueSky/Core/TickerMono.cs.meta b/VirtueSky/Core/TickerMono.cs.meta new file mode 100644 index 00000000..9d6383dd --- /dev/null +++ b/VirtueSky/Core/TickerMono.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 53b6a565cbc2e0843b41138a1fee1805 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/DataStorage.meta b/VirtueSky/DataStorage.meta new file mode 100644 index 00000000..02576159 --- /dev/null +++ b/VirtueSky/DataStorage.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 791968b3b56ca3946a6a7051703192c5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/DataStorage/DataStorage.cs b/VirtueSky/DataStorage/DataStorage.cs new file mode 100644 index 00000000..cf1fe5e4 --- /dev/null +++ b/VirtueSky/DataStorage/DataStorage.cs @@ -0,0 +1,179 @@ +using System; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; +using UnityEngine; + +namespace VirtueSky.DataStorage +{ + public class DataStorage + { + string BackupPath => path + "-bak"; + string path; + + PersistentData data; + + public DataStorage(string name) + { + path = GetDataPath(name); + var bakPath = BackupPath; + + if (File.Exists(bakPath) && !File.Exists(path)) + { + Debug.LogErrorFormat("Recover {0} from {1}", path, bakPath); + File.Move(bakPath, path); + } + + if (!File.Exists(path)) + { + data = new PersistentData(); + return; + } + + try + { + using (var stream = new FileStream(path, FileMode.OpenOrCreate)) + { + data = Deserialize(stream); + } + } + catch (Exception e) + { + Debug.LogErrorFormat("Exception deserialize {0}: {1} {2}", path, e.Message, e.StackTrace); + } + + if (data == null) + { + data = new PersistentData(); + } + } + + public void Save() + { + var bakPath = BackupPath; + var tmpPath = path + "-tmp"; + + try + { + if (File.Exists(path)) + { + if (File.Exists(bakPath)) File.Delete(bakPath); + File.Move(path, bakPath); + } + + using (var stream = new FileStream(tmpPath, FileMode.Create)) + { + Serialize(data, stream); + } + + File.Move(tmpPath, path); + File.Delete(bakPath); + } + catch (Exception e) + { + Debug.LogErrorFormat("Saving {0} error {1} {2}", path, e.Message, e.StackTrace); + throw; + } + + using (var stream = new FileStream(path, FileMode.Create)) + { + Serialize(data, stream); + } + + Debug.LogFormat("Saving {0} successfully", path); + } + + string GetDataPath(string name) + { + var persistentDataPath = GetPersistentDataPath(); + if (!Directory.Exists(persistentDataPath)) + { + Directory.CreateDirectory(persistentDataPath); + } + + return Path.Combine(persistentDataPath, name); + } + + public static string GetPersistentDataPath() + { +#if UNITY_EDITOR + return Path.Combine(Directory.GetParent(Application.dataPath).FullName, "TempDataStorage"); +#else + return Application.persistentDataPath; +#endif + } + + public object this[string key] + { + get => data.TryGetValue(key, out var pd) ? pd : default; + set => data.Set(key, value); + } + + public bool ContainsKey(string key) + { + return data.ContainsKey(key); + } + + public void Remove(string key) + { + data.Remove(key); + } + + public void Clear() + { + data.Clear(); + } + + void Serialize(object d, Stream stream) + { + var formatter = new BinaryFormatter(); + formatter.Serialize(stream, d); + } + + PersistentData Deserialize(Stream stream) + { + var formatter = new BinaryFormatter(); + return formatter.Deserialize(stream) as PersistentData; + } + + T To(object input, T defaultValue) + { + var result = defaultValue; + + if (typeof(T).IsEnum) + { + result = (T)Enum.ToObject(typeof(T), To(input, Convert.ToInt32(defaultValue))); + } + else + { + result = (T)Convert.ChangeType(input, typeof(T)); + } + + return result; + } + + public T Get(string key, T defaultValue = default(T)) + { + if (data.TryGetValue(key, out var value)) + { + return To(value, defaultValue); + } + + return defaultValue; + } + + public void Set(string key, T value) + { + this[key] = value; + } + + public void Load(IDataPersistent persistentData, bool root = false) + { + data.Load(persistentData, root); + } + + public void Store(IDataPersistent persistentData, bool root = false) + { + data.Store(persistentData, root); + } + } +} \ No newline at end of file diff --git a/VirtueSky/DataStorage/DataStorage.cs.meta b/VirtueSky/DataStorage/DataStorage.cs.meta new file mode 100644 index 00000000..9d1c34b9 --- /dev/null +++ b/VirtueSky/DataStorage/DataStorage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a212b4a94d8495f41a5d563c7dab62e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/DataStorage/GameData.cs b/VirtueSky/DataStorage/GameData.cs new file mode 100644 index 00000000..061812fe --- /dev/null +++ b/VirtueSky/DataStorage/GameData.cs @@ -0,0 +1,55 @@ +using VirtueSky.Utils; + +namespace VirtueSky.DataStorage +{ + public static partial class GameData + { + const string LAST_LOGIN_TIME_KEY = "LAST_LOGIN_TIME"; + const string LAST_ACTIVE_TIME_KEY = "LAST_ACTIVE_TIME"; + + static DataStorage _storage; + static DataStorage Storage => _storage ?? (_storage = new DataStorage("data.dat")); + + public static double LastLoginTime + { + get => TimeUtils.TicksToSeconds(Storage.Get(LAST_LOGIN_TIME_KEY)); + set => Storage.Set(LAST_LOGIN_TIME_KEY, TimeUtils.SecondsToTicks(value)); + } + + public static double LastActiveTime + { + get => TimeUtils.TicksToSeconds(Storage.Get(LAST_ACTIVE_TIME_KEY)); + set => Storage.Set(LAST_ACTIVE_TIME_KEY, TimeUtils.SecondsToTicks(value)); + } + + public static T Get(string key, T defaultValue = default) + { + return Storage.Get(key, defaultValue); + } + + public static void Set(string key, T data) + { + Storage[key] = data; + } + + public static void Load(IDataPersistent dataPersistent, bool root = false) + { + Storage.Load(dataPersistent, root); + } + + public static void Store(IDataPersistent dataPersistent, bool root = false) + { + Storage.Store(dataPersistent, root); + } + + public static void Save() + { + Storage.Save(); + } + + public static void Clear() + { + _storage = null; + } + } +} \ No newline at end of file diff --git a/VirtueSky/DataStorage/GameData.cs.meta b/VirtueSky/DataStorage/GameData.cs.meta new file mode 100644 index 00000000..632284af --- /dev/null +++ b/VirtueSky/DataStorage/GameData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5b92dfce44ac6d249b3fc916aafbb42d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/DataStorage/IDataPersistent.cs b/VirtueSky/DataStorage/IDataPersistent.cs new file mode 100644 index 00000000..c72a4532 --- /dev/null +++ b/VirtueSky/DataStorage/IDataPersistent.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json; + +namespace VirtueSky.DataStorage +{ + public interface IDataPersistent + { + string Key { get; } + void LoadData(PersistentData data); + void StoreData(PersistentData data); + } + + [Serializable] + public class PersistentData : AbstractPersistentData + { + public T GetOrCreate(string key) where T : new() + { + if (ContainsKey(key)) return Get(key); + + var value = new T(); + Set(key, value); + return value; + } + + public void Store(IDataPersistent target, bool root = false) + { + var data = root ? this : GetOrCreate(target.Key); + target.StoreData(data); + } + + public void Load(IDataPersistent target, bool root = false) + { + var data = root ? this : Get(target.Key); + if (data != null) target.LoadData(data); + } + + public void Store(string key, IDataPersistent target) + { + var pd = new PersistentData(); + target.StoreData(pd); + Set(key, pd); + } + + public void Load(string key, IDataPersistent target) + { + var pd = Get(key); + if (pd != null) target.LoadData(pd); + } + + public void ClearMaintainChildren() + { + var keys = this.Select(p => p.Key).ToList(); + foreach (var k in keys) + { + if (TryGetValue(k, out var val)) + { + if (val is PersistentData childPD) childPD.ClearMaintainChildren(); + else Remove(k); + } + } + } + } + + [Serializable, JsonObject(MemberSerialization.OptIn)] + public class AbstractPersistentData : IEnumerable> + { + [JsonProperty] Dictionary data; + + public AbstractPersistentData() + { + data = new Dictionary(); + } + + public bool TryGetValue(K key, out V value) + { + return data.TryGetValue(key, out value); + } + + public bool TryGet(K key, out T value) + { + value = default; + if (!data.TryGetValue(key, out V v)) return false; + value = To(v, default(T)); + return true; + } + + public T Get(K key, T defaultValue = default) + { + return data.TryGetValue(key, out var value) ? To(value, defaultValue) : defaultValue; + } + + public void Set(K key, V value) => data[key] = value; + + public bool ContainsKey(K key) => data.ContainsKey(key); + public void Remove(K key) => data.Remove(key); + public void Clear() => data.Clear(); + + public IEnumerator> GetEnumerator() => data.GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public static T To(object input, T defaultValue) + { + T result; + if (typeof(T).IsEnum) + { + result = (T)Enum.ToObject(typeof(T), To(input, Convert.ToInt32(defaultValue))); + } + else + { + result = (T)Convert.ChangeType(input, typeof(T)); + } + + return result; + } + } +} \ No newline at end of file diff --git a/VirtueSky/DataStorage/IDataPersistent.cs.meta b/VirtueSky/DataStorage/IDataPersistent.cs.meta new file mode 100644 index 00000000..83e18ca9 --- /dev/null +++ b/VirtueSky/DataStorage/IDataPersistent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c2e8840cdd618ef4fb642803d9ff1e30 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/DataType.meta b/VirtueSky/DataType.meta new file mode 100644 index 00000000..e9e00fb0 --- /dev/null +++ b/VirtueSky/DataType.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e272376fd682f6b46a867b4eab4fc8cc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/DataType/SVector2.cs b/VirtueSky/DataType/SVector2.cs new file mode 100644 index 00000000..47421ab6 --- /dev/null +++ b/VirtueSky/DataType/SVector2.cs @@ -0,0 +1,27 @@ +using UnityEngine; +using Newtonsoft.Json; + +namespace VirtueSky.DataType +{ + [System.Serializable, JsonObject(MemberSerialization.OptIn)] + public struct SVector2 + { + [JsonProperty] public float x; + [JsonProperty] public float y; + + public SVector2(float x, float y) + { + this.x = x; + this.y = y; + } + + public SVector2(Vector2 v) + { + x = v.x; + y = v.y; + } + + public static implicit operator Vector2(SVector2 v) => new Vector2(v.x, v.y); + public static explicit operator SVector2(Vector2 v) => new SVector2(v); + } +} \ No newline at end of file diff --git a/VirtueSky/DataType/SVector2.cs.meta b/VirtueSky/DataType/SVector2.cs.meta new file mode 100644 index 00000000..8d57a5a4 --- /dev/null +++ b/VirtueSky/DataType/SVector2.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ec09676100c54fc3a40bba1e1bc18b1d +timeCreated: 1635094465 \ No newline at end of file diff --git a/VirtueSky/DataType/SVector3.cs b/VirtueSky/DataType/SVector3.cs new file mode 100644 index 00000000..dde2e46c --- /dev/null +++ b/VirtueSky/DataType/SVector3.cs @@ -0,0 +1,23 @@ +using Newtonsoft.Json; +using UnityEngine; + +namespace VirtueSky.DataType +{ + [System.Serializable, JsonObject(MemberSerialization.OptIn)] + public struct SVector3 + { + [Newtonsoft.Json.JsonProperty] public float x; + [Newtonsoft.Json.JsonProperty] public float y; + [Newtonsoft.Json.JsonProperty] public float z; + + public SVector3(Vector3 v) + { + x = v.x; + y = v.y; + z = v.z; + } + + public static implicit operator Vector3(SVector3 v) => new Vector3(v.x, v.y, v.z); + public static explicit operator SVector3(Vector3 v) => new SVector3(v); + } +} \ No newline at end of file diff --git a/VirtueSky/DataType/SVector3.cs.meta b/VirtueSky/DataType/SVector3.cs.meta new file mode 100644 index 00000000..7398e14f --- /dev/null +++ b/VirtueSky/DataType/SVector3.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: daa9d2684efb4edf9e81298426e7bada +timeCreated: 1628525719 \ No newline at end of file diff --git a/VirtueSky/DataType/ShortDouble.Units.cs b/VirtueSky/DataType/ShortDouble.Units.cs new file mode 100644 index 00000000..dac04f5f --- /dev/null +++ b/VirtueSky/DataType/ShortDouble.Units.cs @@ -0,0 +1,184 @@ +using System; + +namespace VirtueSky.DataType +{ + public partial struct ShortDouble + { + static Unit FindUnit(double value) + { + return _unitFinder.Invoke(value); + } + + public static class Unit0 + { + static readonly Unit[] Units; + static readonly Unit Infinity; + static readonly Unit Zero; + + static Unit0() + { + Infinity.exponent = 0; + Infinity.name = "(VeryBIG)"; + Zero.exponent = 0; + Zero.name = ""; + + Units = new Unit[120]; + var i = 0; + + Units[i++].name = ""; + Units[i - 1].exponent = (i - 1) * 3; + + Units[i++].name = "k"; + Units[i - 1].exponent = (i - 1) * 3; + + Units[i++].name = "m"; + Units[i - 1].exponent = (i - 1) * 3; + + Units[i++].name = "b"; + Units[i - 1].exponent = (i - 1) * 3; + + Units[i++].name = "t"; + Units[i - 1].exponent = (i - 1) * 3; + + + for (var c0 = 'a'; c0 <= 'z'; c0++) + { + for (var c1 = c0; c1 <= 'z'; c1++) + { + if (i >= Units.Length) + { + break; + } + + Units[i++].name = c0.ToString() + c1.ToString(); + Units[i - 1].exponent = (i - 1) * 3; + } + } + } + + public static Unit Find(double value) + { + //extract + + var e = Math.Log10(Math.Abs(value)); + var fe = Math.Floor(e); + + var exponent = Math.DivRem((long)fe, 3, out _) * 3; + + //find + if (exponent < 0) + return Zero; + return exponent / 3 < Units.Length ? Units[exponent / 3] : Infinity; + } + } + + public static class Unit1 + { + static readonly Unit[] Units; + static readonly Unit Infinity; + static readonly Unit Zero; + + static Unit1() + { + Infinity.exponent = 0; + Infinity.name = "(VeryBIG)"; + Zero.exponent = 0; + Zero.name = ""; + + Units = new Unit[304]; + var i = 0; + + Units[i++].name = ""; + Units[i - 1].exponent = (i - 1) * 3; + + Units[i++].name = "K"; + Units[i - 1].exponent = (i - 1) * 3; + + Units[i++].name = "M"; + Units[i - 1].exponent = (i - 1) * 3; + + Units[i++].name = "B"; + Units[i - 1].exponent = (i - 1) * 3; + + Units[i++].name = "T"; + Units[i - 1].exponent = (i - 1) * 3; + + var exp = 14; + for (var j = i; j < Units.Length; j++) + { + Units[j].name = "e" + (++exp); + Units[j].exponent = exp; + } + } + + public static Unit Find(double value) + { + //extract + long exponent; + + var e = Math.Log10(Math.Abs(value)); + var fe = Math.Floor(e); + + if (fe < 15) + { + exponent = Math.DivRem((long)fe, 3, out _) * 3; + } + else + exponent = (long)fe; + + //find + if (exponent < 0) + return Zero; + if (exponent < 15) + return Units[exponent / 3]; + return exponent < Units.Length + 5 ? Units[15 / 3 + exponent - 15] : Infinity; + } + } + + public static class Unit2 + { + private static readonly Unit[] Units; + private static readonly Unit Infinity; + private static readonly Unit Zero; + + private static readonly string[] Signs = + { + "", "k", "m", "b", "t", "q", "Q", "s", "S", "o", "n", "d", "u", + "Du", "Tr", "Qu", "Qi", "Sx", "Sp", "Oc", "No", "Vi", "Ce" + }; + + static Unit2() + { + Infinity.exponent = 0; + Infinity.name = "(VeryBIG)"; + Zero.exponent = 0; + Zero.name = ""; + + Units = new Unit[Signs.Length]; + for (var i = 0; i < Signs.Length; i++) + { + Units[i].name = Signs[i]; + Units[i].exponent = i * 3; + } + } + + public static Unit Find(double value) + { + var e = Math.Log10(Math.Abs(value)); + var fe = Math.Floor(e); + + var exponent = Math.DivRem((long)fe, 3, out long remainder) * 3; + + if (exponent < 0) + return Zero; + return exponent / 3 < Units.Length ? Units[exponent / 3] : Infinity; + } + } + + public struct Unit + { + public int exponent; + public string name; + } + } +} \ No newline at end of file diff --git a/VirtueSky/DataType/ShortDouble.Units.cs.meta b/VirtueSky/DataType/ShortDouble.Units.cs.meta new file mode 100644 index 00000000..bb8eec81 --- /dev/null +++ b/VirtueSky/DataType/ShortDouble.Units.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7c10ed2d72cf4d26ba8c0bdfe8ec3d7f +timeCreated: 1617701321 \ No newline at end of file diff --git a/VirtueSky/DataType/ShortDouble.cs b/VirtueSky/DataType/ShortDouble.cs new file mode 100644 index 00000000..869b0f69 --- /dev/null +++ b/VirtueSky/DataType/ShortDouble.cs @@ -0,0 +1,143 @@ +using System; +using System.Runtime.InteropServices; +using Newtonsoft.Json; +using UnityEditor; +using UnityEngine; + +namespace VirtueSky.DataType +{ + [Serializable, JsonObject(MemberSerialization.OptIn)] + public partial struct ShortDouble : IFormattable, IComparable, IEquatable, + IComparable + { + static Func _unitFinder; + + static ShortDouble() + { + _unitFinder = Unit0.Find; + } + + [SerializeField] double value; + + public ShortDouble(double value = 0) + { + this.value = value; + } + + public double Value => value; + + // Implicit convert double to SecuredDouble + public static implicit operator ShortDouble(double value) => new ShortDouble(value); + + // Implicit convert SecuredDouble to double + public static implicit operator double(ShortDouble value) => value.Value; + + public static ShortDouble operator +(ShortDouble a, ShortDouble b) => + new ShortDouble(a.Value + b.Value); + + public static ShortDouble operator -(ShortDouble a, ShortDouble b) => + new ShortDouble(a.Value - b.Value); + + public static ShortDouble operator *(ShortDouble a, ShortDouble b) => + new ShortDouble(a.Value * b.Value); + + public static ShortDouble operator /(ShortDouble a, ShortDouble b) => + new ShortDouble(a.Value / b.Value); + + public static bool operator >(ShortDouble a, ShortDouble b) => a.Value > b.Value; + public static bool operator >=(ShortDouble a, ShortDouble b) => a.Value >= b.Value; + public static bool operator <(ShortDouble a, ShortDouble b) => a.Value < b.Value; + public static bool operator <=(ShortDouble a, ShortDouble b) => a.Value <= b.Value; + + public ShortDouble Floor => new ShortDouble(Math.Floor(Value)); + public ShortDouble Ceiling => new ShortDouble(Math.Ceiling(Value)); + public ShortDouble Round => new ShortDouble(Math.Round(Value)); + + public float AsFloat() => (float)Value; + public long AsLong() => (long)Value; + public bool AsBool(float eps = 0.3f) => Value > eps; + public int AsInt() => (int)Value; + public bool True => AsBool(); + + public ShortDouble Pow(double p) => new ShortDouble(Math.Pow(Value, p)); + public static ShortDouble Max(ShortDouble a, ShortDouble b) => a > b ? a : b; + public static ShortDouble Min(ShortDouble a, ShortDouble b) => a > b ? b : a; + + public static ShortDouble Clamp(ShortDouble value, ShortDouble min, ShortDouble max) => + value < min ? min : (value > max ? max : value); + + public int CompareTo(ShortDouble other) => Value.CompareTo(other.Value); + public int CompareTo(object obj) => Value.CompareTo(obj); + + public bool Equals(ShortDouble other) => Value.Equals(other.Value); + + public override bool Equals(object other) + { + if (other == null || GetType() != other.GetType()) return false; + return Value.Equals(((ShortDouble)other).Value); + } + + public override int GetHashCode() => Value.GetHashCode(); + + public override string ToString() => ToString(FindUnit(Value), "0.#"); + public string ToString(string format) => ToString(FindUnit(Value), format); + public string ToString(IFormatProvider provider) => Value.ToString(provider); + public string ToString(string format, IFormatProvider provider) => ToString(FindUnit(Value), format, provider); + + string ToString(Unit unit, string format = "0.##") + { + if (double.IsInfinity(Value) || double.IsNaN(Value)) + { + return "Infinity or NaN"; + } + + return (Value / System.Math.Pow(10, unit.exponent)).ToString(format) + unit.name; + } + + string ToString(Unit unit, string format, IFormatProvider provider) + { + if (double.IsInfinity(Value) || double.IsNaN(Value)) + { + return "Infinity or NaN"; + } + + return (Value / System.Math.Pow(10, unit.exponent)).ToString(format, provider) + unit.name; + } + + public static void SetUnit(int u) + { + if (u == 0) + { + _unitFinder = Unit0.Find; + } + else if (u == 1) + { + _unitFinder = Unit1.Find; + } + else + { + _unitFinder = Unit2.Find; + } + } + } + +#if UNITY_EDITOR + [CustomPropertyDrawer(typeof(ShortDouble))] + public class ShortDoubleDrawer : PropertyDrawer + { + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + EditorGUI.BeginProperty(position, label, property); + + position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); + + var indent = EditorGUI.indentLevel; + EditorGUI.indentLevel = 0; + EditorGUI.PropertyField(position, property.FindPropertyRelative("value"), GUIContent.none); + EditorGUI.indentLevel = indent; + + EditorGUI.EndProperty(); + } + } +#endif +} \ No newline at end of file diff --git a/VirtueSky/DataType/ShortDouble.cs.meta b/VirtueSky/DataType/ShortDouble.cs.meta new file mode 100644 index 00000000..59946ca4 --- /dev/null +++ b/VirtueSky/DataType/ShortDouble.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3a7fad66991554a129cbbd53d0878356 +timeCreated: 1504925677 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/EditorUtils.meta b/VirtueSky/EditorUtils.meta new file mode 100644 index 00000000..394c12c9 --- /dev/null +++ b/VirtueSky/EditorUtils.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f6bb609d13a41f0409be48f8c75fb746 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/EditorUtils/EditorGUIUtils.cs b/VirtueSky/EditorUtils/EditorGUIUtils.cs new file mode 100644 index 00000000..056598af --- /dev/null +++ b/VirtueSky/EditorUtils/EditorGUIUtils.cs @@ -0,0 +1,192 @@ +#if UNITY_EDITOR +using UnityEditor; +using UnityEngine; + +namespace VirtueSky.EditorUtils +{ + public static class EditorGUIUtils + { + public class DisabledGUI : System.IDisposable + { + bool enabled; + + public DisabledGUI(bool disable) + { + enabled = GUI.enabled; + GUI.enabled = !disable; + } + + public void Dispose() + { + GUI.enabled = enabled; + } + } + + public class GUIColor : System.IDisposable + { + Color c; + + public GUIColor(Color c) + { + this.c = GUI.color; + GUI.color = c; + } + + public void Dispose() + { + GUI.color = c; + } + } + + public class BackgroundColor : System.IDisposable + { + Color c; + + public BackgroundColor(Color c) + { + this.c = GUI.color; + GUI.backgroundColor = c; + } + + public void Dispose() + { + GUI.backgroundColor = c; + } + } + + public class GizmosColor : System.IDisposable + { + Color c; + + public GizmosColor(Color c) + { + this.c = Gizmos.color; + Gizmos.color = c; + } + + public void Dispose() + { + Gizmos.color = c; + } + } + + public class HandlesColor : System.IDisposable + { + Color c; + + public HandlesColor(Color c) + { + this.c = Handles.color; + Handles.color = c; + } + + public void Dispose() + { + Handles.color = c; + } + } + + public class VerticalHelpBox : System.IDisposable + { + public VerticalHelpBox(params GUILayoutOption[] options) + { + EditorGUILayout.BeginVertical(EditorStyles.helpBox, options); + } + + public void Dispose() + { + EditorGUILayout.EndVertical(); + } + } + + public class HorizontalHelpBox : System.IDisposable + { + public HorizontalHelpBox(params GUILayoutOption[] options) + { + EditorGUILayout.BeginHorizontal(EditorStyles.helpBox, options); + } + + public void Dispose() + { + EditorGUILayout.EndHorizontal(); + } + } + + public class ScrollView : System.IDisposable + { + public ScrollView(ref Vector2 pos) + { + pos = EditorGUILayout.BeginScrollView(pos); + } + + public void Dispose() + { + EditorGUILayout.EndScrollView(); + } + } + + public class HorizontalLayout : System.IDisposable + { + private bool centered; + + public HorizontalLayout(bool centered = false, params GUILayoutOption[] options) + { + this.centered = centered; + EditorGUILayout.BeginHorizontal(options); + if (centered) GUILayout.FlexibleSpace(); + } + + public void Dispose() + { + if (centered) GUILayout.FlexibleSpace(); + EditorGUILayout.EndHorizontal(); + } + } + + public class VerticalLayout : System.IDisposable + { + public VerticalLayout(params GUILayoutOption[] options) + { + EditorGUILayout.BeginVertical(options); + } + + public void Dispose() + { + EditorGUILayout.EndVertical(); + } + } + + public class LabelWidth : System.IDisposable + { + float originalWidth; + + public LabelWidth(float width) + { + originalWidth = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = width; + } + + public void Dispose() + { + EditorGUIUtility.labelWidth = originalWidth; + } + } + + public class Indent : System.IDisposable + { + int indent; + + public Indent(int indent = 1) + { + this.indent = indent; + EditorGUI.indentLevel += indent; + } + + public void Dispose() + { + EditorGUI.indentLevel -= indent; + } + } + } +} +#endif \ No newline at end of file diff --git a/VirtueSky/EditorUtils/EditorGUIUtils.cs.meta b/VirtueSky/EditorUtils/EditorGUIUtils.cs.meta new file mode 100644 index 00000000..33fa3d3e --- /dev/null +++ b/VirtueSky/EditorUtils/EditorGUIUtils.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d009654f54214548a829eb95f493f3f6 +timeCreated: 1658972649 \ No newline at end of file diff --git a/VirtueSky/EditorUtils/SceneMenu.cs b/VirtueSky/EditorUtils/SceneMenu.cs new file mode 100644 index 00000000..abd66dba --- /dev/null +++ b/VirtueSky/EditorUtils/SceneMenu.cs @@ -0,0 +1,112 @@ +#if UNITY_EDITOR +using System.IO; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine; +using UnityEngine.SceneManagement; + +namespace VirtueSky.EditorUtils +{ + public static class SceneMenu + { + // const string LevelEditorScene = "LevelEditorScene"; + // const string PrefabScene = "PrefabScene"; + // const string LauncherScene = "LauncherScene"; + // const string GameScene = "GameScene"; + // const string FarmScene = "FarmScene"; + // + // static void ChangeScene(string name) + // { + // EditorSceneManager.SaveOpenScenes(); + // EditorSceneManager.OpenScene(Application.dataPath + "/Scenes/" + name + ".unity"); + // } + // + // static bool CanChangeScene(string name) + // { + // return HasScene(name) && SceneManager.GetActiveScene().name != name; + // } + // + // static bool HasScene(string name) + // { + // return File.Exists(Application.dataPath + "/Scenes/" + name + ".unity"); + // } + // + // [MenuItem("Scenes/Level Editor Scene", false, 11)] + // static void OpenLevelEditorScene() + // { + // ChangeScene(LevelEditorScene); + // } + // + // [MenuItem("Scenes/Level Editor Scene", true, 11)] + // static bool CanOpenLevelEditorScene() + // { + // return CanChangeScene(LevelEditorScene); + // } + // + // [MenuItem("Scenes/Prefab Scene", false, 11)] + // static void OpenPrefabScene() + // { + // ChangeScene(PrefabScene); + // } + // + // [MenuItem("Scenes/Prefab Scene", true, 11)] + // static bool CanOpenPrefabScene() + // { + // return CanChangeScene(PrefabScene); + // } + // + // [MenuItem("Scenes/Launcher Scene", false, 22)] + // static void OpenLauncherScene() + // { + // ChangeScene(LauncherScene); + // } + // + // [MenuItem("Scenes/Launcher Scene", true, 22)] + // static bool CanOpenLauncherScene() + // { + // return CanChangeScene(LauncherScene); + // } + // + // [MenuItem("Scenes/Game Scene", false, 22)] + // static void OpenGameScene() + // { + // ChangeScene(GameScene); + // } + // + // [MenuItem("Scenes/Game Scene", true, 22)] + // static bool CanOpenGameScene() + // { + // return CanChangeScene(GameScene); + // } + // + // [MenuItem("Scenes/Farm Scene", false, 33)] + // static void OpenFarmScene() + // { + // ChangeScene(FarmScene); + // } + // + // [MenuItem("Scenes/Farm Scene", true, 33)] + // static bool CanOpenFarmScene() + // { + // return CanChangeScene(FarmScene); + // } + // + // [MenuItem("Scenes/Play", false, 44)] + // public static void PlayLauncherScene() + // { + // if (HasScene(LauncherScene)) + // { + // EditorSceneManager.SaveOpenScenes(); + // ChangeScene(LauncherScene); + // EditorApplication.isPlaying = true; + // } + // } + // + // [MenuItem("Scenes/Play", true, 44)] + // static bool CanPlayLauncherScene() + // { + // return HasScene(LauncherScene) && !Application.isPlaying; + // } + } +} +#endif \ No newline at end of file diff --git a/VirtueSky/EditorUtils/SceneMenu.cs.meta b/VirtueSky/EditorUtils/SceneMenu.cs.meta new file mode 100644 index 00000000..52129175 --- /dev/null +++ b/VirtueSky/EditorUtils/SceneMenu.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ee5447f6da2d4c73a0201e5fa4cfc3e4 +timeCreated: 1586794195 \ No newline at end of file diff --git a/VirtueSky/Events.meta b/VirtueSky/Events.meta new file mode 100644 index 00000000..bf8dd653 --- /dev/null +++ b/VirtueSky/Events.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 75f898c4077929444929383a64dde79b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/BaseEvent.cs b/VirtueSky/Events/BaseEvent.cs new file mode 100644 index 00000000..0c189ab3 --- /dev/null +++ b/VirtueSky/Events/BaseEvent.cs @@ -0,0 +1,145 @@ +using System.Collections.Generic; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using VirtueSky.Core; +using VirtueSky.EditorUtils; +using VirtueSky.Utils; + +namespace VirtueSky.Events +{ + public class BaseEvent : BaseSO, IEvent + { + readonly List listeners = new List(); + + public void Raise() + { +#if UNITY_EDITOR + // Debug.Log($"===> {name}"); +#endif + for (var i = listeners.Count - 1; i >= 0; i--) + { + listeners[i].OnEventRaised(this); + } + } + + public void AddListener(IEventListener listener) + { + if (!listeners.Contains(listener)) + { + listeners.Add(listener); + } + } + + public void RemoveListener(IEventListener listener) + { + if (listeners.Contains(listener)) + { + listeners.Remove(listener); + } + } + + public void RemoveAll() + { + listeners.Clear(); + } + } + + public class BaseEvent : BaseSO, IEvent + { + readonly List> listeners = new List>(); + + public virtual void Raise(TType value) + { +#if UNITY_EDITOR + //Debug.Log($"===> {name}"); +#endif + for (var i = listeners.Count - 1; i >= 0; i--) + { + listeners[i].OnEventRaised(this, value); + } + } + + public void AddListener(IEventListener listener) + { + if (!listeners.Contains(listener)) + { + listeners.Add(listener); + } + } + + public void RemoveListener(IEventListener listener) + { + if (listeners.Contains(listener)) + { + listeners.Remove(listener); + } + } + + public void RemoveAll() + { + listeners.Clear(); + } + } + +#if UNITY_EDITOR + [CustomEditor(typeof(BaseEvent), true)] + public class BaseEventEditor : Editor + { + BaseEvent baseEvent; + + void OnEnable() + { + baseEvent = target as BaseEvent; + } + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + if (GUILayout.Button("Raise")) + { + baseEvent.Raise(); + } + } + } + // + // [CustomEditor(typeof(BaseEvent<>), true)] + // public class TypedBaseEventEditor : Editor + // { + // public override void OnInspectorGUI() + // { + // base.OnInspectorGUI(); + // + // var debugProperty = serializedObject.FindProperty("debugValue"); + // + // if (debugProperty != null) + // { + // using (new EditorGUIUtils.VerticalHelpBox()) + // { + // using (var scope = new EditorGUI.ChangeCheckScope()) + // { + // EditorGUILayout.PropertyField(debugProperty, GUIContent.none); + // + // if (scope.changed) + // { + // serializedObject.ApplyModifiedProperties(); + // } + // } + // + // if (GUILayout.Button("Raise")) + // { + // var targetType = target.GetType(); + // var targetField = targetType.GetFieldRecursive("debugValue", + // BindingFlags.Instance | BindingFlags.NonPublic); + // var debugValue = targetField.GetValue(target); + // + // var raiseMethod = targetType.BaseType.GetMethod("Raise", + // BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); + // raiseMethod?.Invoke(target, new[] {debugValue}); + // } + // } + // } + // } + // } +#endif +} \ No newline at end of file diff --git a/VirtueSky/Events/BaseEvent.cs.meta b/VirtueSky/Events/BaseEvent.cs.meta new file mode 100644 index 00000000..58d1dff3 --- /dev/null +++ b/VirtueSky/Events/BaseEvent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7f885e714ddc92849ac280af904bba4f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/BaseEventListener.cs b/VirtueSky/Events/BaseEventListener.cs new file mode 100644 index 00000000..5d97f994 --- /dev/null +++ b/VirtueSky/Events/BaseEventListener.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Events; +using UnityEngine.Serialization; +using VirtueSky.Core; +using VirtueSky.Variables; + +namespace VirtueSky.Events +{ + public class BaseEventListener : BaseMono, IEventListener + where TEvent : BaseEvent + where TResponse : UnityEvent + { + [SerializeField] private BindingListener bindingListener; + [SerializeField] private List listEventResponseDatas = new List(); + private readonly Dictionary _dictionary = new Dictionary(); + + [Serializable] + public class EventResponseData + { + public TEvent @event; + public TResponse response; + } + + public override void ListenEvents() + { + base.ListenEvents(); + foreach (var t in listEventResponseDatas) + { + t.@event.AddListener(this); + _dictionary.TryAdd(t.@event, t.response); + } + } + + public override void StopListenEvents() + { + base.StopListenEvents(); + foreach (var t in listEventResponseDatas) + { + t.@event.RemoveListener(this); + if (_dictionary.ContainsKey(t.@event)) _dictionary.Remove(t.@event); + } + } + + public virtual void OnEventRaised(BaseEvent eventRaise) + { + _dictionary[eventRaise].Invoke(); + } + + public override void DoDisable() + { + base.DoDisable(); + if (bindingListener == BindingListener.UNTIL_DISABLE) + { + StopListenEvents(); + } + } + + public override void DoDestroy() + { + base.DoDestroy(); + if (bindingListener == BindingListener.UNTIL_DESTROY) + { + StopListenEvents(); + } + } + } + + public class BaseEventListener : BaseMono, IEventListener + where TEvent : BaseEvent + where TResponse : UnityEvent + { + [SerializeField] private BindingListener bindingListener; + + [SerializeField] protected List listEventResponseDatas = new List(); + + protected readonly Dictionary, UnityEvent> _dictionary = + new Dictionary, UnityEvent>(); + + [Serializable] + public class EventResponseData + { + public TEvent @event; + public TResponse response; + } + + public override void ListenEvents() + { + base.ListenEvents(); + foreach (var t in listEventResponseDatas) + { + t.@event.AddListener(this); + _dictionary.TryAdd(t.@event, t.response); + } + } + + public override void StopListenEvents() + { + base.StopListenEvents(); + foreach (var t in listEventResponseDatas) + { + t.@event.RemoveListener(this); + if (_dictionary.ContainsKey(t.@event)) _dictionary.Remove(t.@event); + } + } + + public virtual void OnEventRaised(BaseEvent eventRaise, TType value) + { + _dictionary[eventRaise].Invoke(value); + } + + public override void DoDisable() + { + base.DoDisable(); + if (bindingListener == BindingListener.UNTIL_DISABLE) + { + StopListenEvents(); + } + } + + public override void DoDestroy() + { + base.DoDestroy(); + if (bindingListener == BindingListener.UNTIL_DESTROY) + { + StopListenEvents(); + } + } + } +} + +public enum BindingListener +{ + UNTIL_DISABLE, + UNTIL_DESTROY +} \ No newline at end of file diff --git a/VirtueSky/Events/BaseEventListener.cs.meta b/VirtueSky/Events/BaseEventListener.cs.meta new file mode 100644 index 00000000..52f606f8 --- /dev/null +++ b/VirtueSky/Events/BaseEventListener.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1f85358eae4b4fedbec94383e714f35c +timeCreated: 1651562443 \ No newline at end of file diff --git a/VirtueSky/Events/BaseEventResponse.cs b/VirtueSky/Events/BaseEventResponse.cs new file mode 100644 index 00000000..6e855047 --- /dev/null +++ b/VirtueSky/Events/BaseEventResponse.cs @@ -0,0 +1,12 @@ +using UnityEngine.Events; + +namespace VirtueSky.Events +{ + public class BaseEventResponse : UnityEvent, IEventResponse + { + } + + public class BaseEventResponse : UnityEvent, IEventResponse + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/BaseEventResponse.cs.meta b/VirtueSky/Events/BaseEventResponse.cs.meta new file mode 100644 index 00000000..037f176f --- /dev/null +++ b/VirtueSky/Events/BaseEventResponse.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 893521d098d1429489b6dc83598b1b1b +timeCreated: 1651574321 \ No newline at end of file diff --git a/VirtueSky/Events/BaseListener.cs b/VirtueSky/Events/BaseListener.cs new file mode 100644 index 00000000..4423ba28 --- /dev/null +++ b/VirtueSky/Events/BaseListener.cs @@ -0,0 +1,6 @@ +namespace VirtueSky.Events +{ + public class BaseListener + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/BaseListener.cs.meta b/VirtueSky/Events/BaseListener.cs.meta new file mode 100644 index 00000000..c776b6ce --- /dev/null +++ b/VirtueSky/Events/BaseListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c8bf35bc47aa4924ca4ac5b34891fc8e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/BooleanEvent.cs b/VirtueSky/Events/BooleanEvent.cs new file mode 100644 index 00000000..4f00e66a --- /dev/null +++ b/VirtueSky/Events/BooleanEvent.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace VirtueSky.Events +{ + [CreateAssetMenu(menuName = "Event/Boolean Event")] + public class BooleanEvent : BaseEvent + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/BooleanEvent.cs.meta b/VirtueSky/Events/BooleanEvent.cs.meta new file mode 100644 index 00000000..d104107b --- /dev/null +++ b/VirtueSky/Events/BooleanEvent.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: aef918ec277845979450b0fbea88e78b +timeCreated: 1659151605 \ No newline at end of file diff --git a/VirtueSky/Events/BooleanEventListener.cs b/VirtueSky/Events/BooleanEventListener.cs new file mode 100644 index 00000000..734cb2bf --- /dev/null +++ b/VirtueSky/Events/BooleanEventListener.cs @@ -0,0 +1,6 @@ +namespace VirtueSky.Events +{ + public class BooleanEventListener : BaseEventListener + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/BooleanEventListener.cs.meta b/VirtueSky/Events/BooleanEventListener.cs.meta new file mode 100644 index 00000000..36c6460a --- /dev/null +++ b/VirtueSky/Events/BooleanEventListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fd08215cd3194a57bd070df5454b8d18 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/BooleanEventResponse.cs b/VirtueSky/Events/BooleanEventResponse.cs new file mode 100644 index 00000000..57575215 --- /dev/null +++ b/VirtueSky/Events/BooleanEventResponse.cs @@ -0,0 +1,9 @@ +using System; + +namespace VirtueSky.Events +{ + [Serializable] + public class BooleanEventResponse : BaseEventResponse + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/BooleanEventResponse.cs.meta b/VirtueSky/Events/BooleanEventResponse.cs.meta new file mode 100644 index 00000000..ad3c9b17 --- /dev/null +++ b/VirtueSky/Events/BooleanEventResponse.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f5c01c8b67014dfb83f095ecacbb35f4 +timeCreated: 1659151605 \ No newline at end of file diff --git a/VirtueSky/Events/DictionaryEvent.cs b/VirtueSky/Events/DictionaryEvent.cs new file mode 100644 index 00000000..565fdf0b --- /dev/null +++ b/VirtueSky/Events/DictionaryEvent.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace VirtueSky.Events +{ + [CreateAssetMenu(menuName = "Event/DictionaryEvent")] + public class DictionaryEvent : BaseEvent> + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/DictionaryEvent.cs.meta b/VirtueSky/Events/DictionaryEvent.cs.meta new file mode 100644 index 00000000..5c4911be --- /dev/null +++ b/VirtueSky/Events/DictionaryEvent.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 814787ad80ba44cea17a4a3b6d536ef1 +timeCreated: 1659155205 \ No newline at end of file diff --git a/VirtueSky/Events/DictionaryEventListener.cs b/VirtueSky/Events/DictionaryEventListener.cs new file mode 100644 index 00000000..ffb42025 --- /dev/null +++ b/VirtueSky/Events/DictionaryEventListener.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace VirtueSky.Events +{ + public class DictionaryEventListener : BaseEventListener, DictionaryEvent, DictionaryEventResponse> + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/DictionaryEventListener.cs.meta b/VirtueSky/Events/DictionaryEventListener.cs.meta new file mode 100644 index 00000000..2293fdd5 --- /dev/null +++ b/VirtueSky/Events/DictionaryEventListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 566e31263e25463eb7afbf70fdc47acc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/DictionaryEventResponse.cs b/VirtueSky/Events/DictionaryEventResponse.cs new file mode 100644 index 00000000..2bee1ddd --- /dev/null +++ b/VirtueSky/Events/DictionaryEventResponse.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; + +namespace VirtueSky.Events +{ + [Serializable] + public class DictionaryEventResponse : BaseEventResponse> + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/DictionaryEventResponse.cs.meta b/VirtueSky/Events/DictionaryEventResponse.cs.meta new file mode 100644 index 00000000..f353291b --- /dev/null +++ b/VirtueSky/Events/DictionaryEventResponse.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 55e065f206f040459d9ddb559fd3ad40 +timeCreated: 1659155254 \ No newline at end of file diff --git a/VirtueSky/Events/EventDispatcher.cs b/VirtueSky/Events/EventDispatcher.cs new file mode 100644 index 00000000..1f0bc08f --- /dev/null +++ b/VirtueSky/Events/EventDispatcher.cs @@ -0,0 +1,27 @@ +using UnityEngine; +using UnityEngine.Serialization; +using VirtueSky.Core; + +namespace VirtueSky.Events +{ + public class EventDispatcher : BaseMono + { + [FormerlySerializedAs("eventNoFunc")] [FormerlySerializedAs("scriptableEvent")] [FormerlySerializedAs("event")] [SerializeField] + EventNoParam eventNoParam; + + [SerializeField] bool dispatchOnEnable; + + public override void Initialize() + { + if (dispatchOnEnable) + { + Dispatch(); + } + } + + public void Dispatch() + { + eventNoParam.Raise(); + } + } +} \ No newline at end of file diff --git a/VirtueSky/Events/EventDispatcher.cs.meta b/VirtueSky/Events/EventDispatcher.cs.meta new file mode 100644 index 00000000..011856ca --- /dev/null +++ b/VirtueSky/Events/EventDispatcher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d84926e8dc214d729fb1253d81aca402 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/EventListenerNoParam.cs b/VirtueSky/Events/EventListenerNoParam.cs new file mode 100644 index 00000000..d3a5acfc --- /dev/null +++ b/VirtueSky/Events/EventListenerNoParam.cs @@ -0,0 +1,6 @@ +namespace VirtueSky.Events +{ + public class EventListenerNoParam : BaseEventListener + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/EventListenerNoParam.cs.meta b/VirtueSky/Events/EventListenerNoParam.cs.meta new file mode 100644 index 00000000..eed67404 --- /dev/null +++ b/VirtueSky/Events/EventListenerNoParam.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f477bc0650f64520ad655afc7aacef99 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/EventNoParam.cs b/VirtueSky/Events/EventNoParam.cs new file mode 100644 index 00000000..0f0feea5 --- /dev/null +++ b/VirtueSky/Events/EventNoParam.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace VirtueSky.Events +{ + [CreateAssetMenu(menuName = "Event/Event No Param")] + public class EventNoParam : BaseEvent + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/EventNoParam.cs.meta b/VirtueSky/Events/EventNoParam.cs.meta new file mode 100644 index 00000000..d0afb8eb --- /dev/null +++ b/VirtueSky/Events/EventNoParam.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 719558c56beb4a8d98cf058fadf5455a +timeCreated: 1651591065 \ No newline at end of file diff --git a/VirtueSky/Events/EventResponse.cs b/VirtueSky/Events/EventResponse.cs new file mode 100644 index 00000000..9b51a68d --- /dev/null +++ b/VirtueSky/Events/EventResponse.cs @@ -0,0 +1,9 @@ +using System; + +namespace VirtueSky.Events +{ + [Serializable] + public class EventResponse : BaseEventResponse + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/EventResponse.cs.meta b/VirtueSky/Events/EventResponse.cs.meta new file mode 100644 index 00000000..fdb64275 --- /dev/null +++ b/VirtueSky/Events/EventResponse.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: dbe3c2bf266f40799ca5f846bd5b42e9 +timeCreated: 1651572748 \ No newline at end of file diff --git a/VirtueSky/Events/FloatEvent.cs b/VirtueSky/Events/FloatEvent.cs new file mode 100644 index 00000000..b517e934 --- /dev/null +++ b/VirtueSky/Events/FloatEvent.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace VirtueSky.Events +{ + [CreateAssetMenu(menuName = "Event/Float Event")] + public class FloatEvent : BaseEvent + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/FloatEvent.cs.meta b/VirtueSky/Events/FloatEvent.cs.meta new file mode 100644 index 00000000..00077079 --- /dev/null +++ b/VirtueSky/Events/FloatEvent.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0d8122074d0747c0bcac7e533000ff1e +timeCreated: 1651590796 \ No newline at end of file diff --git a/VirtueSky/Events/FloatEventListener.cs b/VirtueSky/Events/FloatEventListener.cs new file mode 100644 index 00000000..981cb126 --- /dev/null +++ b/VirtueSky/Events/FloatEventListener.cs @@ -0,0 +1,6 @@ +namespace VirtueSky.Events +{ + public class FloatEventListener : BaseEventListener + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/FloatEventListener.cs.meta b/VirtueSky/Events/FloatEventListener.cs.meta new file mode 100644 index 00000000..93f57e42 --- /dev/null +++ b/VirtueSky/Events/FloatEventListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 995103f2e8fb4e2b9b064c3d37181c3d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/FloatEventResponse.cs b/VirtueSky/Events/FloatEventResponse.cs new file mode 100644 index 00000000..c9d0f103 --- /dev/null +++ b/VirtueSky/Events/FloatEventResponse.cs @@ -0,0 +1,9 @@ +using System; + +namespace VirtueSky.Events +{ + [Serializable] + public class FloatEventResponse : BaseEventResponse + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/FloatEventResponse.cs.meta b/VirtueSky/Events/FloatEventResponse.cs.meta new file mode 100644 index 00000000..c71f9bb0 --- /dev/null +++ b/VirtueSky/Events/FloatEventResponse.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 36073394bda540afb4697e351c927583 +timeCreated: 1651591152 \ No newline at end of file diff --git a/VirtueSky/Events/IEvent.cs b/VirtueSky/Events/IEvent.cs new file mode 100644 index 00000000..e851b81c --- /dev/null +++ b/VirtueSky/Events/IEvent.cs @@ -0,0 +1,18 @@ +namespace VirtueSky.Events +{ + public interface IEvent + { + void Raise(); + void AddListener(IEventListener listener); + void RemoveListener(IEventListener listener); + void RemoveAll(); + } + + public interface IEvent + { + void Raise(T value); + void AddListener(IEventListener listener); + void RemoveListener(IEventListener listener); + void RemoveAll(); + } +} \ No newline at end of file diff --git a/VirtueSky/Events/IEvent.cs.meta b/VirtueSky/Events/IEvent.cs.meta new file mode 100644 index 00000000..960d4051 --- /dev/null +++ b/VirtueSky/Events/IEvent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d2070d97c1045c34ea2aa99703681ff7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/IEventListener.cs b/VirtueSky/Events/IEventListener.cs new file mode 100644 index 00000000..0631967b --- /dev/null +++ b/VirtueSky/Events/IEventListener.cs @@ -0,0 +1,14 @@ +using UnityEngine.Events; + +namespace VirtueSky.Events +{ + public interface IEventListener + { + void OnEventRaised(BaseEvent eventRaise); + } + + public interface IEventListener + { + void OnEventRaised(BaseEvent eventRaise, TType value); + } +} \ No newline at end of file diff --git a/VirtueSky/Events/IEventListener.cs.meta b/VirtueSky/Events/IEventListener.cs.meta new file mode 100644 index 00000000..a50dcd0d --- /dev/null +++ b/VirtueSky/Events/IEventListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ea776ff2b47efba45aaaa97cd1d5b0e1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/IEventResponse.cs b/VirtueSky/Events/IEventResponse.cs new file mode 100644 index 00000000..8b59a721 --- /dev/null +++ b/VirtueSky/Events/IEventResponse.cs @@ -0,0 +1,6 @@ +namespace VirtueSky.Events +{ + public interface IEventResponse + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/IEventResponse.cs.meta b/VirtueSky/Events/IEventResponse.cs.meta new file mode 100644 index 00000000..83386a37 --- /dev/null +++ b/VirtueSky/Events/IEventResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d75ca69d3baf1944e9fcc175757ee9e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/IntegerEvent.cs b/VirtueSky/Events/IntegerEvent.cs new file mode 100644 index 00000000..110da2a1 --- /dev/null +++ b/VirtueSky/Events/IntegerEvent.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace VirtueSky.Events +{ + [CreateAssetMenu(menuName = "Event/Integer Event")] + public class IntegerEvent : BaseEvent + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/IntegerEvent.cs.meta b/VirtueSky/Events/IntegerEvent.cs.meta new file mode 100644 index 00000000..744261a0 --- /dev/null +++ b/VirtueSky/Events/IntegerEvent.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d6c2a70b0ee64462889213f36f37da24 +timeCreated: 1660313324 \ No newline at end of file diff --git a/VirtueSky/Events/IntegerEventListener.cs b/VirtueSky/Events/IntegerEventListener.cs new file mode 100644 index 00000000..279a4bc4 --- /dev/null +++ b/VirtueSky/Events/IntegerEventListener.cs @@ -0,0 +1,6 @@ +namespace VirtueSky.Events +{ + public class IntegerEventListener : BaseEventListener + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/IntegerEventListener.cs.meta b/VirtueSky/Events/IntegerEventListener.cs.meta new file mode 100644 index 00000000..24c6cfcc --- /dev/null +++ b/VirtueSky/Events/IntegerEventListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 16935cb5c30543f0b25ff56d4717ccf7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/IntegerEventResponse.cs b/VirtueSky/Events/IntegerEventResponse.cs new file mode 100644 index 00000000..0812af8f --- /dev/null +++ b/VirtueSky/Events/IntegerEventResponse.cs @@ -0,0 +1,9 @@ +using System; + +namespace VirtueSky.Events +{ + [Serializable] + public class IntegerEventResponse : BaseEventResponse + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/IntegerEventResponse.cs.meta b/VirtueSky/Events/IntegerEventResponse.cs.meta new file mode 100644 index 00000000..ab4a6426 --- /dev/null +++ b/VirtueSky/Events/IntegerEventResponse.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 605bf97dd8cf41b1bd5be70b2a0c5c20 +timeCreated: 1660313324 \ No newline at end of file diff --git a/VirtueSky/Events/ObjectEvent.cs b/VirtueSky/Events/ObjectEvent.cs new file mode 100644 index 00000000..7a7c7b55 --- /dev/null +++ b/VirtueSky/Events/ObjectEvent.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace VirtueSky.Events +{ + [CreateAssetMenu(menuName = "Event/Object Event")] + public class ObjectEvent : BaseEvent + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/ObjectEvent.cs.meta b/VirtueSky/Events/ObjectEvent.cs.meta new file mode 100644 index 00000000..1b636d80 --- /dev/null +++ b/VirtueSky/Events/ObjectEvent.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f13707fcbf06428493363549fe525368 +timeCreated: 1651572677 \ No newline at end of file diff --git a/VirtueSky/Events/ObjectEventListener.cs b/VirtueSky/Events/ObjectEventListener.cs new file mode 100644 index 00000000..1ef2eb5b --- /dev/null +++ b/VirtueSky/Events/ObjectEventListener.cs @@ -0,0 +1,8 @@ +using UnityEngine; + +namespace VirtueSky.Events +{ + public class ObjectEventListener : BaseEventListener + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/ObjectEventListener.cs.meta b/VirtueSky/Events/ObjectEventListener.cs.meta new file mode 100644 index 00000000..7c49a023 --- /dev/null +++ b/VirtueSky/Events/ObjectEventListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6ff6677543cf4536a9f672e0851f915c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/ObjectEventResponse.cs b/VirtueSky/Events/ObjectEventResponse.cs new file mode 100644 index 00000000..60edd7a7 --- /dev/null +++ b/VirtueSky/Events/ObjectEventResponse.cs @@ -0,0 +1,10 @@ +using System; +using Object = UnityEngine.Object; + +namespace VirtueSky.Events +{ + [Serializable] + public class ObjectEventResponse : BaseEventResponse + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/ObjectEventResponse.cs.meta b/VirtueSky/Events/ObjectEventResponse.cs.meta new file mode 100644 index 00000000..72e5f1fe --- /dev/null +++ b/VirtueSky/Events/ObjectEventResponse.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ae05b91993734bc7b39f1dfe3e3c193e +timeCreated: 1651590963 \ No newline at end of file diff --git a/VirtueSky/Events/PlayAudioEvent.cs b/VirtueSky/Events/PlayAudioEvent.cs new file mode 100644 index 00000000..2ca70183 --- /dev/null +++ b/VirtueSky/Events/PlayAudioEvent.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace VirtueSky.Events +{ + [CreateAssetMenu(menuName = "Event/Play Audio Event")] + public class PlayAudioEvent : BaseEvent, ISerializationCallbackReceiver + { + Dictionary lastTimePlayDict = new Dictionary(); + + public override void Raise(AudioClip value) + { + if (!lastTimePlayDict.ContainsKey(value)) + { + lastTimePlayDict.Add(value, 0); + } + + if (Time.unscaledTime - lastTimePlayDict[value] < 0.1f) + { + return; + } + + lastTimePlayDict[value] = Time.unscaledTime; + base.Raise(value); + } + + public void RaiseRandom(AudioClip[] audioClips) + { + Raise(audioClips[Random.Range(0, audioClips.Length)]); + } + + public void OnBeforeSerialize() + { + } + + public void OnAfterDeserialize() + { + lastTimePlayDict = new Dictionary(); + } + } +} \ No newline at end of file diff --git a/VirtueSky/Events/PlayAudioEvent.cs.meta b/VirtueSky/Events/PlayAudioEvent.cs.meta new file mode 100644 index 00000000..77ce39d6 --- /dev/null +++ b/VirtueSky/Events/PlayAudioEvent.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d3eb923e481f4f18b23e64cdd5e4dc33 +timeCreated: 1660445218 \ No newline at end of file diff --git a/VirtueSky/Events/PlayAudioEventListener.cs b/VirtueSky/Events/PlayAudioEventListener.cs new file mode 100644 index 00000000..323f560c --- /dev/null +++ b/VirtueSky/Events/PlayAudioEventListener.cs @@ -0,0 +1,8 @@ +using UnityEngine; + +namespace VirtueSky.Events +{ + public class PlayAudioEventListener : BaseEventListener + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/PlayAudioEventListener.cs.meta b/VirtueSky/Events/PlayAudioEventListener.cs.meta new file mode 100644 index 00000000..36b31184 --- /dev/null +++ b/VirtueSky/Events/PlayAudioEventListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 403efc7f1fa54336b727d878cb93a867 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/PlayAudioEventResponse.cs b/VirtueSky/Events/PlayAudioEventResponse.cs new file mode 100644 index 00000000..56aa7b05 --- /dev/null +++ b/VirtueSky/Events/PlayAudioEventResponse.cs @@ -0,0 +1,10 @@ +using System; +using UnityEngine; + +namespace VirtueSky.Events +{ + [Serializable] + public class PlayAudioEventResponse : BaseEventResponse + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/PlayAudioEventResponse.cs.meta b/VirtueSky/Events/PlayAudioEventResponse.cs.meta new file mode 100644 index 00000000..271f4d8c --- /dev/null +++ b/VirtueSky/Events/PlayAudioEventResponse.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 038b817ac23c4ab0abd6e36ec25ec653 +timeCreated: 1660445218 \ No newline at end of file diff --git a/VirtueSky/Events/ShortDoubleEvent.cs b/VirtueSky/Events/ShortDoubleEvent.cs new file mode 100644 index 00000000..edf89d91 --- /dev/null +++ b/VirtueSky/Events/ShortDoubleEvent.cs @@ -0,0 +1,10 @@ +using UnityEngine; +using VirtueSky.DataType; + +namespace VirtueSky.Events +{ + [CreateAssetMenu(menuName = "Event/ShortDouble Event")] + public class ShortDoubleEvent : BaseEvent + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/ShortDoubleEvent.cs.meta b/VirtueSky/Events/ShortDoubleEvent.cs.meta new file mode 100644 index 00000000..35f47ca0 --- /dev/null +++ b/VirtueSky/Events/ShortDoubleEvent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8a3f4bf948b3823458a288ee16eab4d9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/ShortDoubleEventListener.cs b/VirtueSky/Events/ShortDoubleEventListener.cs new file mode 100644 index 00000000..c4a94abc --- /dev/null +++ b/VirtueSky/Events/ShortDoubleEventListener.cs @@ -0,0 +1,8 @@ +using VirtueSky.DataType; + +namespace VirtueSky.Events +{ + public class ShortDoubleEventListener : BaseEventListener + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/ShortDoubleEventListener.cs.meta b/VirtueSky/Events/ShortDoubleEventListener.cs.meta new file mode 100644 index 00000000..b1e2a5e7 --- /dev/null +++ b/VirtueSky/Events/ShortDoubleEventListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 14a9ac023339adc48b39823e57aaab78 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/ShortDoubleEventResponse.cs b/VirtueSky/Events/ShortDoubleEventResponse.cs new file mode 100644 index 00000000..adc34c7b --- /dev/null +++ b/VirtueSky/Events/ShortDoubleEventResponse.cs @@ -0,0 +1,10 @@ +using System; +using VirtueSky.DataType; + +namespace VirtueSky.Events +{ + [Serializable] + public class ShortDoubleEventResponse : BaseEventResponse + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/ShortDoubleEventResponse.cs.meta b/VirtueSky/Events/ShortDoubleEventResponse.cs.meta new file mode 100644 index 00000000..30111e0b --- /dev/null +++ b/VirtueSky/Events/ShortDoubleEventResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8a7944dec2527be48bb2003844a9428a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/StringEvent.cs b/VirtueSky/Events/StringEvent.cs new file mode 100644 index 00000000..5cfbcc22 --- /dev/null +++ b/VirtueSky/Events/StringEvent.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace VirtueSky.Events +{ + [CreateAssetMenu(menuName = "Event/String Event")] + public class StringEvent : BaseEvent + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/StringEvent.cs.meta b/VirtueSky/Events/StringEvent.cs.meta new file mode 100644 index 00000000..ceef5a13 --- /dev/null +++ b/VirtueSky/Events/StringEvent.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7403481dc1f5472fb389d85c74090ef5 +timeCreated: 1660273903 \ No newline at end of file diff --git a/VirtueSky/Events/StringEventListener.cs b/VirtueSky/Events/StringEventListener.cs new file mode 100644 index 00000000..5c8552a0 --- /dev/null +++ b/VirtueSky/Events/StringEventListener.cs @@ -0,0 +1,6 @@ +namespace VirtueSky.Events +{ + public class StringEventListener : BaseEventListener + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/StringEventListener.cs.meta b/VirtueSky/Events/StringEventListener.cs.meta new file mode 100644 index 00000000..4042f2e7 --- /dev/null +++ b/VirtueSky/Events/StringEventListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 73a48105b6a944a69fe24790d53bbbea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/StringEventResponse.cs b/VirtueSky/Events/StringEventResponse.cs new file mode 100644 index 00000000..45a5a961 --- /dev/null +++ b/VirtueSky/Events/StringEventResponse.cs @@ -0,0 +1,9 @@ +using System; + +namespace VirtueSky.Events +{ + [Serializable] + public class StringEventResponse : BaseEventResponse + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/StringEventResponse.cs.meta b/VirtueSky/Events/StringEventResponse.cs.meta new file mode 100644 index 00000000..206a9a1f --- /dev/null +++ b/VirtueSky/Events/StringEventResponse.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5b8a085f69174a3c9beeef25bb05bfd7 +timeCreated: 1660273903 \ No newline at end of file diff --git a/VirtueSky/Events/Vector3Event.cs b/VirtueSky/Events/Vector3Event.cs new file mode 100644 index 00000000..ccbae104 --- /dev/null +++ b/VirtueSky/Events/Vector3Event.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace VirtueSky.Events +{ + [CreateAssetMenu(menuName = "Event/Vector3 Event")] + public class Vector3Event : BaseEvent + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/Vector3Event.cs.meta b/VirtueSky/Events/Vector3Event.cs.meta new file mode 100644 index 00000000..f9f56d97 --- /dev/null +++ b/VirtueSky/Events/Vector3Event.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6204d80d69a942eeae93eff39c44aa91 +timeCreated: 1660440730 \ No newline at end of file diff --git a/VirtueSky/Events/Vector3EventListener.cs b/VirtueSky/Events/Vector3EventListener.cs new file mode 100644 index 00000000..c9879708 --- /dev/null +++ b/VirtueSky/Events/Vector3EventListener.cs @@ -0,0 +1,8 @@ +using UnityEngine; + +namespace VirtueSky.Events +{ + public class Vector3EventListener : BaseEventListener + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/Vector3EventListener.cs.meta b/VirtueSky/Events/Vector3EventListener.cs.meta new file mode 100644 index 00000000..3ca5b484 --- /dev/null +++ b/VirtueSky/Events/Vector3EventListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 287ec16a80e0470794dd652b0c2636c6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Events/Vector3EventResponse.cs b/VirtueSky/Events/Vector3EventResponse.cs new file mode 100644 index 00000000..9cb03f08 --- /dev/null +++ b/VirtueSky/Events/Vector3EventResponse.cs @@ -0,0 +1,10 @@ +using System; +using UnityEngine; + +namespace VirtueSky.Events +{ + [Serializable] + public class Vector3EventResponse : BaseEventResponse + { + } +} \ No newline at end of file diff --git a/VirtueSky/Events/Vector3EventResponse.cs.meta b/VirtueSky/Events/Vector3EventResponse.cs.meta new file mode 100644 index 00000000..b5fccdd0 --- /dev/null +++ b/VirtueSky/Events/Vector3EventResponse.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 12ffc18fb6764f89a9271e41a8e1e24e +timeCreated: 1660440731 \ No newline at end of file diff --git a/VirtueSky/ObjectPooling.meta b/VirtueSky/ObjectPooling.meta new file mode 100644 index 00000000..bba69750 --- /dev/null +++ b/VirtueSky/ObjectPooling.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e935857045c5c7949b038f6337c22b52 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/ObjectPooling/PooledObjectId.cs b/VirtueSky/ObjectPooling/PooledObjectId.cs new file mode 100644 index 00000000..e0ce3fbe --- /dev/null +++ b/VirtueSky/ObjectPooling/PooledObjectId.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace VirtueSky.ObjectPooling +{ + public class PooledObjectId : MonoBehaviour + { + public GameObject prefab; + } +} \ No newline at end of file diff --git a/VirtueSky/ObjectPooling/PooledObjectId.cs.meta b/VirtueSky/ObjectPooling/PooledObjectId.cs.meta new file mode 100644 index 00000000..868933b9 --- /dev/null +++ b/VirtueSky/ObjectPooling/PooledObjectId.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b5e68b9f9e9f478ab34ddf8bcde5baa3 +timeCreated: 1652323347 \ No newline at end of file diff --git a/VirtueSky/ObjectPooling/PooledParticleCallback.cs b/VirtueSky/ObjectPooling/PooledParticleCallback.cs new file mode 100644 index 00000000..15d717ae --- /dev/null +++ b/VirtueSky/ObjectPooling/PooledParticleCallback.cs @@ -0,0 +1,19 @@ +using System.Collections; +using VirtueSky.Core; + +namespace VirtueSky.ObjectPooling +{ + public class PooledParticleCallback : BaseMono + { + void OnParticleSystemStopped() + { + StartCoroutine(IEDespawn()); + } + + IEnumerator IEDespawn() + { + yield return null; + pools.Despawn(gameObject); + } + } +} \ No newline at end of file diff --git a/VirtueSky/ObjectPooling/PooledParticleCallback.cs.meta b/VirtueSky/ObjectPooling/PooledParticleCallback.cs.meta new file mode 100644 index 00000000..2adc7326 --- /dev/null +++ b/VirtueSky/ObjectPooling/PooledParticleCallback.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 569b2c087ecd461ebb584cb0bb62c6f9 +timeCreated: 1652543497 \ No newline at end of file diff --git a/VirtueSky/ObjectPooling/Pools.cs b/VirtueSky/ObjectPooling/Pools.cs new file mode 100644 index 00000000..c9368fe2 --- /dev/null +++ b/VirtueSky/ObjectPooling/Pools.cs @@ -0,0 +1,235 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor; +using UnityEngine; +using UnityEngine.SceneManagement; +using VirtueSky.Core; +using VirtueSky.Utils; +#if UNITY_EDITOR +#endif + +namespace VirtueSky.ObjectPooling +{ + // [CreateAssetMenu(menuName = "ObjectPooling/Pools")] + public class Pools : ScriptableObject, ISerializationCallbackReceiver + { + [SerializeField] PoolData[] poolDatas; + + Dictionary> waitPool; + LinkedList activePool; + + Transform container; + + bool initialized; + + public void Initialize() + { + if (initialized) return; + initialized = true; + + waitPool = new Dictionary>(); + activePool = new LinkedList(); + container = new GameObject("Pool").transform; + DontDestroyOnLoad(container.gameObject); + + PreSpawn(); + } + + void PreSpawn() + { + foreach (var data in poolDatas) + { + for (var i = 0; i < data.preSpawn; i++) + { + SpawnNew(data.prefab); + } + } + } + + public void SpawnNew(GameObject prefab) + { + var gameObject = Instantiate(prefab); + var id = gameObject.AddComponent(); + id.prefab = prefab; + + activePool.AddLast(gameObject); + + Despawn(gameObject, false); + } + + public void Despawn(GameObject gameObject, bool destroy = false) + { + var id = gameObject.GetComponent(); + if (id == null) + { + Debug.LogError($"{gameObject.name} is not a pooled object!"); + return; + } + + if (!activePool.Contains(gameObject)) + { + Debug.LogError($"{gameObject.name} is not in active pool!"); + return; + } + + activePool.Remove(gameObject); + if (!waitPool.ContainsKey(id.prefab)) + { + waitPool.Add(id.prefab, new Queue()); + } + + var stack = waitPool[id.prefab]; + if (stack.Contains(gameObject)) + { + Debug.LogError($"{gameObject.name} is already pooled!"); + return; + } + + CleanUp(gameObject); + if (destroy) + { + Destroy(gameObject); + } + else + { + gameObject.SetActive(false); + gameObject.transform.parent = container; + stack.Enqueue(gameObject); + } + } + + public void DespawnAll() + { + var arr = activePool.ToArray(); + foreach (var o in arr) + { + if (o != null) Despawn(o); + } + } + + public void DestroyAllWaitPools() + { + foreach (var (key, queue) in waitPool) + { + foreach (var go in queue) + { + CleanUp(go); + DestroyImmediate(go); + } + + queue.Clear(); + } + + waitPool.Clear(); + } + + public void DestroyAll() + { + var arr = waitPool.Values.SelectMany(g => g).ToArray(); + for (var i = 0; i < arr.Length; i++) + { + Destroy(arr[i].gameObject); + } + + waitPool.Clear(); + } + + public T Spawn(T type, Transform parent = null, bool initialize = true) where T : Component + { + return Spawn(type.gameObject, parent, initialize).GetComponent(); + } + + public GameObject Spawn(GameObject prefab, Transform parent = null, bool initialize = true) + { + if (!waitPool.ContainsKey(prefab)) + { + waitPool.Add(prefab, new Queue()); + } + + var stack = waitPool[prefab]; + if (stack.Count == 0) + { + SpawnNew(prefab); + } + + var gameObject = stack.Dequeue(); + + gameObject.transform.parent = parent; + + if (parent == null) + { + SceneManager.MoveGameObjectToScene(gameObject, SceneManager.GetActiveScene()); + } + + gameObject.SetActive(true); + + if (initialize) + { + Initialize(gameObject); + } + + activePool.AddLast(gameObject); + + return gameObject; + } + + void Initialize(GameObject go) + { + var monos = go.GetComponentsInChildren(true); + foreach (var mono in monos) + { + mono.Initialize(); + } + } + + void CleanUp(GameObject go) + { + var monos = go.GetComponentsInChildren(true); + foreach (var mono in monos) + { + mono.CleanUp(); + } + } + + public void OnBeforeSerialize() + { + } + + public void OnAfterDeserialize() + { + initialized = false; + } + +#if UNITY_EDITOR + [ContextMenu("Auto Bind")] + public void AutoBind() + { + var soes = AssetUtils.FindAssetAtFolder(new string[] { "Assets" }); + foreach (var so in soes) + { + so.pools = this; + EditorUtility.SetDirty(so); + } + + var goes = AssetUtils.FindAssetAtFolder(new string[] { "Assets" }); + foreach (var go in goes) + { + var monoes = go.GetComponentsInChildren(true); + foreach (var mono in monoes) + { + mono.pools = this; + EditorUtility.SetDirty(mono); + } + } + } +#endif + } + + [Serializable] + public class PoolData + { + public GameObject prefab; + public int preSpawn; + } +} \ No newline at end of file diff --git a/VirtueSky/ObjectPooling/Pools.cs.meta b/VirtueSky/ObjectPooling/Pools.cs.meta new file mode 100644 index 00000000..3185ac2e --- /dev/null +++ b/VirtueSky/ObjectPooling/Pools.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ea56204fcdc152d4ba795117fd8fff72 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Utils.meta b/VirtueSky/Utils.meta new file mode 100644 index 00000000..bee0f3e4 --- /dev/null +++ b/VirtueSky/Utils.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2d0ca7a47dfd41541bb113dfd19ac5e8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Utils/AssetUtils.cs b/VirtueSky/Utils/AssetUtils.cs new file mode 100644 index 00000000..18d68e86 --- /dev/null +++ b/VirtueSky/Utils/AssetUtils.cs @@ -0,0 +1,48 @@ +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; +#if UNITY_EDITOR +#endif + +namespace VirtueSky.Utils +{ + public static class AssetUtils + { +#if UNITY_EDITOR + public static void ChangeAssetName(Object asset, string name) + { + var assetPath = AssetDatabase.GetAssetPath(asset.GetInstanceID()); + AssetDatabase.RenameAsset(assetPath, name); + AssetDatabase.SaveAssets(); + } + + public static T[] FindAssetAtFolder(string[] paths) where T : Object + { + var list = new List(); + var guids = AssetDatabase.FindAssets($"t:{typeof(T).Name}", paths); + foreach (var guid in guids) + { + var asset = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid)); + if (asset) + { + list.Add(asset); + } + } + + return list.ToArray(); + } + + public static T FindAssetAtResource(string path) where T : ScriptableObject + { + T config = + Resources.Load(path); + if (config != null) + { + return config; + } + + return null; + } +#endif + } +} \ No newline at end of file diff --git a/VirtueSky/Utils/AssetUtils.cs.meta b/VirtueSky/Utils/AssetUtils.cs.meta new file mode 100644 index 00000000..75f92d2b --- /dev/null +++ b/VirtueSky/Utils/AssetUtils.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ff9123cf757140448e681c1979224d8f +timeCreated: 1658972648 \ No newline at end of file diff --git a/VirtueSky/Utils/ExtensionUtils.cs b/VirtueSky/Utils/ExtensionUtils.cs new file mode 100644 index 00000000..6ab0aed1 --- /dev/null +++ b/VirtueSky/Utils/ExtensionUtils.cs @@ -0,0 +1,561 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using UnityEditor; +using UnityEngine; +using UnityEngine.AI; +using UnityEngine.Networking; + +namespace VirtueSky.Utils +{ + public static class MonoBehaviorExtension + { + public static Coroutine Delay(this MonoBehaviour mono, float time, bool realTime, System.Action callback) + { + return mono.StartCoroutine(WaitForExtraTime(time, realTime, callback)); + } + + static IEnumerator WaitForExtraTime(float time, bool realTime, System.Action callback) + { + if (realTime) + { + yield return new WaitForSecondsRealtime(time); + } + else + { + yield return new WaitForSeconds(time); + } + + callback?.Invoke(); + } + + public static Coroutine Delay(this MonoBehaviour mono, int frame, System.Action callback) + { + return mono.StartCoroutine(WaitForExtraFrame(frame, callback)); + } + + static IEnumerator WaitForExtraFrame(int frame, System.Action callback) + { + for (var i = 0; i < frame; i++) + { + yield return null; + } + + callback?.Invoke(); + } + + public static Coroutine WaitUntil(this MonoBehaviour mono, Func condition, Action callback) + { + return mono.StartCoroutine(WaitUntil(condition, callback)); + } + + static IEnumerator WaitUntil(Func condition, Action callback) + { + yield return new WaitUntil(condition); + callback?.Invoke(); + } + + public static T GetAndCacheComponent(this MonoBehaviour mono, ref T cache) where T : Component + { + return cache ? cache : (cache = mono.GetComponent()); + } + + public static T GetAndCacheComponentInChildren(this MonoBehaviour mono, ref T cache, bool includeInactive = false) + { + return cache ??= mono.GetComponentInChildren(includeInactive); + } + + public static T[] GetAndCacheComponents(this MonoBehaviour mono, ref T[] cache) where T : Component + { + return cache ??= mono.GetComponents(); + } + + public static T[] GetAndCacheComponentsInChildren(this MonoBehaviour mono, ref T[] cache, bool includeInactive = false) + { + return cache ??= mono.GetComponentsInChildren(includeInactive); + } + + public static T GetAndCacheComponentInParent(this MonoBehaviour mono, ref T cache) + { + return cache ??= mono.GetComponentInParent(); + } + } + + public static class GameObjectExtension + { + static List m_ComponentCache = new List(); + + public static Component GetComponentNoAlloc(this GameObject go, System.Type componentType) + { + go.GetComponents(componentType, m_ComponentCache); + var component = m_ComponentCache.Count > 0 ? m_ComponentCache[0] : null; + m_ComponentCache.Clear(); + return component; + } + + public static T GetComponentNoAlloc(this GameObject go) where T : Component + { + go.GetComponents(typeof(T), m_ComponentCache); + var component = m_ComponentCache.Count > 0 ? m_ComponentCache[0] : null; + m_ComponentCache.Clear(); + return component as T; + } + + public static T GetAndCacheComponent(this GameObject go, ref T cache) + { + return cache ??= go.GetComponent(); + } + + public static T GetAndCacheComponentInChildren(this GameObject go, bool includeInactive, ref T cache) + { + return cache ??= go.GetComponentInChildren(includeInactive); + } + } + + public static class TransformExtensions + { + public static void RandomRotation(this Transform transform, bool onlyY = false) + { + transform.rotation = SimpleMath.RandomRotation(onlyY); + } + + public static void RandomLocalRotation(this Transform transform, bool onlyY = false) + { + transform.localRotation = SimpleMath.RandomRotation(onlyY); + } + + public static void Copy(this Transform transform, Transform other, bool position, bool rotation, bool scale, bool otherLossyScale) + { + if (position) transform.position = other.transform.position; + if (rotation) transform.rotation = other.transform.rotation; + if (scale) + { + transform.localScale = otherLossyScale ? other.transform.lossyScale : other.transform.localScale; + } + } + + public static void ResetLocal(this Transform transform) + { + transform.localPosition = Vector3.zero; + transform.localRotation = Quaternion.identity; + } + + // public static Tween DORotateQuaternionXZ(this Transform transform, Vector3 pos, float duration) + // { + // var dir = pos - transform.position; + // dir.y = 0; + // return transform.DORotateQuaternion(Quaternion.LookRotation(dir), duration); + // } + + public static Vector2 position2D(this Transform transform) + { + return transform.position; + } + + public static Vector2 localPosition2D(this Transform transform) + { + return transform.localPosition; + } + + public static Bounds GetBounds(this Transform transform) + { + var bound = new Bounds(); + var renderers = transform.GetComponentsInChildren().Where(r => !(r is ParticleSystemRenderer)).ToArray(); + + for (var j = 0; j < renderers.Length; j++) + { + if (j == 0) bound = renderers[j].bounds; + else bound.Encapsulate(renderers[j].bounds); + } + + return bound; + } + +#if UNITY_EDITOR + [MenuItem("CONTEXT/Transform/ExpandX")] + public static void ExpandX(MenuCommand command) + { + var tfs = Selection.gameObjects.Select(g => g.transform).OrderBy(t => t.position.x).ToArray(); + if (tfs.Length > 2) + { + Undo.RecordObjects(tfs, "ExpandX"); + var min = tfs[0].position.x; + var max = tfs[tfs.Length - 1].position.x; + var step = (max - min) / (tfs.Length - 1); + for (var i = 0; i < tfs.Length; i++) + { + var pos = tfs[i].position; + pos.x = min + step * i; + tfs[i].position = pos; + EditorUtility.SetDirty(tfs[i]); + } + } + } + + [MenuItem("CONTEXT/Transform/ExpandY")] + public static void ExpandY(MenuCommand command) + { + var tfs = Selection.gameObjects.Select(g => g.transform).OrderBy(t => t.position.y).ToArray(); + if (tfs.Length > 2) + { + Undo.RecordObjects(tfs, "ExpandY"); + var min = tfs[0].position.y; + var max = tfs[tfs.Length - 1].position.y; + var step = (max - min) / (tfs.Length - 1); + for (var i = 0; i < tfs.Length; i++) + { + var pos = tfs[i].position; + pos.y = min + step * i; + tfs[i].position = pos; + EditorUtility.SetDirty(tfs[i]); + } + } + } + + [MenuItem("CONTEXT/Transform/SetX")] + public static void SetX(MenuCommand command) + { + var tfs = Selection.gameObjects.Select(g => g.transform).OrderBy(t => t.position.x).ToArray(); + if (tfs.Length > 2) + { + Undo.RecordObjects(tfs, "SetX"); + var startX = tfs[0].position.x; + var prevBound = tfs[0].GetBounds(); + for (var i = 0; i < tfs.Length; i++) + { + var dist = 0f; + if (i > 0) + { + var bounds = tfs[i].GetBounds(); + dist = prevBound.extents.x + bounds.extents.x; + prevBound = bounds; + } + + var pos = tfs[i].position; + pos.x = startX + dist; + tfs[i].position = pos; + startX = pos.x; + EditorUtility.SetDirty(tfs[i]); + } + } + } + + [MenuItem("CONTEXT/Transform/SetY")] + public static void SetY(MenuCommand command) + { + var tfs = Selection.gameObjects.Select(g => g.transform).OrderBy(t => t.position.y).ToArray(); + if (tfs.Length > 2) + { + Undo.RecordObjects(tfs, "SetY"); + var startY = tfs[0].position.y; + var prevBound = tfs[0].GetBounds(); + for (var i = 0; i < tfs.Length; i++) + { + var dist = 0f; + if (i > 0) + { + var bounds = tfs[i].GetBounds(); + dist = prevBound.extents.y + bounds.extents.y; + prevBound = bounds; + } + + var pos = tfs[i].position; + pos.y = startY + dist; + tfs[i].position = pos; + startY = pos.y; + EditorUtility.SetDirty(tfs[i]); + } + } + } + + [MenuItem("CONTEXT/Transform/AlignX")] + public static void AlignX(MenuCommand command) + { + var tfs = Selection.gameObjects.Select(g => g.transform).OrderBy(t => t.position.x).ToArray(); + if (tfs.Length > 2) + { + Undo.RecordObjects(tfs, "AlignX"); + var x = tfs[0].position.x; + for (var i = 0; i < tfs.Length; i++) + { + var pos = tfs[i].position; + pos.x = x; + tfs[i].position = pos; + EditorUtility.SetDirty(tfs[i]); + } + } + } + + [MenuItem("CONTEXT/Transform/AlignY")] + public static void AlignY(MenuCommand command) + { + var tfs = Selection.gameObjects.Select(g => g.transform).OrderBy(t => t.position.y).ToArray(); + if (tfs.Length > 2) + { + Undo.RecordObjects(tfs, "AlignY"); + var y = tfs[0].position.y; + for (var i = 0; i < tfs.Length; i++) + { + var pos = tfs[i].position; + pos.y = y; + tfs[i].position = pos; + EditorUtility.SetDirty(tfs[i]); + } + } + } +#endif + } + + public static class LayerMaskExtension + { + public static int ToGameObjectLayer(this LayerMask layerMask) + { + return (int)Mathf.Log(layerMask.value, 2); + } + } + + public static class NavmeshExtension + { + public static bool IsReachDestination(this NavMeshAgent agent, float threshold = 0.1f) + { + return !agent.pathPending && agent.remainingDistance < agent.stoppingDistance + threshold; + } + } + + public static class EnumerationExtensions + { + public static bool Has(this Enum type, T value) + { + try + { + return (((int)(object)type & (int)(object)value) == (int)(object)value); + } + catch + { + return false; + } + } + + public static bool Is(this Enum type, T value) + { + try + { + return (int)(object)type == (int)(object)value; + } + catch + { + return false; + } + } + + public static T Add(this Enum type, T value) + { + try + { + return (T)(object)(((int)(object)type | (int)(object)value)); + } + catch (Exception ex) + { + throw new ArgumentException($"Could not append value from enumerated type '{typeof(T).Name}'.", ex); + } + } + + public static T Remove(this Enum type, T value) + { + try + { + return (T)(object)(((int)(object)type & ~(int)(object)value)); + } + catch (Exception ex) + { + throw new ArgumentException($"Could not remove value from enumerated type '{typeof(T).Name}'.", ex); + } + } + } + + public static class MathExtension + { + public static System.Numerics.Vector3 ToSysVector3(this Vector3 v) + { + return new System.Numerics.Vector3(v.x, v.y, v.z); + } + + public static System.Numerics.Quaternion ToSysQuaternion(this Quaternion v) + { + return new System.Numerics.Quaternion(v.x, v.y, v.z, v.w); + } + } + + public static class ParticleExtension + { + public static void SetSortingOrder(this ParticleSystem particle, int sortingOrder) + { + var ps = particle.GetComponentsInChildren(); + foreach (var p in ps) + { + var r = p.GetComponent(); + r.sortingOrder += sortingOrder; + } + } + + public static void SetStopAction(this ParticleSystem particle, ParticleSystemStopAction stopAction) + { + var main = particle.main; + main.stopAction = stopAction; + } + } + + public static class FlipXExtension + { + public static void FlipX(this Transform target) + { + var pos = target.localPosition; + pos.x = -pos.x; + target.localPosition = pos; + + var rot = target.localRotation; + rot *= Quaternion.Euler(0, 0, rot.y * 2); + target.localRotation = rot; + } + + public static void FlipX(this PolygonCollider2D target) + { + var points = target.points; + for (var i = 0; i < points.Length; i++) + { + points[i].x = -points[i].x; + } + + target.points = points; + } + + public static void FlipX(this HingeJoint2D target) + { + var motor = target.motor; + motor.motorSpeed = -motor.motorSpeed; + target.motor = motor; + } + + public static void FlipX(this BoxCollider2D target) + { + var offset = target.offset; + offset.x = -offset.x; + target.offset = offset; + } + + public static void FlipX(this WheelJoint2D target) + { + var motor = target.motor; + motor.motorSpeed = -motor.motorSpeed; + target.motor = motor; + } + +#if UNITY_EDITOR + [MenuItem("CONTEXT/PolygonCollider2D/FlipX")] + static void PolygonCollider2DFlipX(MenuCommand command) + { + var target = (PolygonCollider2D)command.context; + target.FlipX(); + + EditorUtility.SetDirty(target); + } + + [MenuItem("CONTEXT/Transform/FlipX")] + static void TransformFlipX(MenuCommand command) + { + var target = (Transform)command.context; + target.FlipX(); + + EditorUtility.SetDirty(target); + } + + [MenuItem("CONTEXT/HingeJoint2D/FlipX")] + static void HingeJoint2DFlipX(MenuCommand command) + { + var target = (HingeJoint2D)command.context; + target.FlipX(); + + EditorUtility.SetDirty(target); + } + + [MenuItem("CONTEXT/BoxCollider2D/FlipX")] + static void BoxCollider2DFlipX(MenuCommand command) + { + var target = (BoxCollider2D)command.context; + target.FlipX(); + + EditorUtility.SetDirty(target); + } + + [MenuItem("CONTEXT/WheelJoint2D/FlipX")] + static void WheelJoint2DFlipX(MenuCommand command) + { + var target = (WheelJoint2D)command.context; + target.FlipX(); + + EditorUtility.SetDirty(target); + } +#endif + } + + public class UnityWebRequestAwaiter : INotifyCompletion + { + UnityWebRequestAsyncOperation ao; + Action continuation; + + public UnityWebRequestAwaiter(UnityWebRequestAsyncOperation ao) + { + this.ao = ao; + ao.completed += OnRequestCompleted; + } + + public bool IsCompleted => ao.isDone; + + public void GetResult() + { + } + + public void OnCompleted(Action c) + { + continuation = c; + } + + void OnRequestCompleted(AsyncOperation obj) + { + continuation(); + } + } + + public static class UnityWebRequestExtensions + { + public static UnityWebRequestAwaiter GetAwaiter(this UnityWebRequestAsyncOperation asyncOp) + { + return new UnityWebRequestAwaiter(asyncOp); + } + } + + public static class DictionaryExtension + { + public static Dictionary Clone(this Dictionary dict) + { + if (dict == null) + { + return null; + } + + return dict.ToDictionary(i => i.Key, i => i.Value); + } + + public static string ToString(this Dictionary dict) + { + if (dict == null) + { + return string.Empty; + } + + return string.Join(", ", dict); + } + } +} \ No newline at end of file diff --git a/VirtueSky/Utils/ExtensionUtils.cs.meta b/VirtueSky/Utils/ExtensionUtils.cs.meta new file mode 100644 index 00000000..47fa312c --- /dev/null +++ b/VirtueSky/Utils/ExtensionUtils.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d424096a405f4d10b578a33d12c66fd1 +timeCreated: 1622039108 \ No newline at end of file diff --git a/VirtueSky/Utils/GameViewUtils.cs b/VirtueSky/Utils/GameViewUtils.cs new file mode 100644 index 00000000..58641c8f --- /dev/null +++ b/VirtueSky/Utils/GameViewUtils.cs @@ -0,0 +1,98 @@ +#if UNITY_EDITOR +using System; +using System.Reflection; +using UnityEditor; + +namespace VirtueSky.Utils +{ + public class GameViewUtils + { + public const int DefaultSizeCount = 18; + + public static readonly Resolution[] resolutions = + { + new Resolution("iPhone 4", 640, 960), + new Resolution("iPhone 5", 640, 1136), + new Resolution("iPhone 6", 750, 1334), + new Resolution("iPhone 8+", 1242, 2208), + new Resolution("iPhone X", 1125, 2436), + new Resolution("iPhone Xs Max", 1242, 2688), + new Resolution("iPhone XR ", 828, 1792), + new Resolution("HD", 1080, 1920), + new Resolution("iPad Retina", 1536, 2048), + new Resolution("iPad Pro 10.5", 1668, 2224), + new Resolution("iPad Pro 12.9", 2048, 2732), + new Resolution("iPhone 11 Pro", 1125, 2436), + new Resolution("iPhone 11 Pro Max", 1242, 2688) + }; + + static readonly object gameViewSizesInstance; + static readonly MethodInfo getGroup; + + static GameViewUtils() + { + var sizesType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizes"); + var singleType = typeof(ScriptableSingleton<>).MakeGenericType(sizesType); + var instanceProp = singleType.GetProperty("instance"); + getGroup = sizesType.GetMethod("GetGroup"); + gameViewSizesInstance = instanceProp.GetValue(null, null); + } + + public static void AddCustomSize() + { + foreach (var resolution in resolutions) + AddCustomSize(GameViewSizeGroupType.Android, resolution.width, resolution.height, resolution.name); + } + + static void AddCustomSize(GameViewSizeGroupType sizeGroupType, int width, int height, string text) + { + var group = GetGroup(sizeGroupType); + var addCustomSize = getGroup.ReturnType.GetMethod("AddCustomSize"); + var gvsType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSize"); + var ctor = gvsType.GetConstructor(new[] + { + typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizeType"), typeof(int), typeof(int), + typeof(string) + }); + var newSize = ctor.Invoke(new object[] { 1, width, height, text }); + addCustomSize.Invoke(group, new[] { newSize }); + } + + public static void SetSize(int index) + { + var gvWndType = typeof(Editor).Assembly.GetType("UnityEditor.GameView"); + var gvWnd = EditorWindow.GetWindow(gvWndType); + var sizeSelectionCallback = gvWndType.GetMethod("SizeSelectionCallback", + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + sizeSelectionCallback.Invoke(gvWnd, new object[] { index, null }); + } + + static object GetGroup(GameViewSizeGroupType type) + { + return getGroup.Invoke(gameViewSizesInstance, new object[] { (int)type }); + } + + public static int GetViewListSize() + { + var group = GetGroup(GameViewSizeGroupType.Android); + var getDisplayTexts = group.GetType().GetMethod("GetDisplayTexts"); + return (getDisplayTexts.Invoke(group, null) as string[]).Length; + } + } + + [Serializable] + public class Resolution + { + public string name; + public int height; + public int width; + + public Resolution(string name, int width, int height) + { + this.name = name; + this.width = width; + this.height = height; + } + } +} +#endif \ No newline at end of file diff --git a/VirtueSky/Utils/GameViewUtils.cs.meta b/VirtueSky/Utils/GameViewUtils.cs.meta new file mode 100644 index 00000000..e64e6747 --- /dev/null +++ b/VirtueSky/Utils/GameViewUtils.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 75154e8e7c6146cda787abf4cae97bd1 +timeCreated: 1610554859 \ No newline at end of file diff --git a/VirtueSky/Utils/InputUtils.cs b/VirtueSky/Utils/InputUtils.cs new file mode 100644 index 00000000..9014dc95 --- /dev/null +++ b/VirtueSky/Utils/InputUtils.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.EventSystems; + +namespace VirtueSky.Utils +{ + public class InputUtils + { + public static bool IsPointerOverUI(Vector2 pos) + { + var eventDataCurrentPosition = new PointerEventData(EventSystem.current) + { + position = new Vector2(pos.x, pos.y) + }; + var results = new List(); + EventSystem.current.RaycastAll(eventDataCurrentPosition, results); + return results.Count > 0; + } + } +} \ No newline at end of file diff --git a/VirtueSky/Utils/InputUtils.cs.meta b/VirtueSky/Utils/InputUtils.cs.meta new file mode 100644 index 00000000..050bb448 --- /dev/null +++ b/VirtueSky/Utils/InputUtils.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b6fe19d3e11140659ebed2c0c0ef0ac1 +timeCreated: 1630517731 \ No newline at end of file diff --git a/VirtueSky/Utils/InterfaceUtils.cs b/VirtueSky/Utils/InterfaceUtils.cs new file mode 100644 index 00000000..864074e8 --- /dev/null +++ b/VirtueSky/Utils/InterfaceUtils.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using UnityEngine.SceneManagement; + +namespace VirtueSky.Utils +{ + public static class InterfaceUtils + { + public static List GetAllInterfaces() + { + var interfaces = new List(); + var rootGameObjects = SceneManager.GetActiveScene().GetRootGameObjects(); + foreach (var rootGameObject in rootGameObjects) + { + var childrenInterfaces = rootGameObject.GetComponentsInChildren(true); + foreach (var childInterface in childrenInterfaces) + { + interfaces.Add(childInterface); + } + } + + return interfaces; + } + } +} \ No newline at end of file diff --git a/VirtueSky/Utils/InterfaceUtils.cs.meta b/VirtueSky/Utils/InterfaceUtils.cs.meta new file mode 100644 index 00000000..36aaff0a --- /dev/null +++ b/VirtueSky/Utils/InterfaceUtils.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f38899acc2024dee8832c6a518563565 +timeCreated: 1631162887 \ No newline at end of file diff --git a/VirtueSky/Utils/ReflectionUtils.cs b/VirtueSky/Utils/ReflectionUtils.cs new file mode 100644 index 00000000..004973ce --- /dev/null +++ b/VirtueSky/Utils/ReflectionUtils.cs @@ -0,0 +1,22 @@ +using System; +using System.Reflection; + +namespace VirtueSky.Utils +{ + public static class ReflectionUtils + { + public static FieldInfo GetFieldRecursive(this Type type, string fieldName, BindingFlags bindingFlags) + { + var t = type; + FieldInfo field = null; + while (t != null) + { + field = t.GetField(fieldName, bindingFlags); + if (field != null) break; + t = t.BaseType; + } + + return field; + } + } +} \ No newline at end of file diff --git a/VirtueSky/Utils/ReflectionUtils.cs.meta b/VirtueSky/Utils/ReflectionUtils.cs.meta new file mode 100644 index 00000000..453c3266 --- /dev/null +++ b/VirtueSky/Utils/ReflectionUtils.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e093744796dd4fd19982333ec51c2ec5 +timeCreated: 1658972648 \ No newline at end of file diff --git a/VirtueSky/Utils/SampleAnim.cs b/VirtueSky/Utils/SampleAnim.cs new file mode 100644 index 00000000..751f642c --- /dev/null +++ b/VirtueSky/Utils/SampleAnim.cs @@ -0,0 +1,50 @@ +using UnityEditor; +using UnityEngine; +using VirtueSky.Core; + +namespace VirtueSky.Utils +{ + public class SampleAnim : BaseMono + { + [SerializeField] public AnimationClip clip; + + public override void Initialize() + { + Destroy(this); + } + } + +#if UNITY_EDITOR + [CustomEditor(typeof(SampleAnim))] + public class SampleAnimEditor : Editor + { + SampleAnim sampleAnim; + int frame; + + void OnEnable() + { + sampleAnim = target as SampleAnim; + } + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + if (sampleAnim.clip != null) + { + var pos = sampleAnim.transform.position; + var rot = sampleAnim.transform.rotation; + var scale = sampleAnim.transform.localScale; + + var frames = (int)(sampleAnim.clip.length * sampleAnim.clip.frameRate); + frame = EditorGUILayout.IntSlider("Frame", frame, 0, frames); + var t = frame / sampleAnim.clip.frameRate; + sampleAnim.clip.SampleAnimation(sampleAnim.gameObject, t); + + sampleAnim.transform.position = pos; + sampleAnim.transform.rotation = rot; + sampleAnim.transform.localScale = scale; + } + } + } +#endif +} \ No newline at end of file diff --git a/VirtueSky/Utils/SampleAnim.cs.meta b/VirtueSky/Utils/SampleAnim.cs.meta new file mode 100644 index 00000000..a7683b64 --- /dev/null +++ b/VirtueSky/Utils/SampleAnim.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 94908faf31f6cc44386133f7a95b9bb5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Utils/ScreenShooter.cs b/VirtueSky/Utils/ScreenShooter.cs new file mode 100644 index 00000000..c24f3cbc --- /dev/null +++ b/VirtueSky/Utils/ScreenShooter.cs @@ -0,0 +1,57 @@ +using System.Collections; +using UnityEngine; +using VirtueSky.Core; + +namespace VirtueSky.Utils +{ + public class ScreenShooter : BaseMono + { +#if UNITY_EDITOR + public override void Initialize() + { + DontDestroyOnLoad(gameObject); + } + + public override void Tick() + { + if (Input.GetKey(KeyCode.LeftShift) && Input.GetKeyDown(KeyCode.S)) + { + Shoot(); + } + } + + [ContextMenu("Shoot")] + public void Shoot() + { + StartCoroutine(IEShoot()); + } + + IEnumerator IEShoot() + { + var timeScale = Time.timeScale; + Time.timeScale = 0; + // + // var cam = GetComponentInChildren(); + // var camExtra = GetComponentInChildren(); + // camExtra.Setup(cam); + + var gameViewProfilesCount = GameViewUtils.GetViewListSize(); + for (var i = GameViewUtils.DefaultSizeCount; i < gameViewProfilesCount; i++) + { + var resolution = GameViewUtils.resolutions[i - GameViewUtils.DefaultSizeCount]; + + GameViewUtils.SetSize(i); + yield return null; + // camExtra.Apply(); + yield return null; + + yield return new WaitForEndOfFrame(); + var tex = ScreenCapture.CaptureScreenshotAsTexture(1); + TextureUtils.Texture2DToFile(tex, $"Assets/{TimeUtils.CurrentTicks}-{resolution.name}-{resolution.width}x{resolution.height}"); + } + + Time.timeScale = timeScale; + } +#endif + } +} \ No newline at end of file diff --git a/VirtueSky/Utils/ScreenShooter.cs.meta b/VirtueSky/Utils/ScreenShooter.cs.meta new file mode 100644 index 00000000..48b01b4a --- /dev/null +++ b/VirtueSky/Utils/ScreenShooter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: bb5cae92c69f434e941c16f6e1e744f4 +timeCreated: 1610552490 \ No newline at end of file diff --git a/VirtueSky/Utils/ScreenShooterSingle.cs b/VirtueSky/Utils/ScreenShooterSingle.cs new file mode 100644 index 00000000..48fb5aa3 --- /dev/null +++ b/VirtueSky/Utils/ScreenShooterSingle.cs @@ -0,0 +1,35 @@ +using System.IO; +using UnityEngine; +using VirtueSky.Core; +using Resolution = VirtueSky.Utils.Resolution; + +namespace VirtueSky.Utils +{ + public class ScreenShooterSingle : BaseMono + { + [SerializeField] Resolution resolution; + [SerializeField] KeyCode keyCode; + +#if UNITY_EDITOR + public override void Tick() + { + if (Input.GetKeyDown(keyCode)) + { + Shoot(); + } + } + + [ContextMenu("Shoot")] + public void Shoot() + { + if (!Directory.Exists(Application.dataPath + $"/../ScreenShots")) + { + Directory.CreateDirectory(Application.dataPath + $"/../ScreenShots"); + } + + TextureUtils.CaptureToFile(GetComponent(), Application.dataPath + $"/../ScreenShots/{TimeUtils.CurrentTicks}", resolution.width, resolution.height, + refresh: false); + } +#endif + } +} \ No newline at end of file diff --git a/VirtueSky/Utils/ScreenShooterSingle.cs.meta b/VirtueSky/Utils/ScreenShooterSingle.cs.meta new file mode 100644 index 00000000..c82fb9d3 --- /dev/null +++ b/VirtueSky/Utils/ScreenShooterSingle.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d11f134cecd14712827357aa1b976e50 +timeCreated: 1637763374 \ No newline at end of file diff --git a/VirtueSky/Utils/SimpleMath.cs b/VirtueSky/Utils/SimpleMath.cs new file mode 100644 index 00000000..57a33962 --- /dev/null +++ b/VirtueSky/Utils/SimpleMath.cs @@ -0,0 +1,360 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using Random = UnityEngine.Random; + +namespace VirtueSky.Utils +{ + public static class SimpleMath + { + public static bool InRange(Vector3 p, Vector3 c, float r, out float sqrDst, bool compareY = false) + { + if (!compareY) p.y = c.y; + sqrDst = SqrDist(p, c); + return sqrDst <= r * r; + } + + public static bool InRange(Vector3 p, Vector3 c, float r, bool compareY = false) + { + if (!compareY) p.y = c.y; + var sqrDst = SqrDist(p, c); + return sqrDst <= r * r; + } + + public static bool InRange2D(Vector2 p, Vector2 c, float r) + { + var sqrDst = SqrDist(p, c); + return sqrDst <= r * r; + } + + public static float SqrDist(Vector3 a, Vector3 b) + { + return (a - b).sqrMagnitude; + } + + public static Quaternion RandomRotation(bool onlyY = false) + { + if (onlyY) return Quaternion.Euler(0, Random.value * 360f, 0); + return Quaternion.Euler(RandomVector3() * 180f); + } + + public static Quaternion GetRotationXZ(Vector3 a, Vector3 b) + { + var dir = b - a; + dir.y = 0; + if (dir != Vector3.zero) + { + return Quaternion.LookRotation(dir); + } + else + { + return Quaternion.identity; + } + } + + public static Quaternion AngVelToDeriv(Quaternion current, Vector3 angVel) + { + var spin = new Quaternion(angVel.x, angVel.y, angVel.z, 0f); + var result = spin * current; + return new Quaternion(0.5f * result.x, 0.5f * result.y, 0.5f * result.z, 0.5f * result.w); + } + + public static Vector3 DerivToAngVel(Quaternion current, Quaternion deriv) + { + var result = deriv * Quaternion.Inverse(current); + return new Vector3(2f * result.x, 2f * result.y, 2f * result.z); + } + + public static Quaternion IntegrateRotation(Quaternion rotation, Vector3 angularVelocity, float deltaTime) + { + if (deltaTime < Mathf.Epsilon) return rotation; + var deriv = AngVelToDeriv(rotation, angularVelocity); + var pred = new Vector4( + rotation.x + deriv.x * deltaTime, + rotation.y + deriv.y * deltaTime, + rotation.z + deriv.z * deltaTime, + rotation.w + deriv.w * deltaTime + ).normalized; + return new Quaternion(pred.x, pred.y, pred.z, pred.w); + } + + public static Quaternion QuaternionSmoothDamp(Quaternion rot, Quaternion target, ref Quaternion deriv, + float time) + { + if (Time.deltaTime < Mathf.Epsilon) return rot; + // account for double-cover + var dot = Quaternion.Dot(rot, target); + var multi = dot > 0f ? 1f : -1f; + target.x *= multi; + target.y *= multi; + target.z *= multi; + target.w *= multi; + // smooth damp (nlerp approx) + var result = new Vector4( + Mathf.SmoothDamp(rot.x, target.x, ref deriv.x, time), + Mathf.SmoothDamp(rot.y, target.y, ref deriv.y, time), + Mathf.SmoothDamp(rot.z, target.z, ref deriv.z, time), + Mathf.SmoothDamp(rot.w, target.w, ref deriv.w, time) + ).normalized; + + // ensure deriv is tangent + var derivError = Vector4.Project(new Vector4(deriv.x, deriv.y, deriv.z, deriv.w), result); + deriv.x -= derivError.x; + deriv.y -= derivError.y; + deriv.z -= derivError.z; + deriv.w -= derivError.w; + + return new Quaternion(result.x, result.y, result.z, result.w); + } + + public static Vector3 RandomVector3(bool zeroY = false) + { + var result = Random.insideUnitSphere; + if (zeroY) result.y = 0; + return result; + } + + public static int GetNearestIndex(Vector3 p, float r, Vector3[] list, bool compareY = false) + { + var minDist = Mathf.Infinity; + var index = -1; + var dist = 0f; + for (var i = 0; i < list.Length; i++) + { + if (InRange(p, list[i], r, out dist, compareY)) + { + if (dist <= minDist) + { + minDist = dist; + index = i; + } + } + } + + return index; + } + + public static Vector3 RandomBetween(Vector3 a, Vector3 b) + { + return a + (b - a).normalized * Random.value * (b - a).magnitude; + } + + public static string NewGuid() + { + var encoded = Convert.ToBase64String(System.Guid.NewGuid().ToByteArray()); + encoded = encoded.Replace("/", "_").Replace("+", "-"); + return encoded.Substring(0, 22); + } + + + public static Vector3 DirectionFromAngle(float angleInDegrees) + { + return new Vector3(Mathf.Sin(angleInDegrees * Mathf.Deg2Rad), 0, Mathf.Cos(angleInDegrees * Mathf.Deg2Rad)); + } + + public static T[] SelectRandomFromArray(T[] items, int count) + { + if (items.Length < count) + { + return items; + } + + var list = items.ToList(); + var result = new T[count]; + while (list.Count > 0 && count > 0) + { + count--; + result[count] = list[Random.Range(0, list.Count)]; + list.Remove(result[count]); + } + + return result; + } + + public static Vector3[] GetCirclePoint(Vector3 center, float radius, float step = 0.1f) + { + var points = new List(); + var theta = 0f; + var x = radius * Mathf.Cos(theta); + var y = radius * Mathf.Sin(theta); + points.Add(center + new Vector3(x, 0, y)); + for (theta = step; theta < Mathf.PI * 2; theta += step) + { + x = radius * Mathf.Cos(theta); + y = radius * Mathf.Sin(theta); + points.Add(center + new Vector3(x, 0, y)); + } + + return points.ToArray(); + } + + public static bool LinePlaneIntersection(out Vector3 intersection, Vector3 linePoint, Vector3 lineVec, + Vector3 planeNormal, Vector3 planePoint) + { + float length; + float dotNumerator; + float dotDenominator; + Vector3 vector; + intersection = Vector3.zero; + + //calculate the distance between the linePoint and the line-plane intersection point + dotNumerator = Vector3.Dot((planePoint - linePoint), planeNormal); + dotDenominator = Vector3.Dot(lineVec, planeNormal); + + //line and plane are not parallel + if (dotDenominator != 0.0f) + { + length = dotNumerator / dotDenominator; + + //create a vector from the linePoint to the intersection point + vector = SetVectorLength(lineVec, length); + + //get the coordinates of the line-plane intersection point + intersection = linePoint + vector; + + return true; + } + //output not valid + else + { + return false; + } + } + + public static bool AreLineSegmentsCrossing(Vector3 pointA1, Vector3 pointA2, Vector3 pointB1, Vector3 pointB2) + { + Vector3 closestPointA; + Vector3 closestPointB; + int sideA; + int sideB; + + Vector3 lineVecA = pointA2 - pointA1; + Vector3 lineVecB = pointB2 - pointB1; + + bool valid = ClosestPointsOnTwoLines(out closestPointA, out closestPointB, pointA1, lineVecA.normalized, + pointB1, lineVecB.normalized); + + //lines are not parallel + if (valid) + { + sideA = PointOnWhichSideOfLineSegment(pointA1, pointA2, closestPointA); + sideB = PointOnWhichSideOfLineSegment(pointB1, pointB2, closestPointB); + + if ((sideA == 0) && (sideB == 0)) + { + return true; + } + else + { + return false; + } + } + else + { + return false; + } + } + + public static bool ClosestPointsOnTwoLines(out Vector3 closestPointLine1, out Vector3 closestPointLine2, + Vector3 linePoint1, Vector3 lineVec1, Vector3 linePoint2, Vector3 lineVec2) + { + closestPointLine1 = Vector3.zero; + closestPointLine2 = Vector3.zero; + + float a = Vector3.Dot(lineVec1, lineVec1); + float b = Vector3.Dot(lineVec1, lineVec2); + float e = Vector3.Dot(lineVec2, lineVec2); + + float d = a * e - b * b; + + //lines are not parallel + if (d != 0.0f) + { + Vector3 r = linePoint1 - linePoint2; + float c = Vector3.Dot(lineVec1, r); + float f = Vector3.Dot(lineVec2, r); + + float s = (b * f - c * e) / d; + float t = (a * f - c * b) / d; + + closestPointLine1 = linePoint1 + lineVec1 * s; + closestPointLine2 = linePoint2 + lineVec2 * t; + + return true; + } + + else + { + return false; + } + } + + public static int PointOnWhichSideOfLineSegment(Vector3 linePoint1, Vector3 linePoint2, Vector3 point) + { + Vector3 lineVec = linePoint2 - linePoint1; + Vector3 pointVec = point - linePoint1; + + float dot = Vector3.Dot(pointVec, lineVec); + + //point is on side of linePoint2, compared to linePoint1 + if (dot > 0) + { + //point is on the line segment + if (pointVec.magnitude <= lineVec.magnitude) + { + return 0; + } + + //point is not on the line segment and it is on the side of linePoint2 + else + { + return 2; + } + } + + //Point is not on side of linePoint2, compared to linePoint1. + //Point is not on the line segment and it is on the side of linePoint1. + else + { + return 1; + } + } + + public static Vector3 SetVectorLength(Vector3 vector, float size) + { + //normalize the vector + var vectorNormalized = Vector3.Normalize(vector); + + //scale the vector + return vectorNormalized *= size; + } + + public static Color DotColor(Color a, Color b) + { + var vA = new Vector3(a.r, a.g, a.b); + var vB = new Vector3(b.r, b.g, b.b); + var vC = Vector3.Dot(vA, vB); + return new Color(vC, vC, vC); + } + + public static T GetRandomWithWeight(T[] items, int[] weights) + { + var totalWeight = weights.Sum(); + var rd = Random.Range(0, totalWeight); + var sumWeight = 0; + var result = items[0]; + for (var i = 0; i < items.Length; i++) + { + sumWeight += weights[i]; + if (rd < sumWeight) + { + result = items[i]; + break; + } + } + + return result; + } + } +} \ No newline at end of file diff --git a/VirtueSky/Utils/SimpleMath.cs.meta b/VirtueSky/Utils/SimpleMath.cs.meta new file mode 100644 index 00000000..1cfc3a02 --- /dev/null +++ b/VirtueSky/Utils/SimpleMath.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 596eb1042e0345789ff57fc696c2de73 +timeCreated: 1598278587 \ No newline at end of file diff --git a/VirtueSky/Utils/StoreUtils.cs b/VirtueSky/Utils/StoreUtils.cs new file mode 100644 index 00000000..19abb7e6 --- /dev/null +++ b/VirtueSky/Utils/StoreUtils.cs @@ -0,0 +1,16 @@ +using UnityEngine; + +namespace VirtueSky.Utils +{ + public static class StoreUtils + { + public static void OpenStore() + { +#if UNITY_ANDROID + Application.OpenURL($"market://details?id={Application.identifier}"); +#elif UNITY_IPHONE + Application.OpenURL("itms-apps://itunes.apple.com/app/1598593737"); +#endif + } + } +} \ No newline at end of file diff --git a/VirtueSky/Utils/StoreUtils.cs.meta b/VirtueSky/Utils/StoreUtils.cs.meta new file mode 100644 index 00000000..0168ac72 --- /dev/null +++ b/VirtueSky/Utils/StoreUtils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 95bee5da44516954396fb291ece7ae5f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Utils/TextureUtils.cs b/VirtueSky/Utils/TextureUtils.cs new file mode 100644 index 00000000..dda45917 --- /dev/null +++ b/VirtueSky/Utils/TextureUtils.cs @@ -0,0 +1,68 @@ +#if UNITY_EDITOR +#endif +using System; +using System.IO; +using UnityEditor; +using UnityEngine; +using Object = UnityEngine.Object; + +namespace VirtueSky.Utils +{ +#if UNITY_EDITOR + public static class TextureUtils + { + public static void CaptureToFile(Camera cam, string path, int width = 1024, int height = 1024, int depth = 24, + RenderTextureFormat format = RenderTextureFormat.ARGB32, TextureExtension extension = TextureExtension.PNG, bool refresh = true) + { + var rt = new RenderTexture(width, height, depth, format); + cam.targetTexture = rt; + cam.Render(); + + RenderTextureToFile(rt, path, extension, refresh); + cam.targetTexture = null; + Object.Destroy(rt); + } + + public static void RenderTextureToFile(RenderTexture rt, string path, TextureExtension extension = TextureExtension.PNG, bool refresh = true) + { + var oldRt = RenderTexture.active; + + var tex = new Texture2D(rt.width, rt.height); + RenderTexture.active = rt; + tex.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0); + tex.Apply(); + + Texture2DToFile(tex, path, extension); + + RenderTexture.active = oldRt; + } + + public static void Texture2DToFile(Texture2D tex, string path, TextureExtension extension = TextureExtension.PNG, bool refresh = true) + { + switch (extension) + { + case TextureExtension.PNG: + File.WriteAllBytes(path + ".png", tex.EncodeToPNG()); + break; + case TextureExtension.JPG: + File.WriteAllBytes(path + ".jpg", tex.EncodeToJPG()); + break; + default: + throw new ArgumentOutOfRangeException(nameof(extension), extension, null); + } + + + if (refresh) + { + AssetDatabase.Refresh(); + } + } + + public enum TextureExtension + { + PNG, + JPG + } + } +#endif +} \ No newline at end of file diff --git a/VirtueSky/Utils/TextureUtils.cs.meta b/VirtueSky/Utils/TextureUtils.cs.meta new file mode 100644 index 00000000..7f5b7fe1 --- /dev/null +++ b/VirtueSky/Utils/TextureUtils.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 03a0e739fe864fc69e58652dc60f8e67 +timeCreated: 1608451762 \ No newline at end of file diff --git a/VirtueSky/Utils/TimeUtils.cs b/VirtueSky/Utils/TimeUtils.cs new file mode 100644 index 00000000..b675d2dd --- /dev/null +++ b/VirtueSky/Utils/TimeUtils.cs @@ -0,0 +1,89 @@ +using System; + +namespace VirtueSky.Utils +{ + public static class TimeUtils + { + public static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0); + public static readonly DateTime EpochUtc = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + public static DateTime Now => DateTime.Now; + public static long CurrentTicks => DateTime.Now.Ticks - Epoch.Ticks; + + public static long CurrentTicksUtc => DateTime.UtcNow.Ticks - EpochUtc.Ticks; + + public static long CurrentDays => CurrentTicks / TimeSpan.TicksPerDay; + + public static double CurrentSeconds => TicksToSeconds(CurrentTicks); + + public static double CurrentSecondsUtc => TicksToSeconds(CurrentTicksUtc); + + public static DateTime TicksToDateTime(long ticks) + { + var date = Epoch + TimeSpan.FromTicks(ticks); + return date.ToLocalTime(); + } + + public static DateTime SecondsToDateTime(double seconds) + { + var date = Epoch + TimeSpan.FromSeconds(seconds); + return date; + } + + public static double TimespanSeconds(long ticks, long lastTicks) + { + return TimeSpan.FromTicks(ticks - lastTicks).TotalSeconds; + } + + public static double TimespanHours(long ticks, long lastTicks) + { + return TimeSpan.FromTicks(ticks - lastTicks).TotalHours; + } + + public static long SecondsToTicks(double seconds) + { + return (long)(seconds * TimeSpan.TicksPerSecond); + } + + public static int SecondsToMiniseconds(double seconds) + { + return (int)(seconds * 1000); + } + + public static double MinisecondsToSeconds(int miniseconds) + { + return (double)(miniseconds / 1000f); + } + + public static double TicksToSeconds(long ticks) + { + return (double)ticks / TimeSpan.TicksPerSecond; + } + + public static long SecondsToDays(double seconds) + { + return SecondsToTicks(seconds) / TimeSpan.TicksPerDay; + } + + public static double DaysToSeconds(long days) + { + return TimeSpan.FromDays(days).TotalSeconds; + } + + public static string FormatTimeSpan(double seconds) + { + var span = new TimeSpan(SecondsToTicks(seconds)); + return span.Days > 0 ? $"{span.Days}:{span.Hours:00}:{span.Minutes:00}:{span.Seconds:00}" : + span.Hours > 0 ? $"{span.Hours:00}:{span.Minutes:00}:{span.Seconds:00}" : + $"{span.Minutes:00}:{span.Seconds:00}"; + } + + public static string FormatTimeSpanExcludeSecond(double seconds) + { + var span = new TimeSpan(SecondsToTicks(seconds)); + return span.Hours > 0 ? $"{span.Hours:00}h:{span.Minutes:00}min" : $"{span.Minutes:00}min"; + } + + public static float TargetTimeScale { get; set; } = 1; + } +} \ No newline at end of file diff --git a/VirtueSky/Utils/TimeUtils.cs.meta b/VirtueSky/Utils/TimeUtils.cs.meta new file mode 100644 index 00000000..3e57c45b --- /dev/null +++ b/VirtueSky/Utils/TimeUtils.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 56cb55840fb34aedb0e10253d754d60c +timeCreated: 1596822219 \ No newline at end of file diff --git a/VirtueSky/Variables.meta b/VirtueSky/Variables.meta new file mode 100644 index 00000000..28e0ef23 --- /dev/null +++ b/VirtueSky/Variables.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 220c229567bfa014885a022face64260 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Variables/BaseReference.cs b/VirtueSky/Variables/BaseReference.cs new file mode 100644 index 00000000..9acb6c32 --- /dev/null +++ b/VirtueSky/Variables/BaseReference.cs @@ -0,0 +1,166 @@ +using System; +using UnityEditor; +using UnityEngine; +#if UNITY_EDITOR +#endif + +namespace VirtueSky.Variables +{ + [Serializable] + public class BaseReference : IReference + { + } + + [Serializable] + public class BaseReference : BaseReference, IReference + where TVariable : BaseVariable + { + [SerializeField] bool useVariable; + [SerializeField] TType constantValue; + [SerializeField] TVariable variable; + + public TType Value + { + get => useVariable ? variable.Value : constantValue; + set + { + if (useVariable) + { + variable.Value = value; + } + else + { + constantValue = value; + } + } + } + + public override string ToString() + { + return Value.ToString(); + } + } + +#if UNITY_EDITOR + [CustomPropertyDrawer(typeof(BaseReference), true)] + public sealed class BaseReferenceDrawer : PropertyDrawer + { + static readonly string[] popupOptions = + { + "Use Constant", + "Use Variable" + }; + + SerializedProperty property; + SerializedProperty useVariable; + SerializedProperty constantValue; + SerializedProperty variable; + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + this.property = property; + useVariable = property.FindPropertyRelative("useVariable"); + constantValue = property.FindPropertyRelative("constantValue"); + variable = property.FindPropertyRelative("variable"); + + var oldIndent = ResetIndent(); + + var fieldRect = DrawLabel(position, property, label); + var valueRect = DrawField(position, fieldRect); + DrawValue(position, valueRect); + + EndIndent(oldIndent); + + property.serializedObject.ApplyModifiedProperties(); + } + + Rect DrawLabel(Rect position, SerializedProperty property, GUIContent label) + { + return EditorGUI.PrefixLabel(position, label); + } + + Rect DrawField(Rect position, Rect fieldRect) + { + var buttonRect = GetPopupButtonRect(fieldRect); + var valueRect = GetValueRect(fieldRect, buttonRect); + + var result = DrawPopupButton(buttonRect, useVariable.boolValue ? 1 : 0); + useVariable.boolValue = result == 1; + + return valueRect; + } + + void DrawValue(Rect position, Rect valueRect) + { + if (useVariable.boolValue) + { + EditorGUI.PropertyField(valueRect, variable, GUIContent.none); + } + else + { + DrawGenericPropertyField(position, valueRect); + } + } + + void DrawGenericPropertyField(Rect position, Rect valueRect) + { + EditorGUI.PropertyField(valueRect, constantValue, GUIContent.none); + } + + int ResetIndent() + { + var indent = EditorGUI.indentLevel; + EditorGUI.indentLevel = 0; + + return indent; + } + + void EndIndent(int indent) + { + EditorGUI.indentLevel = indent; + } + + int DrawPopupButton(Rect rect, int value) + { + return EditorGUI.Popup(rect, value, popupOptions, Styles.PopupStyle); + } + + Rect GetValueRect(Rect fieldRect, Rect buttonRect) + { + var valueRect = new Rect(fieldRect); + valueRect.x += buttonRect.width; + valueRect.width -= buttonRect.width; + + return valueRect; + } + + Rect GetPopupButtonRect(Rect fieldrect) + { + var buttonRect = new Rect(fieldrect); + buttonRect.yMin += Styles.PopupStyle.margin.top; + buttonRect.width = Styles.PopupStyle.fixedWidth + Styles.PopupStyle.margin.right; + buttonRect.height = Styles.PopupStyle.fixedHeight + Styles.PopupStyle.margin.top; + + return buttonRect; + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + return EditorGUIUtility.singleLineHeight; + } + + static class Styles + { + static Styles() + { + PopupStyle = new GUIStyle(GUI.skin.GetStyle("PaneOptions")) + { + imagePosition = ImagePosition.ImageOnly, + }; + } + + public static GUIStyle PopupStyle { get; set; } + } + } +#endif +} \ No newline at end of file diff --git a/VirtueSky/Variables/BaseReference.cs.meta b/VirtueSky/Variables/BaseReference.cs.meta new file mode 100644 index 00000000..1be1d64f --- /dev/null +++ b/VirtueSky/Variables/BaseReference.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e2fd30b177734d4d8a02e823ec21b503 +timeCreated: 1651588713 \ No newline at end of file diff --git a/VirtueSky/Variables/BaseVariable.cs b/VirtueSky/Variables/BaseVariable.cs new file mode 100644 index 00000000..0b34f98a --- /dev/null +++ b/VirtueSky/Variables/BaseVariable.cs @@ -0,0 +1,55 @@ +using System; +using UnityEngine; +using VirtueSky.DataStorage; +using VirtueSky.Events; + +namespace VirtueSky.Variables +{ + public class BaseVariable : BaseEvent, IVariable, ISerializationCallbackReceiver + { + [SerializeField] TType initializeValue; + [SerializeField] bool isSavable; + [SerializeField] bool isRaiseEvent; + [NonSerialized] TType runtimeValue; + + public TType Value + { + get => isSavable ? GameData.Get(Id, initializeValue) : runtimeValue; + set + { + if (isSavable) + { + GameData.Set(Id, value); + } + else + { + runtimeValue = value; + } + + if (isRaiseEvent) + { + Raise(value); + } + } + } + + public void OnBeforeSerialize() + { + } + + public void OnAfterDeserialize() + { + runtimeValue = initializeValue; + } + + public void ResetValue() + { + Value = initializeValue; + } + + public override string ToString() + { + return Value.ToString(); + } + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/BaseVariable.cs.meta b/VirtueSky/Variables/BaseVariable.cs.meta new file mode 100644 index 00000000..56671af1 --- /dev/null +++ b/VirtueSky/Variables/BaseVariable.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 354f4bae410149e59e0ac1eec4ddc1e5 +timeCreated: 1651587715 \ No newline at end of file diff --git a/VirtueSky/Variables/BaseVariableListener.cs b/VirtueSky/Variables/BaseVariableListener.cs new file mode 100644 index 00000000..2139a754 --- /dev/null +++ b/VirtueSky/Variables/BaseVariableListener.cs @@ -0,0 +1,37 @@ +using UnityEngine; +using UnityEngine.Events; +using VirtueSky.Events; + +namespace VirtueSky.Variables +{ + public class BaseVariableListener : BaseEventListener + where TEvent : BaseVariable + where TResponse : UnityEvent + { + [SerializeField] bool setOnEnable; + + public override void Initialize() + { + base.Initialize(); + if (setOnEnable) + { + foreach (var t in listEventResponseDatas) + { + OnEventRaised(t.@event, t.@event.Value); + } + } + } + + public override void DoEnable() + { + base.DoEnable(); + if (setOnEnable) + { + foreach (var t in listEventResponseDatas) + { + OnEventRaised(t.@event, t.@event.Value); + } + } + } + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/BaseVariableListener.cs.meta b/VirtueSky/Variables/BaseVariableListener.cs.meta new file mode 100644 index 00000000..092b8a38 --- /dev/null +++ b/VirtueSky/Variables/BaseVariableListener.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 618fae92af2d4fd59f81d8f97daf73a6 +timeCreated: 1660205495 \ No newline at end of file diff --git a/VirtueSky/Variables/BooleanReference.cs b/VirtueSky/Variables/BooleanReference.cs new file mode 100644 index 00000000..821dfc4f --- /dev/null +++ b/VirtueSky/Variables/BooleanReference.cs @@ -0,0 +1,9 @@ +using System; + +namespace VirtueSky.Variables +{ + [Serializable] + public class BooleanReference : BaseReference + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/BooleanReference.cs.meta b/VirtueSky/Variables/BooleanReference.cs.meta new file mode 100644 index 00000000..d4b79ab3 --- /dev/null +++ b/VirtueSky/Variables/BooleanReference.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5afc2b5361de44a59b143ce9db37d46f +timeCreated: 1659149814 \ No newline at end of file diff --git a/VirtueSky/Variables/BooleanVariable.cs b/VirtueSky/Variables/BooleanVariable.cs new file mode 100644 index 00000000..c05b22dd --- /dev/null +++ b/VirtueSky/Variables/BooleanVariable.cs @@ -0,0 +1,10 @@ +using UnityEngine; +using VirtueSky.Variables; + +namespace VirtueSky.Variables +{ + [CreateAssetMenu(menuName = "Variables/Boolean")] + public class BooleanVariable : BaseVariable + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/BooleanVariable.cs.meta b/VirtueSky/Variables/BooleanVariable.cs.meta new file mode 100644 index 00000000..f03cbd93 --- /dev/null +++ b/VirtueSky/Variables/BooleanVariable.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8612af88fd55455ab06a565de64186b9 +timeCreated: 1659149776 \ No newline at end of file diff --git a/VirtueSky/Variables/FloatReference.cs b/VirtueSky/Variables/FloatReference.cs new file mode 100644 index 00000000..5f9b1bfd --- /dev/null +++ b/VirtueSky/Variables/FloatReference.cs @@ -0,0 +1,9 @@ +using System; + +namespace VirtueSky.Variables +{ + [Serializable] + public class FloatReference : BaseReference + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/FloatReference.cs.meta b/VirtueSky/Variables/FloatReference.cs.meta new file mode 100644 index 00000000..310a3c64 --- /dev/null +++ b/VirtueSky/Variables/FloatReference.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1e5ea93b60834733af1822c26b795c31 +timeCreated: 1651588790 \ No newline at end of file diff --git a/VirtueSky/Variables/FloatVariable.cs b/VirtueSky/Variables/FloatVariable.cs new file mode 100644 index 00000000..ab6316cd --- /dev/null +++ b/VirtueSky/Variables/FloatVariable.cs @@ -0,0 +1,10 @@ +using UnityEngine; + + +namespace VirtueSky.Variables +{ + [CreateAssetMenu(menuName = "Variables/Float")] + public class FloatVariable : BaseVariable + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/FloatVariable.cs.meta b/VirtueSky/Variables/FloatVariable.cs.meta new file mode 100644 index 00000000..4cd8b42b --- /dev/null +++ b/VirtueSky/Variables/FloatVariable.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e09883a9e2054c19929fd8b3292fa7d9 +timeCreated: 1651588182 \ No newline at end of file diff --git a/VirtueSky/Variables/FloatVariableListener.cs b/VirtueSky/Variables/FloatVariableListener.cs new file mode 100644 index 00000000..cae3aece --- /dev/null +++ b/VirtueSky/Variables/FloatVariableListener.cs @@ -0,0 +1,8 @@ +using VirtueSky.Events; + +namespace VirtueSky.Variables +{ + public class FloatVariableListener : BaseVariableListener + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/FloatVariableListener.cs.meta b/VirtueSky/Variables/FloatVariableListener.cs.meta new file mode 100644 index 00000000..7ea6c78a --- /dev/null +++ b/VirtueSky/Variables/FloatVariableListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a246834ae1b84ef38132800b51b86cfe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Variables/IReference.cs b/VirtueSky/Variables/IReference.cs new file mode 100644 index 00000000..dd2ede08 --- /dev/null +++ b/VirtueSky/Variables/IReference.cs @@ -0,0 +1,11 @@ +namespace VirtueSky.Variables +{ + public interface IReference + { + } + + public interface IReference : IReference + { + TType Value { get; set; } + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/IReference.cs.meta b/VirtueSky/Variables/IReference.cs.meta new file mode 100644 index 00000000..e0236565 --- /dev/null +++ b/VirtueSky/Variables/IReference.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 651c592a5818b6b49bc85bab221450ba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Variables/IVariable.cs b/VirtueSky/Variables/IVariable.cs new file mode 100644 index 00000000..087202d7 --- /dev/null +++ b/VirtueSky/Variables/IVariable.cs @@ -0,0 +1,7 @@ +namespace VirtueSky.Variables +{ + public interface IVariable + { + TType Value { get; set; } + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/IVariable.cs.meta b/VirtueSky/Variables/IVariable.cs.meta new file mode 100644 index 00000000..c17ab969 --- /dev/null +++ b/VirtueSky/Variables/IVariable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 271e3e5d558841141b076d69acb0b86b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Variables/IntegerReference.cs b/VirtueSky/Variables/IntegerReference.cs new file mode 100644 index 00000000..b7cf25b7 --- /dev/null +++ b/VirtueSky/Variables/IntegerReference.cs @@ -0,0 +1,9 @@ +using System; + +namespace VirtueSky.Variables +{ + [Serializable] + public class IntegerReference : BaseReference + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/IntegerReference.cs.meta b/VirtueSky/Variables/IntegerReference.cs.meta new file mode 100644 index 00000000..3bfd73eb --- /dev/null +++ b/VirtueSky/Variables/IntegerReference.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4848f429140e4efcbf42ee9e910e9bb3 +timeCreated: 1659595428 \ No newline at end of file diff --git a/VirtueSky/Variables/IntegerVariable.cs b/VirtueSky/Variables/IntegerVariable.cs new file mode 100644 index 00000000..92ae4349 --- /dev/null +++ b/VirtueSky/Variables/IntegerVariable.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace VirtueSky.Variables +{ + [CreateAssetMenu(menuName = "Variables/Integer")] + public class IntegerVariable : BaseVariable + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/IntegerVariable.cs.meta b/VirtueSky/Variables/IntegerVariable.cs.meta new file mode 100644 index 00000000..f4f474fd --- /dev/null +++ b/VirtueSky/Variables/IntegerVariable.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c1e2751cf33a439b997c1f79b966df48 +timeCreated: 1659595428 \ No newline at end of file diff --git a/VirtueSky/Variables/IntegerVariableListener.cs b/VirtueSky/Variables/IntegerVariableListener.cs new file mode 100644 index 00000000..9e4703d4 --- /dev/null +++ b/VirtueSky/Variables/IntegerVariableListener.cs @@ -0,0 +1,8 @@ +using VirtueSky.Events; + +namespace VirtueSky.Variables +{ + public class IntegerVariableListener : BaseVariableListener + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/IntegerVariableListener.cs.meta b/VirtueSky/Variables/IntegerVariableListener.cs.meta new file mode 100644 index 00000000..74cf3028 --- /dev/null +++ b/VirtueSky/Variables/IntegerVariableListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3184f556234f4c47b9374467cd4afcef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Variables/ObjectReference.cs b/VirtueSky/Variables/ObjectReference.cs new file mode 100644 index 00000000..3e15c68d --- /dev/null +++ b/VirtueSky/Variables/ObjectReference.cs @@ -0,0 +1,10 @@ +using System; +using Object = UnityEngine.Object; + +namespace VirtueSky.Variables +{ + [Serializable] + public class ObjectReference : BaseReference + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/ObjectReference.cs.meta b/VirtueSky/Variables/ObjectReference.cs.meta new file mode 100644 index 00000000..c997267a --- /dev/null +++ b/VirtueSky/Variables/ObjectReference.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 29476f09124c4a239c99d28185892add +timeCreated: 1651594418 \ No newline at end of file diff --git a/VirtueSky/Variables/ObjectVariable.cs b/VirtueSky/Variables/ObjectVariable.cs new file mode 100644 index 00000000..9726bfad --- /dev/null +++ b/VirtueSky/Variables/ObjectVariable.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace VirtueSky.Variables +{ + [CreateAssetMenu(menuName = "Variables/Object")] + public class ObjectVariable : BaseVariable + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/ObjectVariable.cs.meta b/VirtueSky/Variables/ObjectVariable.cs.meta new file mode 100644 index 00000000..69aed36f --- /dev/null +++ b/VirtueSky/Variables/ObjectVariable.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0a14f4e476834f9a917da6b6bf0b5d88 +timeCreated: 1651594395 \ No newline at end of file diff --git a/VirtueSky/Variables/RectVariable.cs b/VirtueSky/Variables/RectVariable.cs new file mode 100644 index 00000000..b385f0c2 --- /dev/null +++ b/VirtueSky/Variables/RectVariable.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace VirtueSky.Variables +{ + [CreateAssetMenu(menuName = "Variables/Rect")] + public class RectVariable : BaseVariable + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/RectVariable.cs.meta b/VirtueSky/Variables/RectVariable.cs.meta new file mode 100644 index 00000000..5765cffb --- /dev/null +++ b/VirtueSky/Variables/RectVariable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aa90022cc8bc365459867349d32fba34 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Variables/ShortDoubleReference.cs b/VirtueSky/Variables/ShortDoubleReference.cs new file mode 100644 index 00000000..d60a5ab6 --- /dev/null +++ b/VirtueSky/Variables/ShortDoubleReference.cs @@ -0,0 +1,10 @@ +using System; +using VirtueSky.DataType; + +namespace VirtueSky.Variables +{ + [Serializable] + public class ShortDoubleReference : BaseReference + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/ShortDoubleReference.cs.meta b/VirtueSky/Variables/ShortDoubleReference.cs.meta new file mode 100644 index 00000000..527c1b36 --- /dev/null +++ b/VirtueSky/Variables/ShortDoubleReference.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0e49dc8d16524024cb54cf7f9c0abea8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Variables/ShortDoubleVariable.cs b/VirtueSky/Variables/ShortDoubleVariable.cs new file mode 100644 index 00000000..66abf0c4 --- /dev/null +++ b/VirtueSky/Variables/ShortDoubleVariable.cs @@ -0,0 +1,10 @@ +using UnityEngine; +using VirtueSky.DataType; + +namespace VirtueSky.Variables +{ + [CreateAssetMenu(menuName = "Variables/ShortDouble")] + public class ShortDoubleVariable : BaseVariable + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/ShortDoubleVariable.cs.meta b/VirtueSky/Variables/ShortDoubleVariable.cs.meta new file mode 100644 index 00000000..a1e598d1 --- /dev/null +++ b/VirtueSky/Variables/ShortDoubleVariable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4c151fa8c0723124eb8aedcc6c272839 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Variables/ShortDoubleVariableListener.cs b/VirtueSky/Variables/ShortDoubleVariableListener.cs new file mode 100644 index 00000000..9866ae06 --- /dev/null +++ b/VirtueSky/Variables/ShortDoubleVariableListener.cs @@ -0,0 +1,9 @@ +using VirtueSky.DataType; +using VirtueSky.Events; + +namespace VirtueSky.Variables +{ + public class ShortDoubleVariableListener : BaseVariableListener + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/ShortDoubleVariableListener.cs.meta b/VirtueSky/Variables/ShortDoubleVariableListener.cs.meta new file mode 100644 index 00000000..dbf96031 --- /dev/null +++ b/VirtueSky/Variables/ShortDoubleVariableListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e1cc454b4a0e77b458061f8da8a844ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Variables/StringVariable.cs b/VirtueSky/Variables/StringVariable.cs new file mode 100644 index 00000000..827f5214 --- /dev/null +++ b/VirtueSky/Variables/StringVariable.cs @@ -0,0 +1,10 @@ +using UnityEngine; + + +namespace VirtueSky.Variables +{ + [CreateAssetMenu(menuName = "Variables/String")] + public class StringVariable : BaseVariable + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/StringVariable.cs.meta b/VirtueSky/Variables/StringVariable.cs.meta new file mode 100644 index 00000000..935e2eef --- /dev/null +++ b/VirtueSky/Variables/StringVariable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ac78349e5fc985d48b9901f74f86c69c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Variables/StringVariableListener.cs b/VirtueSky/Variables/StringVariableListener.cs new file mode 100644 index 00000000..32afba8e --- /dev/null +++ b/VirtueSky/Variables/StringVariableListener.cs @@ -0,0 +1,9 @@ +using VirtueSky.Events; + + +namespace VirtueSky.Variables +{ + public class StringVariableListener : BaseVariableListener + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/StringVariableListener.cs.meta b/VirtueSky/Variables/StringVariableListener.cs.meta new file mode 100644 index 00000000..657e5051 --- /dev/null +++ b/VirtueSky/Variables/StringVariableListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2205b9d988c5bbf41bcf05224141d0ac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/Variables/TransformReference.cs b/VirtueSky/Variables/TransformReference.cs new file mode 100644 index 00000000..b23b8502 --- /dev/null +++ b/VirtueSky/Variables/TransformReference.cs @@ -0,0 +1,10 @@ +using System; +using UnityEngine; + +namespace VirtueSky.Variables +{ + [Serializable] + public class TransformReference : BaseReference + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/TransformReference.cs.meta b/VirtueSky/Variables/TransformReference.cs.meta new file mode 100644 index 00000000..876e71fe --- /dev/null +++ b/VirtueSky/Variables/TransformReference.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 09c1018d879b4836aa50590af7928614 +timeCreated: 1663139158 \ No newline at end of file diff --git a/VirtueSky/Variables/TransformVariable.cs b/VirtueSky/Variables/TransformVariable.cs new file mode 100644 index 00000000..8160dbee --- /dev/null +++ b/VirtueSky/Variables/TransformVariable.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace VirtueSky.Variables +{ + [CreateAssetMenu(menuName = "Variables/Transform")] + public class TransformVariable : BaseVariable + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/TransformVariable.cs.meta b/VirtueSky/Variables/TransformVariable.cs.meta new file mode 100644 index 00000000..0c0ef08f --- /dev/null +++ b/VirtueSky/Variables/TransformVariable.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 864f507d17eb4386b9d734dc4ac56fdc +timeCreated: 1663139158 \ No newline at end of file diff --git a/VirtueSky/Variables/Vector3Reference.cs b/VirtueSky/Variables/Vector3Reference.cs new file mode 100644 index 00000000..80005021 --- /dev/null +++ b/VirtueSky/Variables/Vector3Reference.cs @@ -0,0 +1,10 @@ +using System; +using UnityEngine; + +namespace VirtueSky.Variables +{ + [Serializable] + public class Vector3Reference : BaseReference + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/Vector3Reference.cs.meta b/VirtueSky/Variables/Vector3Reference.cs.meta new file mode 100644 index 00000000..dbd9d111 --- /dev/null +++ b/VirtueSky/Variables/Vector3Reference.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c8538927a6f440d09b3d9bd721c98d03 +timeCreated: 1659591686 \ No newline at end of file diff --git a/VirtueSky/Variables/Vector3Variable.cs b/VirtueSky/Variables/Vector3Variable.cs new file mode 100644 index 00000000..b6a00476 --- /dev/null +++ b/VirtueSky/Variables/Vector3Variable.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace VirtueSky.Variables +{ + [CreateAssetMenu(menuName = "Variables/Vector3")] + public class Vector3Variable : BaseVariable + { + } +} \ No newline at end of file diff --git a/VirtueSky/Variables/Vector3Variable.cs.meta b/VirtueSky/Variables/Vector3Variable.cs.meta new file mode 100644 index 00000000..9b4896ee --- /dev/null +++ b/VirtueSky/Variables/Vector3Variable.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b70b256ab705423f99a909c913eecede +timeCreated: 1659591686 \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 00000000..11927819 --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "com.virtuesky.scriptableobject.architecture", + "displayName": "ScriptableObjectArchitecture", + "description": "ScriptableObjectArchitecture for unity", + "version": "1.0.0", + "unity": "2021.3", + "category": "virtuesky", + "keywords": [ + "ScriptableObjectArchitecture", + "ScriptableObject", + "Architecture", + "Unity" + ], + "dependencies": {} +} \ No newline at end of file diff --git a/package.json.meta b/package.json.meta new file mode 100644 index 00000000..c334e46c --- /dev/null +++ b/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 124b2d6d5f51c4f1f970cf0138354eb3 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/virtuesky@SOArchitecture.asmdef b/virtuesky@SOArchitecture.asmdef new file mode 100644 index 00000000..acdfb669 --- /dev/null +++ b/virtuesky@SOArchitecture.asmdef @@ -0,0 +1,14 @@ +{ + "name": "virtuesky@SO.Architecture", + "rootNamespace": "", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/virtuesky@SOArchitecture.asmdef.meta b/virtuesky@SOArchitecture.asmdef.meta new file mode 100644 index 00000000..a75bf50d --- /dev/null +++ b/virtuesky@SOArchitecture.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9290e2823bed84cbf86be0b95066e1d7 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: