James Peret преди 3 години
ревизия
4cde4c03df

+ 71 - 0
.gitignore

@@ -0,0 +1,71 @@
+# This .gitignore file should be placed at the root of your Unity project directory
+#
+# Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore
+#
+/[Ll]ibrary/
+/[Tt]emp/
+/[Oo]bj/
+/[Bb]uild/
+/[Bb]uilds/
+/[Ll]ogs/
+/[Uu]ser[Ss]ettings/
+
+# MemoryCaptures can get excessive in size.
+# They also could contain extremely sensitive data
+/[Mm]emoryCaptures/
+
+# Asset meta data should only be ignored when the corresponding asset is also ignored
+!/[Aa]ssets/**/*.meta
+
+# Uncomment this line if you wish to ignore the asset store tools plugin
+# /[Aa]ssets/AssetStoreTools*
+
+# Autogenerated Jetbrains Rider plugin
+/[Aa]ssets/Plugins/Editor/JetBrains*
+
+# Visual Studio cache directory
+.vs/
+
+# Gradle cache directory
+.gradle/
+
+# Autogenerated VS/MD/Consulo solution and project files
+ExportedObj/
+.consulo/
+*.csproj
+*.unityproj
+*.sln
+*.suo
+*.tmp
+*.user
+*.userprefs
+*.pidb
+*.booproj
+*.svd
+*.pdb
+*.mdb
+*.opendb
+*.VC.db
+
+# Unity3D generated meta files
+*.pidb.meta
+*.pdb.meta
+*.mdb.meta
+
+# Unity3D generated file on crash reports
+sysinfo.txt
+
+# Builds
+*.apk
+*.aab
+*.unitypackage
+
+# Crashlytics generated file
+crashlytics-build.properties
+
+# Packed Addressables
+/[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin*
+
+# Temporary auto-generated Android Assets
+/[Aa]ssets/[Ss]treamingAssets/aa.meta
+/[Aa]ssets/[Ss]treamingAssets/aa/*

+ 25 - 0
Readme.md

@@ -0,0 +1,25 @@
+# 📦 KairoEngine.Statistics v0.2.0
+
+Statistics database library for kairoEngine.
+
+### 🛑Required packages
+
+- `KairoEngine.Core`
+- `KairoEngine.Utilities`
+- `Sirenix`
+- `QFSW`
+
+### 📄Namespaces
+
+- `KairoEngine.Statistics`
+
+### 📙Modules
+
+- **Statistics module** – Loads the Statistics system with a database
+
+### 📄Changelog
+
+##### v0.2.0
+
+- Moved Statistics library from Utilities package to its own package
+- Added Statistics GameModule

+ 7 - 0
Readme.md.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 754155587ecf0994caf641b9652da7af
+TextScriptImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Runtime.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: f816662f51348004b9a7e29c4a97f21e
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 19 - 0
Runtime/KairoEngine.Statistics.asmdef

@@ -0,0 +1,19 @@
+{
+    "name": "KairoEngine.Statistics",
+    "rootNamespace": "",
+    "references": [
+        "GUID:7e5ae6a38d1532248b4c890eca668b06",
+        "GUID:165d83fc3bb2a4144925c85421871d8e",
+        "GUID:e048eeec9bdb9d30448017b829deb3f6",
+        "GUID:fb24642277b1db2449da7ac148ce939d"
+    ],
+    "includePlatforms": [],
+    "excludePlatforms": [],
+    "allowUnsafeCode": false,
+    "overrideReferences": false,
+    "precompiledReferences": [],
+    "autoReferenced": true,
+    "defineConstraints": [],
+    "versionDefines": [],
+    "noEngineReferences": false
+}

+ 7 - 0
Runtime/KairoEngine.Statistics.asmdef.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: ca01279424a9a9144a1fea1b6910a36a
+AssemblyDefinitionImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 51 - 0
Runtime/StatisticChangeInteger.cs

@@ -0,0 +1,51 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using Sirenix.OdinInspector;
+
+namespace KairoEngine.Statistics
+{
+    public enum StatisticChangeIntegerTrigger
+    {
+        OnStart,
+        OnDisable,
+        OnDestroy
+    }
+
+    [HideMonoScript]
+    public class StatisticChangeInteger : MonoBehaviour
+    {
+        [HorizontalGroup()] public string statisticName = "";
+        [HorizontalGroup(80), ReadOnly, HideLabel] public string value;
+
+        public StatisticChangeIntegerTrigger trigger;
+        public int number;
+
+        void Start()
+        {
+            if(Statistics.instance == null) Debug.LogError("Statistics not loaded yet");
+            if(trigger == StatisticChangeIntegerTrigger.OnStart) ChangeInteger();
+        }
+
+        void OnDisable()
+        {
+            if(trigger == StatisticChangeIntegerTrigger.OnDisable) ChangeInteger();
+        }
+
+        void OnDestroy()
+        {
+            if(trigger == StatisticChangeIntegerTrigger.OnDestroy) ChangeInteger();
+        }
+
+        void Update()
+        {
+            value = Statistics.GetData(statisticName).GetInteger().ToString();
+        }
+
+        public void ChangeInteger()
+        {
+            Statistics.GetData(statisticName).AddInteger(number);
+        }
+    }
+}
+

+ 11 - 0
Runtime/StatisticChangeInteger.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 71a9a6d00db694e40938597e57bd95cf
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 75 - 0
Runtime/StatisticData.cs

@@ -0,0 +1,75 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using Sirenix.OdinInspector;
+using KairoEngine.Core;
+
+namespace KairoEngine.Statistics
+{
+    public enum StatisticType
+    {
+        time,
+        integer,
+        text
+    }
+
+    [System.Serializable, HideMonoScript]
+    public class StatisticData
+    {
+        [HorizontalGroup(180), HideLabel] public string title;
+
+        [ShowIf("@category == StatisticType.time"), HorizontalGroup(), HideLabel, ShowInInspector] private float time;
+        [ShowIf("@category == StatisticType.integer"), HorizontalGroup(), HideLabel, ShowInInspector] private int integer;
+        [ShowIf("@category == StatisticType.text"), HorizontalGroup(), HideLabel, ShowInInspector] private string text;
+        [HorizontalGroup(80), HideLabel] public StatisticType category;
+        [HorizontalGroup(), HideLabel, Tooltip("Persistent Data?")] public bool persistent = false;
+
+        public void AddTime(float t)
+        {
+            time += t;
+            TriggerEvent(time);
+        } 
+
+        public void AddInteger(int n)
+        {
+            integer += n;
+            TriggerEvent(integer);
+        } 
+
+        public float GetTime() => time;
+        public int GetInteger() => integer;
+        public string GetText() => text;
+
+        public void SetTime(float t) 
+        {
+            time = t;
+            TriggerEvent(time);
+        } 
+
+        public void SetInteger(int n) 
+        {
+            integer = n;
+            TriggerEvent(integer);
+        }
+
+        public void SetText(string t)
+        {
+            text = t;
+            TriggerEvent(text);
+        } 
+
+        public void Reset()
+        {
+            time = 0f;
+            integer = 0;
+            text = "";
+        }
+
+        private void TriggerEvent(float time) => GenericEvents.Trigger("StatisticDataChanged", title, time);
+
+        private void TriggerEvent(int integer) => GenericEvents.Trigger("StatisticDataChanged", title, integer);
+
+        private void TriggerEvent(string text) => GenericEvents.Trigger("StatisticDataChanged", title, text);
+
+    }
+}

+ 11 - 0
Runtime/StatisticData.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 919fc0a3cb4d10b4d8651a582a736d4e
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 39 - 0
Runtime/StatisticElapsedTime.cs

@@ -0,0 +1,39 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using KairoEngine.Utility;
+using Sirenix.OdinInspector;
+using KairoEngine.Core;
+
+namespace KairoEngine.Statistics
+{
+    [HideMonoScript]
+    public class StatisticElapsedTime : MonoBehaviour
+    {
+        public string statisticName = "";
+        [ReadOnly] public string elapsedTime;
+
+        [HorizontalGroup()] public bool unscaledDeltaTime = true;
+        [HorizontalGroup()] public bool resetOnStart = true;
+
+        void Start()
+        {
+            if(resetOnStart) Statistics.GetData(statisticName).Reset();
+        }
+
+        void Update()
+        {
+            if(unscaledDeltaTime)
+            {
+                Statistics.GetData(statisticName).AddTime(Time.unscaledDeltaTime);
+            }
+            else
+            {
+                Statistics.GetData(statisticName).AddTime(Time.deltaTime);
+            }
+            float time = Statistics.GetData(statisticName).GetTime();
+            elapsedTime = KairoEngine.Core.Utilities.TimeToString(time);
+        }
+    }
+}
+

+ 11 - 0
Runtime/StatisticElapsedTime.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0f810b498e3e89445aa607425e0fdcac
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 155 - 0
Runtime/Statistics.cs

@@ -0,0 +1,155 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using KairoEngine.Core;
+using Sirenix.OdinInspector;
+
+namespace KairoEngine.Statistics
+{
+    [HideMonoScript]
+    public class Statistics : SerializedMonoBehaviour
+    {
+        #region Singleton
+        private static Statistics statistics;
+        public static Statistics instance
+        {
+            get {
+                if(!statistics)
+                {
+                    statistics = FindObjectOfType (typeof(Statistics)) as Statistics;
+                    if(!statistics)
+                    {
+                        Debug.LogError("There need to one active Statistics script on the scene.");
+                        return null;
+                    }
+                }
+                return statistics;
+            }
+        }
+        #endregion
+
+        public bool listenForStatisticsEvents = true;
+        public string setStatisticEvent = "SetStatisticData";
+        [InlineEditor(InlineEditorObjectFieldModes.Boxed)] public StatisticsLibrary db;
+
+        void Awake()
+        {
+            if(instance != null && instance != this) 
+            {
+                Destroy(this.gameObject);
+                return;
+            }
+        }
+
+        void Start()
+        {
+            if(db == null)
+            {
+                Debug.LogError("Statistics component is missing the StatisticsList.\nPlease configure the statistics module in the Game config file.");
+                return;
+            }
+            LoadStatistics();
+            if(!listenForStatisticsEvents) return;
+            GenericEvents.StartListening(setStatisticEvent, SetStatisticInt);
+            GenericEvents.StartListeningForStringFloat(setStatisticEvent, SetStatisticFloat);
+            GenericEvents.StartListening(setStatisticEvent, SetStatisticString);
+        }
+
+        void OnDestroy()
+        {
+            SaveStatistics();
+            if(!listenForStatisticsEvents) return;
+            GenericEvents.StopListening(setStatisticEvent, SetStatisticInt);
+            GenericEvents.StopListeningForStringFloat(setStatisticEvent, SetStatisticFloat);
+            GenericEvents.StopListening(setStatisticEvent, SetStatisticString);
+        }
+
+        public static StatisticData GetData(string title)
+        {
+            if(instance == null) return null;
+            if(instance.db == null) return null;
+            for (int i = 0; i < instance.db.data.Count; i++)
+            {
+                if(instance.db.data[i].title == title) return instance.db.data[i];
+            }
+            return null;
+        }
+
+        private void LoadStatistics()
+        {
+            if(instance == null) return;
+            if(instance.db == null) return;
+            for (int i = 0; i < instance.db.data.Count; i++)
+            {
+                StatisticData stat = instance.db.data[i];
+                if(stat.persistent == false) continue;
+                switch (stat.category)
+                {
+                    case StatisticType.time:
+                        float time = PlayerPrefs.GetFloat(stat.title, 0f);
+                        stat.SetTime(time);
+                        break;
+                    case StatisticType.integer:
+                        int integer = PlayerPrefs.GetInt(stat.title, 0);
+                        stat.SetInteger(integer);
+                        break;
+                    case StatisticType.text:
+                        string text = PlayerPrefs.GetString(stat.title, "");
+                        stat.SetText(text);
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+
+        private void SaveStatistics()
+        {
+            if(instance == null) return;
+            if(instance.db == null) return;
+            for (int i = 0; i < instance.db.data.Count; i++)
+            {
+                StatisticData stat = instance.db.data[i];
+                if(stat.persistent == false) continue;
+                switch (stat.category)
+                {
+                    case StatisticType.time:
+                        PlayerPrefs.SetFloat(stat.title, stat.GetTime());
+                        break;
+                    case StatisticType.integer:
+                        PlayerPrefs.SetInt(stat.title, stat.GetInteger());
+                        break;
+                    case StatisticType.text:
+                        PlayerPrefs.SetString(stat.title, stat.GetText());
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+
+        public void SetStatisticInt(string statName, int newValue)
+        {
+            StatisticData statisticData = GetData(statName);
+            if(statisticData == null) return;
+            if(statisticData.category != StatisticType.integer) return;
+            statisticData.SetInteger(newValue);
+        }
+
+        public void SetStatisticFloat(string statName, float newValue)
+        {
+            StatisticData statisticData = GetData(statName);
+            if(statisticData == null) return;
+            if(statisticData.category != StatisticType.time) return;
+            statisticData.SetTime(newValue);
+        }
+
+        public void SetStatisticString(string statName, string newValue)
+        {
+            StatisticData statisticData = GetData(statName);
+            if(statisticData == null) return;
+            if(statisticData.category != StatisticType.text) return;
+            statisticData.SetText(newValue);
+        }
+    }
+}

+ 11 - 0
Runtime/Statistics.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8a8d253b00a34644980604012c30900d
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 50 - 0
Runtime/StatisticsConsoleCommands.cs

@@ -0,0 +1,50 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using UnityEngine;
+using QFSW.QC;
+using QFSW.QC.Utilities;
+using KairoEngine.Core;
+
+namespace KairoEngine.Statistics
+{
+    public static class StatisticsConsoleCommands
+    {
+        private static readonly Pool<StringBuilder> _builderPool = new Pool<StringBuilder>();
+
+        [Command("statistics-list", "List of statistics names")]
+        private static string PrintStatistics()
+        {
+            QuantumConsole console = QuantumConsole.Instance;
+            string result = "";
+            StringBuilder buffer = _builderPool.GetObject();
+            Color color = Color.white;
+            buffer.Clear();
+            if(console != null)
+            {
+                QuantumTheme theme = console.GetTheme();
+                color = theme ? theme.SuccessColor : Color.white;
+            }
+            foreach (var stat in Statistics.instance.db.data)
+            {
+                result += stat.title;
+                switch (stat.category)
+                {
+                    case StatisticType.integer:
+                    result += " - " + ColorExtensions.ColorText(stat.GetInteger().ToString(), color);
+                    break;
+                    case StatisticType.time:
+                    result += " - " + ColorExtensions.ColorText(KairoEngine.Core.Utilities.TimeToString(stat.GetTime()), color);
+                    break;
+                    default:
+                    break;
+                }
+                buffer.AppendLine(result);
+                result = "";
+            }
+            result = buffer.ToString();
+            _builderPool.Release(buffer);
+            return result;
+        }
+    }
+}

+ 11 - 0
Runtime/StatisticsConsoleCommands.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 00fb781460b49ed49bf1cd22d5794f94
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 14 - 0
Runtime/StatisticsLibrary.cs

@@ -0,0 +1,14 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using Sirenix.OdinInspector;
+
+namespace KairoEngine.Statistics
+{
+    [CreateAssetMenu(fileName = "StatisticsLibrary", menuName = "KairoEngine/Statistics/Library"), HideMonoScript]
+    public class StatisticsLibrary : ScriptableObject
+    {
+        [ListDrawerSettings(ShowPaging = false)]
+        public List<StatisticData> data = new List<StatisticData>();
+    }
+}

+ 11 - 0
Runtime/StatisticsLibrary.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 48fb955243a877d4ea4cbe3debd8bcb1
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 66 - 0
Runtime/StatisticsModule.cs

@@ -0,0 +1,66 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using KairoEngine.Core;
+using KairoEngine.Core.ModuleSystem;
+using Sirenix.OdinInspector;
+
+namespace KairoEngine.Statistics
+{
+    [Serializable, HideReferenceObjectPicker]
+    public class StatisticsModule : GameModuleBase
+    {
+        public override string name => "Statistics Module";
+        [NonSerialized, ShowInInspector, InlineEditor(InlineEditorObjectFieldModes.Boxed)] public StatisticsLibrary database;
+        public StatisticsModule(GameConfig config) : base(config)
+        {
+            this.gameConfig = config;
+            this.className = this.GetType().AssemblyQualifiedName;
+            this.typeName = "StatisticsModule";
+        }
+
+        public override void Load(Transform parent)
+        {
+            if(database == null)
+            {
+                Debug.LogError("Missing statistics database.\nPlease configure the statistics module in the Game config file.");
+                return;
+            }
+            var obj = new GameObject();
+            obj.transform.parent = parent;
+            obj.name = "Statistics";
+            var comp = obj.AddComponent<Statistics>();
+            comp.db = database;
+        }
+
+        public override void Reset()
+        {
+            
+        }
+
+        public override void Destroy() { }
+
+        public static StatisticsModule JSONToStatisticsModule(string data)
+        {
+            try
+            {
+                return JsonUtility.FromJson<StatisticsModule>(data);
+            }
+            catch (System.Exception e)
+            {
+                Debug.LogError($"Could not deserialize StatisticsModule: \n{e}");
+                return new StatisticsModule(null);
+            }
+        }
+
+        public override void OnBeforeSerialize(ObjectSerializer serializer) 
+        {
+            if(database != null) serializer.AddScriptableObject("Statistics_Database", database);
+        }
+        public override void OnBeforeDeserialize(ObjectSerializer serializer)
+        { 
+            database = (StatisticsLibrary)serializer.GetScriptableObject("Statistics_Database");
+        }
+    }
+}

+ 11 - 0
Runtime/StatisticsModule.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a3fea9601b9d8e8419adff3354bb0180
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 19 - 0
package.json

@@ -0,0 +1,19 @@
+{
+    "name": "at.kairoscope.kairoengine.statistics",
+    "displayName" : "KairoEngine Statistics",
+    "version": "0.2.0",
+    "unity": "2020.3",
+    "description": "Statistics database library for kairoEngine",
+    "repository": {
+      "type": "git",
+      "url": "https://git.kairoscope.net/kairoengine/statistics.git"
+    },
+    "author": "Kairoscope",
+    "dependencies": {
+      "at.kairoscope.kairoengine.core":"0.2.0",
+      "at.kairoscope.kairoengine.utilities":"0.2.0",
+      "at.kairoscope.thirdparty.sirenix":"1.0.2",
+      "at.kairoscope.thirdparty.qfsw":"1.0.0"
+    }
+  }
+  

+ 7 - 0
package.json.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 6eccd2ec911412c47b6f00d0e9360c34
+TextScriptImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: