From 7c70617806d5a670ec1d910981e089bfa20b0354 Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期三, 23 四月 2025 19:09:15 +0800
Subject: [PATCH] lit json ui框架 常用utility搬运

---
 Utility/TBlackBoard.cs.meta                       |   12 
 Main/Common/LitJson/IJsonWrapper.cs               |   60 
 Utility/GenerateUICode.cs                         |  294 +
 Utility/UGUIEventListenerContainDrag.cs           |   72 
 Utility/SnxxzUtility.cs                           |   24 
 Main/Common/LitJson/JsonException.cs.meta         |   11 
 Main/Common/LitJson/JsonData.cs                   | 1059 +++++
 Main/Extensions.meta                              |    8 
 Utility/Datumline.cs.meta                         |   12 
 Main/Common/LitJson/JsonReader.cs.meta            |   11 
 Utility/CameraManager.cs                          |   30 
 Utility/VectorUtility.cs                          |   74 
 Main/Common.meta                                  |    8 
 Main/VersionCheck.cs                              |   48 
 Main/Main.asmdef.meta                             |    7 
 Utility.meta                                      |    8 
 Utility/Extension.cs                              |    4 
 Utility/GameObjectPool.cs.meta                    |   12 
 Utility/ProfilerPanel.cs.meta                     |   12 
 Main/Common/LitJson/JsonWriter.cs.meta            |   11 
 Utility/SnxxzUtility.cs.meta                      |   12 
 Main/Common/LitJson/JsonMockWrapper.cs.meta       |   11 
 Utility/LayerUtility.cs.meta                      |   12 
 Main/Common/LitJson/JsonReader.cs                 |  478 ++
 Main/VersionCheck.cs.meta                         |   11 
 Utility/GlobalTimeEvent.cs                        |  190 
 Utility/GameObjectPool.cs                         |   99 
 Utility/GenerateUICode.cs.meta                    |   12 
 Utility/VesselExtension.cs.meta                   |   12 
 Main.meta                                         |    8 
 Utility/Datumline.cs                              |  167 
 Utility/LocalSave.cs                              |  225 +
 Utility/TransformExtension.cs                     |  197 +
 Utility/ColorUtility.cs.meta                      |   12 
 Utility/EnumHelper.cs                             | 1922 +++++++++
 Main/Common/LitJson/JsonMapper.cs.meta            |   11 
 Utility/EnumHelper.cs.meta                        |   12 
 Main/Common/LitJson/Netstandard15Polyfill.cs      |   24 
 Utility/FileExtersion.cs.meta                     |   12 
 Utility/ResolutionUtility.cs                      |   64 
 Utility/RenderOrder.cs                            |   23 
 Utility/TransformExtension.cs.meta                |   12 
 Utility/DrawUtility.cs                            |   62 
 Utility/LayerUtility.cs                           |   85 
 Utility/FPS.cs.meta                               |   12 
 Utility/UIParamCopyTool.cs.meta                   |   12 
 Main/UI.meta                                      |    8 
 Main/Common/LitJson/ParserToken.cs                |   44 
 Utility/CameraManager.cs.meta                     |   12 
 Utility/DeviceUtility.cs                          |  169 
 Utility/UIParamCopyTool.cs                        |  258 +
 Utility/SystemCMD.cs                              |   36 
 Utility/Extension.cs.meta                         |   11 
 Main/Common/LitJson/Lexer.cs                      |  912 ++++
 Utility/EnumLabelAttribute.cs                     |   47 
 Main/Common/LitJson/Netstandard15Polyfill.cs.meta |   11 
 Utility/LocalSave.cs.meta                         |   12 
 Utility/ResolutionUtility.cs.meta                 |   12 
 Utility/FieldPrint.cs                             |  100 
 Utility/BezierMove.cs                             |   45 
 Utility/PathUtility.cs                            |   21 
 Main/Common/LitJson/ParserToken.cs.meta           |   11 
 Utility/PathUtility.cs.meta                       |   12 
 Utility/EffectRenderSort.cs.meta                  |   12 
 Utility/GlobalTimeEvent.cs.meta                   |   12 
 Main/UI/UIBase.cs                                 |  590 ++
 Utility/ComponentExtersion.cs.meta                |   12 
 Utility/ColorUtility.cs                           |   31 
 Utility/EffectRenderSort.cs                       |   21 
 Utility/BezierMove.cs.meta                        |   12 
 Utility/StringUtility.cs.meta                     |   12 
 Main/Extensions/DOTweenExtensions.cs              |   45 
 Main/UI/UIManager.cs.meta                         |   11 
 Utility/ComponentExtersion.cs                     |  234 +
 Main/Common/LitJson/IJsonWrapper.cs.meta          |   11 
 Main/Common/LitJson/JsonMockWrapper.cs            |  105 
 Utility/VectorUtility.cs.meta                     |   12 
 Main/Common/LitJson/JsonData.cs.meta              |   11 
 Main/Common/LitJson.meta                          |    8 
 Utility/Bezier.cs.meta                            |   12 
 Utility/ProfilerPanel.cs                          |   75 
 Utility/Bezier.cs                                 |   39 
 Main/UI/UIBase.cs.meta                            |   11 
 Utility/RenderOrder.cs.meta                       |   12 
 Utility/TBlackBoard.cs                            |   47 
 Utility/MathUtility.cs.meta                       |   12 
 Main/Common/LitJson/JsonWriter.cs                 |  484 ++
 Main/UI/UIManager.cs                              |  586 ++
 Utility/FieldPrint.cs.meta                        |   12 
 Main/Common/LitJson/JsonMapper.cs                 |  995 +++++
 Utility/SystemCMD.cs.meta                         |   12 
 Main/Main.cs                                      |   80 
 Utility/DrawUtility.cs.meta                       |   12 
 Utility/DeviceUtility.cs.meta                     |   12 
 Utility/FileExtersion.cs                          |  207 +
 Utility/MathUtils.cs                              |  222 +
 Main/Main.asmdef                                  |   18 
 Utility/FPS.cs                                    |   39 
 Utility/RenderTextureCreator.cs                   |   56 
 Utility/UGUIEventListenerContainDrag.cs.meta      |   11 
 Utility/TAny.cs                                   |   13 
 Utility/RenderTextureCreator.cs.meta              |   12 
 Utility/VesselExtension.cs                        |  105 
 Main/Main.cs.meta                                 |   11 
 Main/Common/LitJson/Lexer.cs.meta                 |   11 
 Utility/MathUtility.cs                            |  222 +
 Main/Common/LitJson/JsonException.cs              |   65 
 Utility/EnumLabelAttribute.cs.meta                |   12 
 Utility/StringUtility.cs                          |   46 
 Main/Extensions/DOTweenExtensions.cs.meta         |   11 
 Utility/TAny.cs.meta                              |   12 
 Utility/MathUtils.cs.meta                         |   12 
 112 files changed, 11,820 insertions(+), 0 deletions(-)

diff --git a/Main.meta b/Main.meta
new file mode 100644
index 0000000..5346083
--- /dev/null
+++ b/Main.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ece9a9e81ad2b614e90a79034558cb27
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Common.meta b/Main/Common.meta
new file mode 100644
index 0000000..742473e
--- /dev/null
+++ b/Main/Common.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 803e80f2a28981f40bcd15dcf80a532e
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Common/LitJson.meta b/Main/Common/LitJson.meta
new file mode 100644
index 0000000..8aa4caa
--- /dev/null
+++ b/Main/Common/LitJson.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 6b7dc6b26b92f9c4193d59105f975880
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Common/LitJson/IJsonWrapper.cs b/Main/Common/LitJson/IJsonWrapper.cs
new file mode 100644
index 0000000..9b7e2d1
--- /dev/null
+++ b/Main/Common/LitJson/IJsonWrapper.cs
@@ -0,0 +1,60 @@
+#region Header
+/**
+ * IJsonWrapper.cs
+ *   Interface that represents a type capable of handling all kinds of JSON
+ *   data. This is mainly used when mapping objects through JsonMapper, and
+ *   it's implemented by JsonData.
+ *
+ * The authors disclaim copyright to this source code. For more details, see
+ * the COPYING file included with this distribution.
+ **/
+#endregion
+
+
+using System.Collections;
+using System.Collections.Specialized;
+
+
+namespace LitJson
+{
+    public enum JsonType
+    {
+        None,
+
+        Object,
+        Array,
+        String,
+        Int,
+        Long,
+        Double,
+        Boolean
+    }
+
+    public interface IJsonWrapper : IList, IOrderedDictionary
+    {
+        bool IsArray   { get; }
+        bool IsBoolean { get; }
+        bool IsDouble  { get; }
+        bool IsInt     { get; }
+        bool IsLong    { get; }
+        bool IsObject  { get; }
+        bool IsString  { get; }
+
+        bool     GetBoolean ();
+        double   GetDouble ();
+        int      GetInt ();
+        JsonType GetJsonType ();
+        long     GetLong ();
+        string   GetString ();
+
+        void SetBoolean  (bool val);
+        void SetDouble   (double val);
+        void SetInt      (int val);
+        void SetJsonType (JsonType type);
+        void SetLong     (long val);
+        void SetString   (string val);
+
+        string ToJson ();
+        void   ToJson (JsonWriter writer);
+    }
+}
diff --git a/Main/Common/LitJson/IJsonWrapper.cs.meta b/Main/Common/LitJson/IJsonWrapper.cs.meta
new file mode 100644
index 0000000..6d04e58
--- /dev/null
+++ b/Main/Common/LitJson/IJsonWrapper.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 271dce3dff1f78a4bab7ed5e77053b46
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Common/LitJson/JsonData.cs b/Main/Common/LitJson/JsonData.cs
new file mode 100644
index 0000000..e89e4b1
--- /dev/null
+++ b/Main/Common/LitJson/JsonData.cs
@@ -0,0 +1,1059 @@
+#region Header
+/**
+ * JsonData.cs
+ *   Generic type to hold JSON data (objects, arrays, and so on). This is
+ *   the default type returned by JsonMapper.ToObject().
+ *
+ * The authors disclaim copyright to this source code. For more details, see
+ * the COPYING file included with this distribution.
+ **/
+#endregion
+
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.IO;
+
+
+namespace LitJson
+{
+    public class JsonData : IJsonWrapper, IEquatable<JsonData>
+    {
+        #region Fields
+        private IList<JsonData>               inst_array;
+        private bool                          inst_boolean;
+        private double                        inst_double;
+        private int                           inst_int;
+        private long                          inst_long;
+        private IDictionary<string, JsonData> inst_object;
+        private string                        inst_string;
+        private string                        json;
+        private JsonType                      type;
+
+        // Used to implement the IOrderedDictionary interface
+        private IList<KeyValuePair<string, JsonData>> object_list;
+        #endregion
+
+
+        #region Properties
+        public int Count {
+            get { return EnsureCollection ().Count; }
+        }
+
+        public bool IsArray {
+            get { return type == JsonType.Array; }
+        }
+
+        public bool IsBoolean {
+            get { return type == JsonType.Boolean; }
+        }
+
+        public bool IsDouble {
+            get { return type == JsonType.Double; }
+        }
+
+        public bool IsInt {
+            get { return type == JsonType.Int; }
+        }
+
+        public bool IsLong {
+            get { return type == JsonType.Long; }
+        }
+
+        public bool IsObject {
+            get { return type == JsonType.Object; }
+        }
+
+        public bool IsString {
+            get { return type == JsonType.String; }
+        }
+
+        public ICollection<string> Keys {
+            get { EnsureDictionary (); return inst_object.Keys; }
+        }
+        
+        /// <summary>
+        /// Determines whether the json contains an element that has the specified key.
+        /// </summary>
+        /// <param name="key">The key to locate in the json.</param>
+        /// <returns>true if the json contains an element that has the specified key; otherwise, false.</returns>
+        public Boolean ContainsKey(String key) {
+            EnsureDictionary();
+            return this.inst_object.Keys.Contains(key);
+        }
+        #endregion
+
+
+        #region ICollection Properties
+        int ICollection.Count {
+            get {
+                return Count;
+            }
+        }
+
+        bool ICollection.IsSynchronized {
+            get {
+                return EnsureCollection ().IsSynchronized;
+            }
+        }
+
+        object ICollection.SyncRoot {
+            get {
+                return EnsureCollection ().SyncRoot;
+            }
+        }
+        #endregion
+
+
+        #region IDictionary Properties
+        bool IDictionary.IsFixedSize {
+            get {
+                return EnsureDictionary ().IsFixedSize;
+            }
+        }
+
+        bool IDictionary.IsReadOnly {
+            get {
+                return EnsureDictionary ().IsReadOnly;
+            }
+        }
+
+        ICollection IDictionary.Keys {
+            get {
+                EnsureDictionary ();
+                IList<string> keys = new List<string> ();
+
+                foreach (KeyValuePair<string, JsonData> entry in
+                         object_list) {
+                    keys.Add (entry.Key);
+                }
+
+                return (ICollection) keys;
+            }
+        }
+
+        ICollection IDictionary.Values {
+            get {
+                EnsureDictionary ();
+                IList<JsonData> values = new List<JsonData> ();
+
+                foreach (KeyValuePair<string, JsonData> entry in
+                         object_list) {
+                    values.Add (entry.Value);
+                }
+
+                return (ICollection) values;
+            }
+        }
+        #endregion
+
+
+
+        #region IJsonWrapper Properties
+        bool IJsonWrapper.IsArray {
+            get { return IsArray; }
+        }
+
+        bool IJsonWrapper.IsBoolean {
+            get { return IsBoolean; }
+        }
+
+        bool IJsonWrapper.IsDouble {
+            get { return IsDouble; }
+        }
+
+        bool IJsonWrapper.IsInt {
+            get { return IsInt; }
+        }
+
+        bool IJsonWrapper.IsLong {
+            get { return IsLong; }
+        }
+
+        bool IJsonWrapper.IsObject {
+            get { return IsObject; }
+        }
+
+        bool IJsonWrapper.IsString {
+            get { return IsString; }
+        }
+        #endregion
+
+
+        #region IList Properties
+        bool IList.IsFixedSize {
+            get {
+                return EnsureList ().IsFixedSize;
+            }
+        }
+
+        bool IList.IsReadOnly {
+            get {
+                return EnsureList ().IsReadOnly;
+            }
+        }
+        #endregion
+
+
+        #region IDictionary Indexer
+        object IDictionary.this[object key] {
+            get {
+                return EnsureDictionary ()[key];
+            }
+
+            set {
+                if (! (key is String))
+                    throw new ArgumentException (
+                        "The key has to be a string");
+
+                JsonData data = ToJsonData (value);
+
+                this[(string) key] = data;
+            }
+        }
+        #endregion
+
+
+        #region IOrderedDictionary Indexer
+        object IOrderedDictionary.this[int idx] {
+            get {
+                EnsureDictionary ();
+                return object_list[idx].Value;
+            }
+
+            set {
+                EnsureDictionary ();
+                JsonData data = ToJsonData (value);
+
+                KeyValuePair<string, JsonData> old_entry = object_list[idx];
+
+                inst_object[old_entry.Key] = data;
+
+                KeyValuePair<string, JsonData> entry =
+                    new KeyValuePair<string, JsonData> (old_entry.Key, data);
+
+                object_list[idx] = entry;
+            }
+        }
+        #endregion
+
+
+        #region IList Indexer
+        object IList.this[int index] {
+            get {
+                return EnsureList ()[index];
+            }
+
+            set {
+                EnsureList ();
+                JsonData data = ToJsonData (value);
+
+                this[index] = data;
+            }
+        }
+        #endregion
+
+
+        #region Public Indexers
+        public JsonData this[string prop_name] {
+            get {
+                EnsureDictionary ();
+                return inst_object[prop_name];
+            }
+
+            set {
+                EnsureDictionary ();
+
+                KeyValuePair<string, JsonData> entry =
+                    new KeyValuePair<string, JsonData> (prop_name, value);
+
+                if (inst_object.ContainsKey (prop_name)) {
+                    for (int i = 0; i < object_list.Count; i++) {
+                        if (object_list[i].Key == prop_name) {
+                            object_list[i] = entry;
+                            break;
+                        }
+                    }
+                } else
+                    object_list.Add (entry);
+
+                inst_object[prop_name] = value;
+
+                json = null;
+            }
+        }
+
+        public JsonData this[int index] {
+            get {
+                EnsureCollection ();
+
+                if (type == JsonType.Array)
+                    return inst_array[index];
+
+                return object_list[index].Value;
+            }
+
+            set {
+                EnsureCollection ();
+
+                if (type == JsonType.Array)
+                    inst_array[index] = value;
+                else {
+                    KeyValuePair<string, JsonData> entry = object_list[index];
+                    KeyValuePair<string, JsonData> new_entry =
+                        new KeyValuePair<string, JsonData> (entry.Key, value);
+
+                    object_list[index] = new_entry;
+                    inst_object[entry.Key] = value;
+                }
+
+                json = null;
+            }
+        }
+        #endregion
+
+
+        #region Constructors
+        public JsonData ()
+        {
+        }
+
+        public JsonData (bool boolean)
+        {
+            type = JsonType.Boolean;
+            inst_boolean = boolean;
+        }
+
+        public JsonData (double number)
+        {
+            type = JsonType.Double;
+            inst_double = number;
+        }
+
+        public JsonData (int number)
+        {
+            type = JsonType.Int;
+            inst_int = number;
+        }
+
+        public JsonData (long number)
+        {
+            type = JsonType.Long;
+            inst_long = number;
+        }
+
+        public JsonData (object obj)
+        {
+            if (obj is Boolean) {
+                type = JsonType.Boolean;
+                inst_boolean = (bool) obj;
+                return;
+            }
+
+            if (obj is Double) {
+                type = JsonType.Double;
+                inst_double = (double) obj;
+                return;
+            }
+
+            if (obj is Int32) {
+                type = JsonType.Int;
+                inst_int = (int) obj;
+                return;
+            }
+
+            if (obj is Int64) {
+                type = JsonType.Long;
+                inst_long = (long) obj;
+                return;
+            }
+
+            if (obj is String) {
+                type = JsonType.String;
+                inst_string = (string) obj;
+                return;
+            }
+
+            throw new ArgumentException (
+                "Unable to wrap the given object with JsonData");
+        }
+
+        public JsonData (string str)
+        {
+            type = JsonType.String;
+            inst_string = str;
+        }
+        #endregion
+
+
+        #region Implicit Conversions
+        public static implicit operator JsonData (Boolean data)
+        {
+            return new JsonData (data);
+        }
+
+        public static implicit operator JsonData (Double data)
+        {
+            return new JsonData (data);
+        }
+
+        public static implicit operator JsonData (Int32 data)
+        {
+            return new JsonData (data);
+        }
+
+        public static implicit operator JsonData (Int64 data)
+        {
+            return new JsonData (data);
+        }
+
+        public static implicit operator JsonData (String data)
+        {
+            return new JsonData (data);
+        }
+        #endregion
+
+
+        #region Explicit Conversions
+        public static explicit operator Boolean (JsonData data)
+        {
+            if (data.type != JsonType.Boolean)
+                throw new InvalidCastException (
+                    "Instance of JsonData doesn't hold a double");
+
+            return data.inst_boolean;
+        }
+
+        public static explicit operator Double (JsonData data)
+        {
+            if (data.type != JsonType.Double)
+                throw new InvalidCastException (
+                    "Instance of JsonData doesn't hold a double");
+
+            return data.inst_double;
+        }
+
+       public static explicit operator Int32(JsonData data)
+        {
+            if (data.type != JsonType.Int && data.type != JsonType.Long)
+            {
+                throw new InvalidCastException(
+                    "Instance of JsonData doesn't hold an int");
+            }
+
+            // cast may truncate data... but that's up to the user to consider
+            return data.type == JsonType.Int ? data.inst_int : (int)data.inst_long;
+        }
+
+        public static explicit operator Int64(JsonData data)
+        {
+            if (data.type != JsonType.Long && data.type != JsonType.Int)
+            {
+                throw new InvalidCastException(
+                    "Instance of JsonData doesn't hold a long");
+            }
+
+            return data.type == JsonType.Long ? data.inst_long : data.inst_int;
+        }
+
+        public static explicit operator String (JsonData data)
+        {
+            if (data.type != JsonType.String)
+                throw new InvalidCastException (
+                    "Instance of JsonData doesn't hold a string");
+
+            return data.inst_string;
+        }
+        #endregion
+
+
+        #region ICollection Methods
+        void ICollection.CopyTo (Array array, int index)
+        {
+            EnsureCollection ().CopyTo (array, index);
+        }
+        #endregion
+
+
+        #region IDictionary Methods
+        void IDictionary.Add (object key, object value)
+        {
+            JsonData data = ToJsonData (value);
+
+            EnsureDictionary ().Add (key, data);
+
+            KeyValuePair<string, JsonData> entry =
+                new KeyValuePair<string, JsonData> ((string) key, data);
+            object_list.Add (entry);
+
+            json = null;
+        }
+
+        void IDictionary.Clear ()
+        {
+            EnsureDictionary ().Clear ();
+            object_list.Clear ();
+            json = null;
+        }
+
+        bool IDictionary.Contains (object key)
+        {
+            return EnsureDictionary ().Contains (key);
+        }
+
+        IDictionaryEnumerator IDictionary.GetEnumerator ()
+        {
+            return ((IOrderedDictionary) this).GetEnumerator ();
+        }
+
+        void IDictionary.Remove (object key)
+        {
+            EnsureDictionary ().Remove (key);
+
+            for (int i = 0; i < object_list.Count; i++) {
+                if (object_list[i].Key == (string) key) {
+                    object_list.RemoveAt (i);
+                    break;
+                }
+            }
+
+            json = null;
+        }
+        #endregion
+
+
+        #region IEnumerable Methods
+        IEnumerator IEnumerable.GetEnumerator ()
+        {
+            return EnsureCollection ().GetEnumerator ();
+        }
+        #endregion
+
+
+        #region IJsonWrapper Methods
+        bool IJsonWrapper.GetBoolean ()
+        {
+            if (type != JsonType.Boolean)
+                throw new InvalidOperationException (
+                    "JsonData instance doesn't hold a boolean");
+
+            return inst_boolean;
+        }
+
+        double IJsonWrapper.GetDouble ()
+        {
+            if (type != JsonType.Double)
+                throw new InvalidOperationException (
+                    "JsonData instance doesn't hold a double");
+
+            return inst_double;
+        }
+
+        int IJsonWrapper.GetInt ()
+        {
+            if (type != JsonType.Int)
+                throw new InvalidOperationException (
+                    "JsonData instance doesn't hold an int");
+
+            return inst_int;
+        }
+
+        long IJsonWrapper.GetLong ()
+        {
+            if (type != JsonType.Long)
+                throw new InvalidOperationException (
+                    "JsonData instance doesn't hold a long");
+
+            return inst_long;
+        }
+
+        string IJsonWrapper.GetString ()
+        {
+            if (type != JsonType.String)
+                throw new InvalidOperationException (
+                    "JsonData instance doesn't hold a string");
+
+            return inst_string;
+        }
+
+        void IJsonWrapper.SetBoolean (bool val)
+        {
+            type = JsonType.Boolean;
+            inst_boolean = val;
+            json = null;
+        }
+
+        void IJsonWrapper.SetDouble (double val)
+        {
+            type = JsonType.Double;
+            inst_double = val;
+            json = null;
+        }
+
+        void IJsonWrapper.SetInt (int val)
+        {
+            type = JsonType.Int;
+            inst_int = val;
+            json = null;
+        }
+
+        void IJsonWrapper.SetLong (long val)
+        {
+            type = JsonType.Long;
+            inst_long = val;
+            json = null;
+        }
+
+        void IJsonWrapper.SetString (string val)
+        {
+            type = JsonType.String;
+            inst_string = val;
+            json = null;
+        }
+
+        string IJsonWrapper.ToJson ()
+        {
+            return ToJson ();
+        }
+
+        void IJsonWrapper.ToJson (JsonWriter writer)
+        {
+            ToJson (writer);
+        }
+        #endregion
+
+
+        #region IList Methods
+        int IList.Add (object value)
+        {
+            return Add (value);
+        }
+
+        void IList.Clear ()
+        {
+            EnsureList ().Clear ();
+            json = null;
+        }
+
+        bool IList.Contains (object value)
+        {
+            return EnsureList ().Contains (value);
+        }
+
+        int IList.IndexOf (object value)
+        {
+            return EnsureList ().IndexOf (value);
+        }
+
+        void IList.Insert (int index, object value)
+        {
+            EnsureList ().Insert (index, value);
+            json = null;
+        }
+
+        void IList.Remove (object value)
+        {
+            EnsureList ().Remove (value);
+            json = null;
+        }
+
+        void IList.RemoveAt (int index)
+        {
+            EnsureList ().RemoveAt (index);
+            json = null;
+        }
+        #endregion
+
+
+        #region IOrderedDictionary Methods
+        IDictionaryEnumerator IOrderedDictionary.GetEnumerator ()
+        {
+            EnsureDictionary ();
+
+            return new OrderedDictionaryEnumerator (
+                object_list.GetEnumerator ());
+        }
+
+        void IOrderedDictionary.Insert (int idx, object key, object value)
+        {
+            string property = (string) key;
+            JsonData data  = ToJsonData (value);
+
+            this[property] = data;
+
+            KeyValuePair<string, JsonData> entry =
+                new KeyValuePair<string, JsonData> (property, data);
+
+            object_list.Insert (idx, entry);
+        }
+
+        void IOrderedDictionary.RemoveAt (int idx)
+        {
+            EnsureDictionary ();
+
+            inst_object.Remove (object_list[idx].Key);
+            object_list.RemoveAt (idx);
+        }
+        #endregion
+
+
+        #region Private Methods
+        private ICollection EnsureCollection ()
+        {
+            if (type == JsonType.Array)
+                return (ICollection) inst_array;
+
+            if (type == JsonType.Object)
+                return (ICollection) inst_object;
+
+            throw new InvalidOperationException (
+                "The JsonData instance has to be initialized first");
+        }
+
+        private IDictionary EnsureDictionary ()
+        {
+            if (type == JsonType.Object)
+                return (IDictionary) inst_object;
+
+            if (type != JsonType.None)
+                throw new InvalidOperationException (
+                    "Instance of JsonData is not a dictionary");
+
+            type = JsonType.Object;
+            inst_object = new Dictionary<string, JsonData> ();
+            object_list = new List<KeyValuePair<string, JsonData>> ();
+
+            return (IDictionary) inst_object;
+        }
+
+        private IList EnsureList ()
+        {
+            if (type == JsonType.Array)
+                return (IList) inst_array;
+
+            if (type != JsonType.None)
+                throw new InvalidOperationException (
+                    "Instance of JsonData is not a list");
+
+            type = JsonType.Array;
+            inst_array = new List<JsonData> ();
+
+            return (IList) inst_array;
+        }
+
+        private JsonData ToJsonData (object obj)
+        {
+            if (obj == null)
+                return null;
+
+            if (obj is JsonData)
+                return (JsonData) obj;
+
+            return new JsonData (obj);
+        }
+
+        private static void WriteJson (IJsonWrapper obj, JsonWriter writer)
+        {
+            if (obj == null) {
+                writer.Write (null);
+                return;
+            }
+
+            if (obj.IsString) {
+                writer.Write (obj.GetString ());
+                return;
+            }
+
+            if (obj.IsBoolean) {
+                writer.Write (obj.GetBoolean ());
+                return;
+            }
+
+            if (obj.IsDouble) {
+                writer.Write (obj.GetDouble ());
+                return;
+            }
+
+            if (obj.IsInt) {
+                writer.Write (obj.GetInt ());
+                return;
+            }
+
+            if (obj.IsLong) {
+                writer.Write (obj.GetLong ());
+                return;
+            }
+
+            if (obj.IsArray) {
+                writer.WriteArrayStart ();
+                foreach (object elem in (IList) obj)
+                    WriteJson ((JsonData) elem, writer);
+                writer.WriteArrayEnd ();
+
+                return;
+            }
+
+            if (obj.IsObject) {
+                writer.WriteObjectStart ();
+
+                foreach (DictionaryEntry entry in ((IDictionary) obj)) {
+                    writer.WritePropertyName ((string) entry.Key);
+                    WriteJson ((JsonData) entry.Value, writer);
+                }
+                writer.WriteObjectEnd ();
+
+                return;
+            }
+        }
+        #endregion
+
+
+        public int Add (object value)
+        {
+            JsonData data = ToJsonData (value);
+
+            json = null;
+
+            return EnsureList ().Add (data);
+        }
+
+        public bool Remove(object obj)
+        {
+            json = null;
+            if(IsObject)
+            {
+                JsonData value = null;
+                if (inst_object.TryGetValue((string)obj, out value))
+                    return inst_object.Remove((string)obj) && object_list.Remove(new KeyValuePair<string, JsonData>((string)obj, value));
+                else
+                    throw new KeyNotFoundException("The specified key was not found in the JsonData object.");
+            }
+            if(IsArray)
+            {
+                return inst_array.Remove(ToJsonData(obj));
+            }
+            throw new InvalidOperationException (
+                    "Instance of JsonData is not an object or a list.");
+        }
+
+        public void Clear ()
+        {
+            if (IsObject) {
+                ((IDictionary) this).Clear ();
+                return;
+            }
+
+            if (IsArray) {
+                ((IList) this).Clear ();
+                return;
+            }
+        }
+
+        public bool Equals (JsonData x)
+        {
+            if (x == null)
+                return false;
+
+            if (x.type != this.type)
+            {
+                // further check to see if this is a long to int comparison
+                if ((x.type != JsonType.Int && x.type != JsonType.Long)
+                    || (this.type != JsonType.Int && this.type != JsonType.Long))
+                {
+                    return false;
+                }
+            }
+
+            switch (this.type) {
+            case JsonType.None:
+                return true;
+
+            case JsonType.Object:
+                return this.inst_object.Equals (x.inst_object);
+
+            case JsonType.Array:
+                return this.inst_array.Equals (x.inst_array);
+
+            case JsonType.String:
+                return this.inst_string.Equals (x.inst_string);
+
+            case JsonType.Int:
+            {
+                if (x.IsLong)
+                {
+                    if (x.inst_long < Int32.MinValue || x.inst_long > Int32.MaxValue)
+                        return false;
+                    return this.inst_int.Equals((int)x.inst_long);
+                }
+                return this.inst_int.Equals(x.inst_int);
+            }
+
+            case JsonType.Long:
+            {
+                if (x.IsInt)
+                {
+                    if (this.inst_long < Int32.MinValue || this.inst_long > Int32.MaxValue)
+                        return false;
+                    return x.inst_int.Equals((int)this.inst_long);
+                }
+                return this.inst_long.Equals(x.inst_long);
+            }
+
+            case JsonType.Double:
+                return this.inst_double.Equals (x.inst_double);
+
+            case JsonType.Boolean:
+                return this.inst_boolean.Equals (x.inst_boolean);
+            }
+
+            return false;
+        }
+
+        public JsonType GetJsonType ()
+        {
+            return type;
+        }
+
+        public void SetJsonType (JsonType type)
+        {
+            if (this.type == type)
+                return;
+
+            switch (type) {
+            case JsonType.None:
+                break;
+
+            case JsonType.Object:
+                inst_object = new Dictionary<string, JsonData> ();
+                object_list = new List<KeyValuePair<string, JsonData>> ();
+                break;
+
+            case JsonType.Array:
+                inst_array = new List<JsonData> ();
+                break;
+
+            case JsonType.String:
+                inst_string = default (String);
+                break;
+
+            case JsonType.Int:
+                inst_int = default (Int32);
+                break;
+
+            case JsonType.Long:
+                inst_long = default (Int64);
+                break;
+
+            case JsonType.Double:
+                inst_double = default (Double);
+                break;
+
+            case JsonType.Boolean:
+                inst_boolean = default (Boolean);
+                break;
+            }
+
+            this.type = type;
+        }
+
+        public string ToJson ()
+        {
+            if (json != null)
+                return json;
+
+            StringWriter sw = new StringWriter ();
+            JsonWriter writer = new JsonWriter (sw);
+            writer.Validate = false;
+
+            WriteJson (this, writer);
+            json = sw.ToString ();
+
+            return json;
+        }
+
+        public void ToJson (JsonWriter writer)
+        {
+            bool old_validate = writer.Validate;
+
+            writer.Validate = false;
+
+            WriteJson (this, writer);
+
+            writer.Validate = old_validate;
+        }
+
+        public override string ToString ()
+        {
+            switch (type) {
+            case JsonType.Array:
+                return "JsonData array";
+
+            case JsonType.Boolean:
+                return inst_boolean.ToString ();
+
+            case JsonType.Double:
+                return inst_double.ToString ();
+
+            case JsonType.Int:
+                return inst_int.ToString ();
+
+            case JsonType.Long:
+                return inst_long.ToString ();
+
+            case JsonType.Object:
+                return "JsonData object";
+
+            case JsonType.String:
+                return inst_string;
+            }
+
+            return "Uninitialized JsonData";
+        }
+    }
+
+
+    internal class OrderedDictionaryEnumerator : IDictionaryEnumerator
+    {
+        IEnumerator<KeyValuePair<string, JsonData>> list_enumerator;
+
+
+        public object Current {
+            get { return Entry; }
+        }
+
+        public DictionaryEntry Entry {
+            get {
+                KeyValuePair<string, JsonData> curr = list_enumerator.Current;
+                return new DictionaryEntry (curr.Key, curr.Value);
+            }
+        }
+
+        public object Key {
+            get { return list_enumerator.Current.Key; }
+        }
+
+        public object Value {
+            get { return list_enumerator.Current.Value; }
+        }
+
+
+        public OrderedDictionaryEnumerator (
+            IEnumerator<KeyValuePair<string, JsonData>> enumerator)
+        {
+            list_enumerator = enumerator;
+        }
+
+
+        public bool MoveNext ()
+        {
+            return list_enumerator.MoveNext ();
+        }
+
+        public void Reset ()
+        {
+            list_enumerator.Reset ();
+        }
+    }
+}
diff --git a/Main/Common/LitJson/JsonData.cs.meta b/Main/Common/LitJson/JsonData.cs.meta
new file mode 100644
index 0000000..b38cf07
--- /dev/null
+++ b/Main/Common/LitJson/JsonData.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f08013cb4e26ac44f8537d847609a788
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Common/LitJson/JsonException.cs b/Main/Common/LitJson/JsonException.cs
new file mode 100644
index 0000000..4efd890
--- /dev/null
+++ b/Main/Common/LitJson/JsonException.cs
@@ -0,0 +1,65 @@
+#region Header
+/**
+ * JsonException.cs
+ *   Base class throwed by LitJSON when a parsing error occurs.
+ *
+ * The authors disclaim copyright to this source code. For more details, see
+ * the COPYING file included with this distribution.
+ **/
+#endregion
+
+
+using System;
+
+
+namespace LitJson
+{
+    public class JsonException :
+#if NETSTANDARD1_5
+        Exception
+#else
+        ApplicationException
+#endif
+    {
+        public JsonException () : base ()
+        {
+        }
+
+        internal JsonException (ParserToken token) :
+            base (String.Format (
+                    "Invalid token '{0}' in input string", token))
+        {
+        }
+
+        internal JsonException (ParserToken token,
+                                Exception inner_exception) :
+            base (String.Format (
+                    "Invalid token '{0}' in input string", token),
+                inner_exception)
+        {
+        }
+
+        internal JsonException (int c) :
+            base (String.Format (
+                    "Invalid character '{0}' in input string", (char) c))
+        {
+        }
+
+        internal JsonException (int c, Exception inner_exception) :
+            base (String.Format (
+                    "Invalid character '{0}' in input string", (char) c),
+                inner_exception)
+        {
+        }
+
+
+        public JsonException (string message) : base (message)
+        {
+        }
+
+        public JsonException (string message, Exception inner_exception) :
+            base (message, inner_exception)
+        {
+        }
+    }
+}
diff --git a/Main/Common/LitJson/JsonException.cs.meta b/Main/Common/LitJson/JsonException.cs.meta
new file mode 100644
index 0000000..c3b9535
--- /dev/null
+++ b/Main/Common/LitJson/JsonException.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 98f4dafaa0fce514bb6878d7a0fa26e7
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Common/LitJson/JsonMapper.cs b/Main/Common/LitJson/JsonMapper.cs
new file mode 100644
index 0000000..fc10b28
--- /dev/null
+++ b/Main/Common/LitJson/JsonMapper.cs
@@ -0,0 +1,995 @@
+#region Header
+/**
+ * JsonMapper.cs
+ *   JSON to .Net object and object to JSON conversions.
+ *
+ * The authors disclaim copyright to this source code. For more details, see
+ * the COPYING file included with this distribution.
+ **/
+#endregion
+
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Reflection;
+
+
+namespace LitJson
+{
+    internal struct PropertyMetadata
+    {
+        public MemberInfo Info;
+        public bool       IsField;
+        public Type       Type;
+    }
+
+
+    internal struct ArrayMetadata
+    {
+        private Type element_type;
+        private bool is_array;
+        private bool is_list;
+
+
+        public Type ElementType {
+            get {
+                if (element_type == null)
+                    return typeof (JsonData);
+
+                return element_type;
+            }
+
+            set { element_type = value; }
+        }
+
+        public bool IsArray {
+            get { return is_array; }
+            set { is_array = value; }
+        }
+
+        public bool IsList {
+            get { return is_list; }
+            set { is_list = value; }
+        }
+    }
+
+
+    internal struct ObjectMetadata
+    {
+        private Type element_type;
+        private bool is_dictionary;
+
+        private IDictionary<string, PropertyMetadata> properties;
+
+
+        public Type ElementType {
+            get {
+                if (element_type == null)
+                    return typeof (JsonData);
+
+                return element_type;
+            }
+
+            set { element_type = value; }
+        }
+
+        public bool IsDictionary {
+            get { return is_dictionary; }
+            set { is_dictionary = value; }
+        }
+
+        public IDictionary<string, PropertyMetadata> Properties {
+            get { return properties; }
+            set { properties = value; }
+        }
+    }
+
+
+    internal delegate void ExporterFunc    (object obj, JsonWriter writer);
+    public   delegate void ExporterFunc<T> (T obj, JsonWriter writer);
+
+    internal delegate object ImporterFunc                (object input);
+    public   delegate TValue ImporterFunc<TJson, TValue> (TJson input);
+
+    public delegate IJsonWrapper WrapperFactory ();
+
+
+    public class JsonMapper
+    {
+        #region Fields
+        private static readonly int max_nesting_depth;
+
+        private static readonly IFormatProvider datetime_format;
+
+        private static readonly IDictionary<Type, ExporterFunc> base_exporters_table;
+        private static readonly IDictionary<Type, ExporterFunc> custom_exporters_table;
+        private static readonly object custom_exporters_table_lock = new Object();
+
+        private static readonly IDictionary<Type,
+                IDictionary<Type, ImporterFunc>> base_importers_table;
+        private static readonly IDictionary<Type,
+                IDictionary<Type, ImporterFunc>> custom_importers_table;
+        private static readonly object custom_importers_table_lock = new Object();
+
+        private static readonly IDictionary<Type, ArrayMetadata> array_metadata;
+        private static readonly object array_metadata_lock = new Object ();
+
+        private static readonly IDictionary<Type,
+                IDictionary<Type, MethodInfo>> conv_ops;
+        private static readonly object conv_ops_lock = new Object ();
+
+        private static readonly IDictionary<Type, ObjectMetadata> object_metadata;
+        private static readonly object object_metadata_lock = new Object ();
+
+        private static readonly IDictionary<Type,
+                IList<PropertyMetadata>> type_properties;
+        private static readonly object type_properties_lock = new Object ();
+
+        private static readonly JsonWriter      static_writer;
+        private static readonly object static_writer_lock = new Object ();
+        #endregion
+
+
+        #region Constructors
+        static JsonMapper ()
+        {
+            max_nesting_depth = 100;
+
+            array_metadata = new Dictionary<Type, ArrayMetadata> ();
+            conv_ops = new Dictionary<Type, IDictionary<Type, MethodInfo>> ();
+            object_metadata = new Dictionary<Type, ObjectMetadata> ();
+            type_properties = new Dictionary<Type,
+                            IList<PropertyMetadata>> ();
+
+            static_writer = new JsonWriter ();
+
+            datetime_format = DateTimeFormatInfo.InvariantInfo;
+
+            base_exporters_table   = new Dictionary<Type, ExporterFunc> ();
+            custom_exporters_table = new Dictionary<Type, ExporterFunc> ();
+
+            base_importers_table = new Dictionary<Type,
+                                 IDictionary<Type, ImporterFunc>> ();
+            custom_importers_table = new Dictionary<Type,
+                                   IDictionary<Type, ImporterFunc>> ();
+
+            RegisterBaseExporters ();
+            RegisterBaseImporters ();
+        }
+        #endregion
+
+
+        #region Private Methods
+        private static void AddArrayMetadata (Type type)
+        {
+            if (array_metadata.ContainsKey (type))
+                return;
+
+            ArrayMetadata data = new ArrayMetadata ();
+
+            data.IsArray = type.IsArray;
+
+            if (type.GetInterface ("System.Collections.IList") != null)
+                data.IsList = true;
+
+            foreach (PropertyInfo p_info in type.GetProperties ()) {
+                if (p_info.Name != "Item")
+                    continue;
+
+                ParameterInfo[] parameters = p_info.GetIndexParameters ();
+
+                if (parameters.Length != 1)
+                    continue;
+
+                if (parameters[0].ParameterType == typeof (int))
+                    data.ElementType = p_info.PropertyType;
+            }
+
+            lock (array_metadata_lock) {
+                try {
+                    array_metadata.Add (type, data);
+                } catch (ArgumentException) {
+                    return;
+                }
+            }
+        }
+
+        private static void AddObjectMetadata (Type type)
+        {
+            if (object_metadata.ContainsKey (type))
+                return;
+
+            ObjectMetadata data = new ObjectMetadata ();
+
+            if (type.GetInterface ("System.Collections.IDictionary") != null)
+                data.IsDictionary = true;
+
+            data.Properties = new Dictionary<string, PropertyMetadata> ();
+
+            foreach (PropertyInfo p_info in type.GetProperties ()) {
+                if (p_info.Name == "Item") {
+                    ParameterInfo[] parameters = p_info.GetIndexParameters ();
+
+                    if (parameters.Length != 1)
+                        continue;
+
+                    if (parameters[0].ParameterType == typeof (string))
+                        data.ElementType = p_info.PropertyType;
+
+                    continue;
+                }
+
+                PropertyMetadata p_data = new PropertyMetadata ();
+                p_data.Info = p_info;
+                p_data.Type = p_info.PropertyType;
+
+                data.Properties.Add (p_info.Name, p_data);
+            }
+
+            foreach (FieldInfo f_info in type.GetFields ()) {
+                PropertyMetadata p_data = new PropertyMetadata ();
+                p_data.Info = f_info;
+                p_data.IsField = true;
+                p_data.Type = f_info.FieldType;
+
+                data.Properties.Add (f_info.Name, p_data);
+            }
+
+            lock (object_metadata_lock) {
+                try {
+                    object_metadata.Add (type, data);
+                } catch (ArgumentException) {
+                    return;
+                }
+            }
+        }
+
+        private static void AddTypeProperties (Type type)
+        {
+            if (type_properties.ContainsKey (type))
+                return;
+
+            IList<PropertyMetadata> props = new List<PropertyMetadata> ();
+
+            foreach (PropertyInfo p_info in type.GetProperties ()) {
+                if (p_info.Name == "Item")
+                    continue;
+
+                PropertyMetadata p_data = new PropertyMetadata ();
+                p_data.Info = p_info;
+                p_data.IsField = false;
+                props.Add (p_data);
+            }
+
+            foreach (FieldInfo f_info in type.GetFields ()) {
+                PropertyMetadata p_data = new PropertyMetadata ();
+                p_data.Info = f_info;
+                p_data.IsField = true;
+
+                props.Add (p_data);
+            }
+
+            lock (type_properties_lock) {
+                try {
+                    type_properties.Add (type, props);
+                } catch (ArgumentException) {
+                    return;
+                }
+            }
+        }
+
+        private static MethodInfo GetConvOp (Type t1, Type t2)
+        {
+            lock (conv_ops_lock) {
+                if (! conv_ops.ContainsKey (t1))
+                    conv_ops.Add (t1, new Dictionary<Type, MethodInfo> ());
+            }
+
+            if (conv_ops[t1].ContainsKey (t2))
+                return conv_ops[t1][t2];
+
+            MethodInfo op = t1.GetMethod (
+                "op_Implicit", new Type[] { t2 });
+
+            lock (conv_ops_lock) {
+                try {
+                    conv_ops[t1].Add (t2, op);
+                } catch (ArgumentException) {
+                    return conv_ops[t1][t2];
+                }
+            }
+
+            return op;
+        }
+
+        private static object ReadValue (Type inst_type, JsonReader reader)
+        {
+            reader.Read ();
+
+            if (reader.Token == JsonToken.ArrayEnd)
+                return null;
+
+            Type underlying_type = Nullable.GetUnderlyingType(inst_type);
+            Type value_type = underlying_type ?? inst_type;
+
+            if (reader.Token == JsonToken.Null) {
+                #if NETSTANDARD1_5
+                if (inst_type.IsClass() || underlying_type != null) {
+                    return null;
+                }
+                #else
+                if (inst_type.IsClass || underlying_type != null) {
+                    return null;
+                }
+                #endif
+
+                throw new JsonException (String.Format (
+                            "Can't assign null to an instance of type {0}",
+                            inst_type));
+            }
+
+            if (reader.Token == JsonToken.Double ||
+                reader.Token == JsonToken.Int ||
+                reader.Token == JsonToken.Long ||
+                reader.Token == JsonToken.String ||
+                reader.Token == JsonToken.Boolean) {
+
+                Type json_type = reader.Value.GetType ();
+
+                if (value_type.IsAssignableFrom (json_type))
+                    return reader.Value;
+
+                // If there's a custom importer that fits, use it
+                lock (custom_importers_table_lock) {
+                    if (custom_importers_table.TryGetValue(json_type, out IDictionary<Type, ImporterFunc> customImporterTablesValue) &&
+                        customImporterTablesValue.TryGetValue(value_type, out ImporterFunc customImporter)) {
+
+                        return customImporter(reader.Value);
+                    }
+                }
+
+                // Maybe there's a base importer that works
+                if (base_importers_table.TryGetValue(json_type, out IDictionary<Type, ImporterFunc> baseImporterTablesValue) &&
+                    baseImporterTablesValue.TryGetValue(value_type, out ImporterFunc baseImporter)) {
+
+                    return baseImporter(reader.Value);
+                }
+
+                // Maybe it's an enum
+                #if NETSTANDARD1_5
+                if (value_type.IsEnum())
+                    return Enum.ToObject (value_type, reader.Value);
+                #else
+                if (value_type.IsEnum)
+                    return Enum.ToObject (value_type, reader.Value);
+                #endif
+                // Try using an implicit conversion operator
+                MethodInfo conv_op = GetConvOp (value_type, json_type);
+
+                if (conv_op != null)
+                    return conv_op.Invoke (null,
+                                           new object[] { reader.Value });
+
+                // No luck
+                throw new JsonException (String.Format (
+                        "Can't assign value '{0}' (type {1}) to type {2}",
+                        reader.Value, json_type, inst_type));
+            }
+
+            object instance = null;
+
+            if (reader.Token == JsonToken.ArrayStart) {
+
+                AddArrayMetadata (inst_type);
+                ArrayMetadata t_data = array_metadata[inst_type];
+
+                if (! t_data.IsArray && ! t_data.IsList)
+                    throw new JsonException (String.Format (
+                            "Type {0} can't act as an array",
+                            inst_type));
+
+                IList list;
+                Type elem_type;
+
+                if (! t_data.IsArray) {
+                    list = (IList) Activator.CreateInstance (inst_type);
+                    elem_type = t_data.ElementType;
+                } else {
+                    list = new ArrayList ();
+                    elem_type = inst_type.GetElementType ();
+                }
+
+                list.Clear();
+
+                while (true) {
+                    object item = ReadValue (elem_type, reader);
+                    if (item == null && reader.Token == JsonToken.ArrayEnd)
+                        break;
+
+                    list.Add (item);
+                }
+
+                if (t_data.IsArray) {
+                    int n = list.Count;
+                    instance = Array.CreateInstance (elem_type, n);
+
+                    for (int i = 0; i < n; i++)
+                        ((Array) instance).SetValue (list[i], i);
+                } else
+                    instance = list;
+
+            } else if (reader.Token == JsonToken.ObjectStart) {
+                AddObjectMetadata (value_type);
+                ObjectMetadata t_data = object_metadata[value_type];
+
+                instance = Activator.CreateInstance (value_type);
+
+                while (true) {
+                    reader.Read ();
+
+                    if (reader.Token == JsonToken.ObjectEnd)
+                        break;
+
+                    string property = (string) reader.Value;
+
+                    if (t_data.Properties.ContainsKey (property)) {
+                        PropertyMetadata prop_data =
+                            t_data.Properties[property];
+
+                        if (prop_data.IsField) {
+                            ((FieldInfo) prop_data.Info).SetValue (
+                                instance, ReadValue (prop_data.Type, reader));
+                        } else {
+                            PropertyInfo p_info =
+                                (PropertyInfo) prop_data.Info;
+
+                            if (p_info.CanWrite)
+                                p_info.SetValue (
+                                    instance,
+                                    ReadValue (prop_data.Type, reader),
+                                    null);
+                            else
+                                ReadValue (prop_data.Type, reader);
+                        }
+
+                    } else {
+                        if (! t_data.IsDictionary) {
+
+                            if (! reader.SkipNonMembers) {
+                                throw new JsonException (String.Format (
+                                        "The type {0} doesn't have the " +
+                                        "property '{1}'",
+                                        inst_type, property));
+                            } else {
+                                ReadSkip (reader);
+                                continue;
+                            }
+                        }
+
+                        ((IDictionary) instance).Add (
+                            property, ReadValue (
+                                t_data.ElementType, reader));
+                    }
+
+                }
+
+            }
+
+            return instance;
+        }
+
+        private static IJsonWrapper ReadValue (WrapperFactory factory,
+                                               JsonReader reader)
+        {
+            reader.Read ();
+
+            if (reader.Token == JsonToken.ArrayEnd ||
+                reader.Token == JsonToken.Null)
+                return null;
+
+            IJsonWrapper instance = factory ();
+
+            if (reader.Token == JsonToken.String) {
+                instance.SetString ((string) reader.Value);
+                return instance;
+            }
+
+            if (reader.Token == JsonToken.Double) {
+                instance.SetDouble ((double) reader.Value);
+                return instance;
+            }
+
+            if (reader.Token == JsonToken.Int) {
+                instance.SetInt ((int) reader.Value);
+                return instance;
+            }
+
+            if (reader.Token == JsonToken.Long) {
+                instance.SetLong ((long) reader.Value);
+                return instance;
+            }
+
+            if (reader.Token == JsonToken.Boolean) {
+                instance.SetBoolean ((bool) reader.Value);
+                return instance;
+            }
+
+            if (reader.Token == JsonToken.ArrayStart) {
+                instance.SetJsonType (JsonType.Array);
+
+                while (true) {
+                    IJsonWrapper item = ReadValue (factory, reader);
+                    if (item == null && reader.Token == JsonToken.ArrayEnd)
+                        break;
+
+                    ((IList) instance).Add (item);
+                }
+            }
+            else if (reader.Token == JsonToken.ObjectStart) {
+                instance.SetJsonType (JsonType.Object);
+
+                while (true) {
+                    reader.Read ();
+
+                    if (reader.Token == JsonToken.ObjectEnd)
+                        break;
+
+                    string property = (string) reader.Value;
+
+                    ((IDictionary) instance)[property] = ReadValue (
+                        factory, reader);
+                }
+
+            }
+
+            return instance;
+        }
+
+        private static void ReadSkip (JsonReader reader)
+        {
+            ToWrapper (
+                delegate { return new JsonMockWrapper (); }, reader);
+        }
+
+        private static void RegisterBaseExporters ()
+        {
+            // This method is only called from the static initializer,
+            // so there is no need to explicitly lock any static members here
+            base_exporters_table[typeof (byte)] =
+                delegate (object obj, JsonWriter writer) {
+                    writer.Write (Convert.ToInt32 ((byte) obj));
+                };
+
+            base_exporters_table[typeof (char)] =
+                delegate (object obj, JsonWriter writer) {
+                    writer.Write (Convert.ToString ((char) obj));
+                };
+
+            base_exporters_table[typeof (DateTime)] =
+                delegate (object obj, JsonWriter writer) {
+                    writer.Write (Convert.ToString ((DateTime) obj,
+                                                    datetime_format));
+                };
+
+            base_exporters_table[typeof (decimal)] =
+                delegate (object obj, JsonWriter writer) {
+                    writer.Write ((decimal) obj);
+                };
+
+            base_exporters_table[typeof (sbyte)] =
+                delegate (object obj, JsonWriter writer) {
+                    writer.Write (Convert.ToInt32 ((sbyte) obj));
+                };
+
+            base_exporters_table[typeof (short)] =
+                delegate (object obj, JsonWriter writer) {
+                    writer.Write (Convert.ToInt32 ((short) obj));
+                };
+
+            base_exporters_table[typeof (ushort)] =
+                delegate (object obj, JsonWriter writer) {
+                    writer.Write (Convert.ToInt32 ((ushort) obj));
+                };
+
+            base_exporters_table[typeof (uint)] =
+                delegate (object obj, JsonWriter writer) {
+                    writer.Write (Convert.ToUInt64 ((uint) obj));
+                };
+
+            base_exporters_table[typeof (ulong)] =
+                delegate (object obj, JsonWriter writer) {
+                    writer.Write ((ulong) obj);
+                };
+
+            base_exporters_table[typeof(DateTimeOffset)] =
+                delegate (object obj, JsonWriter writer) {
+                    writer.Write(((DateTimeOffset)obj).ToString("yyyy-MM-ddTHH:mm:ss.fffffffzzz", datetime_format));
+                };
+        }
+
+        private static void RegisterBaseImporters ()
+        {
+            // This method is only called from the static initializer,
+            // so there is no need to explicitly lock any static members here
+            ImporterFunc importer;
+
+            importer = delegate (object input) {
+                return Convert.ToByte ((int) input);
+            };
+            RegisterImporter (base_importers_table, typeof (int),
+                              typeof (byte), importer);
+
+            importer = delegate (object input) {
+                return Convert.ToUInt64 ((int) input);
+            };
+            RegisterImporter (base_importers_table, typeof (int),
+                              typeof (ulong), importer);
+
+            importer = delegate (object input) {
+                return Convert.ToInt64((int)input);
+            };
+            RegisterImporter(base_importers_table, typeof(int),
+                              typeof(long), importer);
+
+            importer = delegate (object input) {
+                return Convert.ToSByte ((int) input);
+            };
+            RegisterImporter (base_importers_table, typeof (int),
+                              typeof (sbyte), importer);
+
+            importer = delegate (object input) {
+                return Convert.ToInt16 ((int) input);
+            };
+            RegisterImporter (base_importers_table, typeof (int),
+                              typeof (short), importer);
+
+            importer = delegate (object input) {
+                return Convert.ToUInt16 ((int) input);
+            };
+            RegisterImporter (base_importers_table, typeof (int),
+                              typeof (ushort), importer);
+
+            importer = delegate (object input) {
+                return Convert.ToUInt32 ((int) input);
+            };
+            RegisterImporter (base_importers_table, typeof (int),
+                              typeof (uint), importer);
+
+            importer = delegate (object input) {
+                return Convert.ToSingle ((int) input);
+            };
+            RegisterImporter (base_importers_table, typeof (int),
+                              typeof (float), importer);
+
+            importer = delegate (object input) {
+                return Convert.ToDouble ((int) input);
+            };
+            RegisterImporter (base_importers_table, typeof (int),
+                              typeof (double), importer);
+
+            importer = delegate (object input) {
+                return Convert.ToDecimal ((double) input);
+            };
+            RegisterImporter (base_importers_table, typeof (double),
+                              typeof (decimal), importer);
+
+            importer = delegate (object input) {
+                return Convert.ToSingle((double)input);
+            };
+            RegisterImporter(base_importers_table, typeof(double),
+                typeof(float), importer);
+
+            importer = delegate (object input) {
+                return Convert.ToUInt32 ((long) input);
+            };
+            RegisterImporter (base_importers_table, typeof (long),
+                              typeof (uint), importer);
+
+            importer = delegate (object input) {
+                return Convert.ToChar ((string) input);
+            };
+            RegisterImporter (base_importers_table, typeof (string),
+                              typeof (char), importer);
+
+            importer = delegate (object input) {
+                return Convert.ToDateTime ((string) input, datetime_format);
+            };
+            RegisterImporter (base_importers_table, typeof (string),
+                              typeof (DateTime), importer);
+
+            importer = delegate (object input) {
+                return DateTimeOffset.Parse((string)input, datetime_format);
+            };
+            RegisterImporter(base_importers_table, typeof(string),
+                typeof(DateTimeOffset), importer);
+        }
+
+        private static void RegisterImporter (
+            IDictionary<Type, IDictionary<Type, ImporterFunc>> table,
+            Type json_type, Type value_type, ImporterFunc importer)
+        {
+            if (! table.ContainsKey (json_type))
+                table.Add (json_type, new Dictionary<Type, ImporterFunc> ());
+
+            table[json_type][value_type] = importer;
+        }
+
+        private static void WriteValue (object obj, JsonWriter writer,
+                                        bool writer_is_private,
+                                        int depth)
+        {
+            if (depth > max_nesting_depth)
+                throw new JsonException (
+                    String.Format ("Max allowed object depth reached while " +
+                                   "trying to export from type {0}",
+                                   obj.GetType ()));
+
+            if (obj == null) {
+                writer.Write (null);
+                return;
+            }
+
+            if (obj is IJsonWrapper) {
+                if (writer_is_private)
+                    writer.TextWriter.Write (((IJsonWrapper) obj).ToJson ());
+                else
+                    ((IJsonWrapper) obj).ToJson (writer);
+
+                return;
+            }
+
+            if (obj is String) {
+                writer.Write ((string) obj);
+                return;
+            }
+
+            if (obj is Double) {
+                writer.Write ((double) obj);
+                return;
+            }
+
+            if (obj is Single)
+            {
+                writer.Write((float)obj);
+                return;
+            }
+
+            if (obj is Int32) {
+                writer.Write ((int) obj);
+                return;
+            }
+
+            if (obj is Boolean) {
+                writer.Write ((bool) obj);
+                return;
+            }
+
+            if (obj is Int64) {
+                writer.Write ((long) obj);
+                return;
+            }
+
+            if (obj is Array) {
+                writer.WriteArrayStart ();
+
+                foreach (object elem in (Array) obj)
+                    WriteValue (elem, writer, writer_is_private, depth + 1);
+
+                writer.WriteArrayEnd ();
+
+                return;
+            }
+
+            if (obj is IList) {
+                writer.WriteArrayStart ();
+                foreach (object elem in (IList) obj)
+                    WriteValue (elem, writer, writer_is_private, depth + 1);
+                writer.WriteArrayEnd ();
+
+                return;
+            }
+
+            if (obj is IDictionary dictionary) {
+                writer.WriteObjectStart ();
+                foreach (DictionaryEntry entry in dictionary) {
+                    var propertyName = entry.Key is string key ?
+                        key
+                        : Convert.ToString(entry.Key, CultureInfo.InvariantCulture);
+                    writer.WritePropertyName (propertyName);
+                    WriteValue (entry.Value, writer, writer_is_private,
+                                depth + 1);
+                }
+                writer.WriteObjectEnd ();
+
+                return;
+            }
+
+            Type obj_type = obj.GetType ();
+
+            // See if there's a custom exporter for the object
+            lock (custom_exporters_table_lock) {
+                if (custom_exporters_table.TryGetValue(obj_type, out ExporterFunc customExporter)) {
+                    customExporter(obj, writer);
+
+                    return;
+                }
+            }
+
+            // If not, maybe there's a base exporter
+            if (base_exporters_table.TryGetValue(obj_type, out ExporterFunc baseExporter)) {
+                baseExporter(obj, writer);
+
+                return;
+            }
+
+            // Last option, let's see if it's an enum
+            if (obj is Enum) {
+                Type e_type = Enum.GetUnderlyingType (obj_type);
+
+                if (e_type == typeof (long))
+                    writer.Write ((long) obj);
+                else if (e_type == typeof (uint))
+                    writer.Write ((uint) obj);
+                else if (e_type == typeof (ulong))
+                    writer.Write ((ulong) obj);
+                else if (e_type == typeof(ushort))
+                    writer.Write ((ushort)obj);
+                else if (e_type == typeof(short))
+                    writer.Write ((short)obj);
+                else if (e_type == typeof(byte))
+                    writer.Write ((byte)obj);
+                else if (e_type == typeof(sbyte))
+                    writer.Write ((sbyte)obj);
+                else
+                    writer.Write ((int) obj);
+
+                return;
+            }
+
+            // Okay, so it looks like the input should be exported as an
+            // object
+            AddTypeProperties (obj_type);
+            IList<PropertyMetadata> props = type_properties[obj_type];
+
+            writer.WriteObjectStart ();
+            foreach (PropertyMetadata p_data in props) {
+                if (p_data.IsField) {
+                    writer.WritePropertyName (p_data.Info.Name);
+                    WriteValue (((FieldInfo) p_data.Info).GetValue (obj),
+                                writer, writer_is_private, depth + 1);
+                }
+                else {
+                    PropertyInfo p_info = (PropertyInfo) p_data.Info;
+
+                    if (p_info.CanRead) {
+                        writer.WritePropertyName (p_data.Info.Name);
+                        WriteValue (p_info.GetValue (obj, null),
+                                    writer, writer_is_private, depth + 1);
+                    }
+                }
+            }
+            writer.WriteObjectEnd ();
+        }
+        #endregion
+
+
+        public static string ToJson (object obj)
+        {
+            lock (static_writer_lock) {
+                static_writer.Reset ();
+
+                WriteValue (obj, static_writer, true, 0);
+
+                return static_writer.ToString ();
+            }
+        }
+
+        public static void ToJson (object obj, JsonWriter writer)
+        {
+            WriteValue (obj, writer, false, 0);
+        }
+
+        public static JsonData ToObject (JsonReader reader)
+        {
+            return (JsonData) ToWrapper (
+                delegate { return new JsonData (); }, reader);
+        }
+
+        public static JsonData ToObject (TextReader reader)
+        {
+            JsonReader json_reader = new JsonReader (reader);
+
+            return (JsonData) ToWrapper (
+                delegate { return new JsonData (); }, json_reader);
+        }
+
+        public static JsonData ToObject (string json)
+        {
+            return (JsonData) ToWrapper (
+                delegate { return new JsonData (); }, json);
+        }
+
+        public static T ToObject<T> (JsonReader reader)
+        {
+            return (T) ReadValue (typeof (T), reader);
+        }
+
+        public static T ToObject<T> (TextReader reader)
+        {
+            JsonReader json_reader = new JsonReader (reader);
+
+            return (T) ReadValue (typeof (T), json_reader);
+        }
+
+        public static T ToObject<T> (string json)
+        {
+            JsonReader reader = new JsonReader (json);
+
+            return (T) ReadValue (typeof (T), reader);
+        }
+
+        public static object ToObject(string json, Type ConvertType )
+        {
+            JsonReader reader = new JsonReader(json);
+
+            return ReadValue(ConvertType, reader);
+        }
+
+        public static IJsonWrapper ToWrapper (WrapperFactory factory,
+                                              JsonReader reader)
+        {
+            return ReadValue (factory, reader);
+        }
+
+        public static IJsonWrapper ToWrapper (WrapperFactory factory,
+                                              string json)
+        {
+            JsonReader reader = new JsonReader (json);
+
+            return ReadValue (factory, reader);
+        }
+
+        public static void RegisterExporter<T> (ExporterFunc<T> exporter)
+        {
+            ExporterFunc exporter_wrapper =
+                delegate (object obj, JsonWriter writer) {
+                    exporter ((T) obj, writer);
+                };
+
+            lock (custom_exporters_table_lock) { 
+                custom_exporters_table[typeof (T)] = exporter_wrapper;
+            }
+        }
+
+        public static void RegisterImporter<TJson, TValue> (
+            ImporterFunc<TJson, TValue> importer)
+        {
+            ImporterFunc importer_wrapper =
+                delegate (object input) {
+                    return importer ((TJson) input);
+                };
+
+            lock (custom_importers_table_lock) {
+                RegisterImporter (custom_importers_table, typeof (TJson),
+                                 typeof (TValue), importer_wrapper);
+            }
+        }
+
+        public static void UnregisterExporters ()
+        {
+            lock (custom_exporters_table_lock) {
+                custom_exporters_table.Clear();
+            }
+        }
+
+        public static void UnregisterImporters ()
+        {
+            lock (custom_importers_table_lock) {
+                custom_importers_table.Clear();
+            }
+        }
+    }
+}
diff --git a/Main/Common/LitJson/JsonMapper.cs.meta b/Main/Common/LitJson/JsonMapper.cs.meta
new file mode 100644
index 0000000..345341a
--- /dev/null
+++ b/Main/Common/LitJson/JsonMapper.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c2a82b623add47f4b861ffdf072e7e73
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Common/LitJson/JsonMockWrapper.cs b/Main/Common/LitJson/JsonMockWrapper.cs
new file mode 100644
index 0000000..dfe7adb
--- /dev/null
+++ b/Main/Common/LitJson/JsonMockWrapper.cs
@@ -0,0 +1,105 @@
+#region Header
+/**
+ * JsonMockWrapper.cs
+ *   Mock object implementing IJsonWrapper, to facilitate actions like
+ *   skipping data more efficiently.
+ *
+ * The authors disclaim copyright to this source code. For more details, see
+ * the COPYING file included with this distribution.
+ **/
+#endregion
+
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+
+
+namespace LitJson
+{
+    public class JsonMockWrapper : IJsonWrapper
+    {
+        public bool IsArray   { get { return false; } }
+        public bool IsBoolean { get { return false; } }
+        public bool IsDouble  { get { return false; } }
+        public bool IsInt     { get { return false; } }
+        public bool IsLong    { get { return false; } }
+        public bool IsObject  { get { return false; } }
+        public bool IsString  { get { return false; } }
+
+        public bool     GetBoolean ()  { return false; }
+        public double   GetDouble ()   { return 0.0; }
+        public int      GetInt ()      { return 0; }
+        public JsonType GetJsonType () { return JsonType.None; }
+        public long     GetLong ()     { return 0L; }
+        public string   GetString ()   { return ""; }
+
+        public void SetBoolean  (bool val)      {}
+        public void SetDouble   (double val)    {}
+        public void SetInt      (int val)       {}
+        public void SetJsonType (JsonType type) {}
+        public void SetLong     (long val)      {}
+        public void SetString   (string val)    {}
+
+        public string ToJson ()                  { return ""; }
+        public void   ToJson (JsonWriter writer) {}
+
+
+        bool IList.IsFixedSize { get { return true; } }
+        bool IList.IsReadOnly  { get { return true; } }
+
+        object IList.this[int index] {
+            get { return null; }
+            set {}
+        }
+
+        int  IList.Add (object value)       { return 0; }
+        void IList.Clear ()                 {}
+        bool IList.Contains (object value)  { return false; }
+        int  IList.IndexOf (object value)   { return -1; }
+        void IList.Insert (int i, object v) {}
+        void IList.Remove (object value)    {}
+        void IList.RemoveAt (int index)     {}
+
+
+        int    ICollection.Count          { get { return 0; } }
+        bool   ICollection.IsSynchronized { get { return false; } }
+        object ICollection.SyncRoot       { get { return null; } }
+
+        void ICollection.CopyTo (Array array, int index) {}
+
+
+        IEnumerator IEnumerable.GetEnumerator () { return null; }
+
+
+        bool IDictionary.IsFixedSize { get { return true; } }
+        bool IDictionary.IsReadOnly  { get { return true; } }
+
+        ICollection IDictionary.Keys   { get { return null; } }
+        ICollection IDictionary.Values { get { return null; } }
+
+        object IDictionary.this[object key] {
+            get { return null; }
+            set {}
+        }
+
+        void IDictionary.Add (object k, object v) {}
+        void IDictionary.Clear ()                 {}
+        bool IDictionary.Contains (object key)    { return false; }
+        void IDictionary.Remove (object key)      {}
+
+        IDictionaryEnumerator IDictionary.GetEnumerator () { return null; }
+
+
+        object IOrderedDictionary.this[int idx] {
+            get { return null; }
+            set {}
+        }
+
+        IDictionaryEnumerator IOrderedDictionary.GetEnumerator () {
+            return null;
+        }
+        void IOrderedDictionary.Insert   (int i, object k, object v) {}
+        void IOrderedDictionary.RemoveAt (int i) {}
+    }
+}
diff --git a/Main/Common/LitJson/JsonMockWrapper.cs.meta b/Main/Common/LitJson/JsonMockWrapper.cs.meta
new file mode 100644
index 0000000..4aeb212
--- /dev/null
+++ b/Main/Common/LitJson/JsonMockWrapper.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fcd0c88788b3d3548aaaadda98570f82
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Common/LitJson/JsonReader.cs b/Main/Common/LitJson/JsonReader.cs
new file mode 100644
index 0000000..e47eabc
--- /dev/null
+++ b/Main/Common/LitJson/JsonReader.cs
@@ -0,0 +1,478 @@
+#region Header
+/**
+ * JsonReader.cs
+ *   Stream-like access to JSON text.
+ *
+ * The authors disclaim copyright to this source code. For more details, see
+ * the COPYING file included with this distribution.
+ **/
+#endregion
+
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+
+
+namespace LitJson
+{
+    public enum JsonToken
+    {
+        None,
+
+        ObjectStart,
+        PropertyName,
+        ObjectEnd,
+
+        ArrayStart,
+        ArrayEnd,
+
+        Int,
+        Long,
+        Double,
+
+        String,
+
+        Boolean,
+        Null
+    }
+
+
+    public class JsonReader
+    {
+        #region Fields
+        private static readonly IDictionary<int, IDictionary<int, int[]>> parse_table;
+
+        private Stack<int>    automaton_stack;
+        private int           current_input;
+        private int           current_symbol;
+        private bool          end_of_json;
+        private bool          end_of_input;
+        private Lexer         lexer;
+        private bool          parser_in_string;
+        private bool          parser_return;
+        private bool          read_started;
+        private TextReader    reader;
+        private bool          reader_is_owned;
+        private bool          skip_non_members;
+        private object        token_value;
+        private JsonToken     token;
+        #endregion
+
+
+        #region Public Properties
+        public bool AllowComments {
+            get { return lexer.AllowComments; }
+            set { lexer.AllowComments = value; }
+        }
+
+        public bool AllowSingleQuotedStrings {
+            get { return lexer.AllowSingleQuotedStrings; }
+            set { lexer.AllowSingleQuotedStrings = value; }
+        }
+
+        public bool SkipNonMembers {
+            get { return skip_non_members; }
+            set { skip_non_members = value; }
+        }
+
+        public bool EndOfInput {
+            get { return end_of_input; }
+        }
+
+        public bool EndOfJson {
+            get { return end_of_json; }
+        }
+
+        public JsonToken Token {
+            get { return token; }
+        }
+
+        public object Value {
+            get { return token_value; }
+        }
+        #endregion
+
+
+        #region Constructors
+        static JsonReader ()
+        {
+            parse_table = PopulateParseTable ();
+        }
+
+        public JsonReader (string json_text) :
+            this (new StringReader (json_text), true)
+        {
+        }
+
+        public JsonReader (TextReader reader) :
+            this (reader, false)
+        {
+        }
+
+        private JsonReader (TextReader reader, bool owned)
+        {
+            if (reader == null)
+                throw new ArgumentNullException ("reader");
+
+            parser_in_string = false;
+            parser_return    = false;
+
+            read_started = false;
+            automaton_stack = new Stack<int> ();
+            automaton_stack.Push ((int) ParserToken.End);
+            automaton_stack.Push ((int) ParserToken.Text);
+
+            lexer = new Lexer (reader);
+
+            end_of_input = false;
+            end_of_json  = false;
+
+            skip_non_members = true;
+
+            this.reader = reader;
+            reader_is_owned = owned;
+        }
+        #endregion
+
+
+        #region Static Methods
+        private static IDictionary<int, IDictionary<int, int[]>> PopulateParseTable ()
+        {
+            // See section A.2. of the manual for details
+            IDictionary<int, IDictionary<int, int[]>> parse_table = new Dictionary<int, IDictionary<int, int[]>> ();
+
+            TableAddRow (parse_table, ParserToken.Array);
+            TableAddCol (parse_table, ParserToken.Array, '[',
+                            '[',
+                            (int) ParserToken.ArrayPrime);
+
+            TableAddRow (parse_table, ParserToken.ArrayPrime);
+            TableAddCol (parse_table, ParserToken.ArrayPrime, '"',
+                            (int) ParserToken.Value,
+
+                            (int) ParserToken.ValueRest,
+                            ']');
+            TableAddCol (parse_table, ParserToken.ArrayPrime, '[',
+                            (int) ParserToken.Value,
+                            (int) ParserToken.ValueRest,
+                            ']');
+            TableAddCol (parse_table, ParserToken.ArrayPrime, ']',
+                            ']');
+            TableAddCol (parse_table, ParserToken.ArrayPrime, '{',
+                            (int) ParserToken.Value,
+                            (int) ParserToken.ValueRest,
+                            ']');
+            TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.Number,
+                            (int) ParserToken.Value,
+                            (int) ParserToken.ValueRest,
+                            ']');
+            TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.True,
+                            (int) ParserToken.Value,
+                            (int) ParserToken.ValueRest,
+                            ']');
+            TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.False,
+                            (int) ParserToken.Value,
+                            (int) ParserToken.ValueRest,
+                            ']');
+            TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.Null,
+                            (int) ParserToken.Value,
+                            (int) ParserToken.ValueRest,
+                            ']');
+
+            TableAddRow (parse_table, ParserToken.Object);
+            TableAddCol (parse_table, ParserToken.Object, '{',
+                            '{',
+                            (int) ParserToken.ObjectPrime);
+
+            TableAddRow (parse_table, ParserToken.ObjectPrime);
+            TableAddCol (parse_table, ParserToken.ObjectPrime, '"',
+                            (int) ParserToken.Pair,
+                            (int) ParserToken.PairRest,
+                            '}');
+            TableAddCol (parse_table, ParserToken.ObjectPrime, '}',
+                            '}');
+
+            TableAddRow (parse_table, ParserToken.Pair);
+            TableAddCol (parse_table, ParserToken.Pair, '"',
+                            (int) ParserToken.String,
+                            ':',
+                            (int) ParserToken.Value);
+
+            TableAddRow (parse_table, ParserToken.PairRest);
+            TableAddCol (parse_table, ParserToken.PairRest, ',',
+                            ',',
+                            (int) ParserToken.Pair,
+                            (int) ParserToken.PairRest);
+            TableAddCol (parse_table, ParserToken.PairRest, '}',
+                            (int) ParserToken.Epsilon);
+
+            TableAddRow (parse_table, ParserToken.String);
+            TableAddCol (parse_table, ParserToken.String, '"',
+                            '"',
+                            (int) ParserToken.CharSeq,
+                            '"');
+
+            TableAddRow (parse_table, ParserToken.Text);
+            TableAddCol (parse_table, ParserToken.Text, '[',
+                            (int) ParserToken.Array);
+            TableAddCol (parse_table, ParserToken.Text, '{',
+                            (int) ParserToken.Object);
+
+            TableAddRow (parse_table, ParserToken.Value);
+            TableAddCol (parse_table, ParserToken.Value, '"',
+                            (int) ParserToken.String);
+            TableAddCol (parse_table, ParserToken.Value, '[',
+                            (int) ParserToken.Array);
+            TableAddCol (parse_table, ParserToken.Value, '{',
+                            (int) ParserToken.Object);
+            TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.Number,
+                            (int) ParserToken.Number);
+            TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.True,
+                            (int) ParserToken.True);
+            TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.False,
+                            (int) ParserToken.False);
+            TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.Null,
+                            (int) ParserToken.Null);
+
+            TableAddRow (parse_table, ParserToken.ValueRest);
+            TableAddCol (parse_table, ParserToken.ValueRest, ',',
+                            ',',
+                            (int) ParserToken.Value,
+                            (int) ParserToken.ValueRest);
+            TableAddCol (parse_table, ParserToken.ValueRest, ']',
+                            (int) ParserToken.Epsilon);
+
+            return parse_table;
+        }
+
+        private static void TableAddCol (IDictionary<int, IDictionary<int, int[]>> parse_table, ParserToken row, int col,
+                                         params int[] symbols)
+        {
+            parse_table[(int) row].Add (col, symbols);
+        }
+
+        private static void TableAddRow (IDictionary<int, IDictionary<int, int[]>> parse_table, ParserToken rule)
+        {
+            parse_table.Add ((int) rule, new Dictionary<int, int[]> ());
+        }
+        #endregion
+
+
+        #region Private Methods
+        private void ProcessNumber (string number)
+        {
+            if (number.IndexOf ('.') != -1 ||
+                number.IndexOf ('e') != -1 ||
+                number.IndexOf ('E') != -1) {
+
+                double n_double;
+                if (double.TryParse (number, NumberStyles.Any, CultureInfo.InvariantCulture, out n_double)) {
+                    token = JsonToken.Double;
+                    token_value = n_double;
+
+                    return;
+                }
+            }
+
+            int n_int32;
+            if (int.TryParse (number, NumberStyles.Integer, CultureInfo.InvariantCulture, out n_int32)) {
+                token = JsonToken.Int;
+                token_value = n_int32;
+
+                return;
+            }
+
+            long n_int64;
+            if (long.TryParse (number, NumberStyles.Integer, CultureInfo.InvariantCulture, out n_int64)) {
+                token = JsonToken.Long;
+                token_value = n_int64;
+
+                return;
+            }
+
+            ulong n_uint64;
+            if (ulong.TryParse(number, NumberStyles.Integer, CultureInfo.InvariantCulture, out n_uint64))
+            {
+                token = JsonToken.Long;
+                token_value = n_uint64;
+
+                return;
+            }
+
+            // Shouldn't happen, but just in case, return something
+            token = JsonToken.Int;
+            token_value = 0;
+        }
+
+        private void ProcessSymbol ()
+        {
+            if (current_symbol == '[')  {
+                token = JsonToken.ArrayStart;
+                parser_return = true;
+
+            } else if (current_symbol == ']')  {
+                token = JsonToken.ArrayEnd;
+                parser_return = true;
+
+            } else if (current_symbol == '{')  {
+                token = JsonToken.ObjectStart;
+                parser_return = true;
+
+            } else if (current_symbol == '}')  {
+                token = JsonToken.ObjectEnd;
+                parser_return = true;
+
+            } else if (current_symbol == '"')  {
+                if (parser_in_string) {
+                    parser_in_string = false;
+
+                    parser_return = true;
+
+                } else {
+                    if (token == JsonToken.None)
+                        token = JsonToken.String;
+
+                    parser_in_string = true;
+                }
+
+            } else if (current_symbol == (int) ParserToken.CharSeq) {
+                token_value = lexer.StringValue;
+
+            } else if (current_symbol == (int) ParserToken.False)  {
+                token = JsonToken.Boolean;
+                token_value = false;
+                parser_return = true;
+
+            } else if (current_symbol == (int) ParserToken.Null)  {
+                token = JsonToken.Null;
+                parser_return = true;
+
+            } else if (current_symbol == (int) ParserToken.Number)  {
+                ProcessNumber (lexer.StringValue);
+
+                parser_return = true;
+
+            } else if (current_symbol == (int) ParserToken.Pair)  {
+                token = JsonToken.PropertyName;
+
+            } else if (current_symbol == (int) ParserToken.True)  {
+                token = JsonToken.Boolean;
+                token_value = true;
+                parser_return = true;
+
+            }
+        }
+
+        private bool ReadToken ()
+        {
+            if (end_of_input)
+                return false;
+
+            lexer.NextToken ();
+
+            if (lexer.EndOfInput) {
+                Close ();
+
+                return false;
+            }
+
+            current_input = lexer.Token;
+
+            return true;
+        }
+        #endregion
+
+
+        public void Close ()
+        {
+            if (end_of_input)
+                return;
+
+            end_of_input = true;
+            end_of_json  = true;
+
+            if (reader_is_owned)
+            {
+                using(reader){}
+            }
+
+            reader = null;
+        }
+
+        public bool Read ()
+        {
+            if (end_of_input)
+                return false;
+
+            if (end_of_json) {
+                end_of_json = false;
+                automaton_stack.Clear ();
+                automaton_stack.Push ((int) ParserToken.End);
+                automaton_stack.Push ((int) ParserToken.Text);
+            }
+
+            parser_in_string = false;
+            parser_return    = false;
+
+            token       = JsonToken.None;
+            token_value = null;
+
+            if (! read_started) {
+                read_started = true;
+
+                if (! ReadToken ())
+                    return false;
+            }
+
+
+            int[] entry_symbols;
+
+            while (true) {
+                if (parser_return) {
+                    if (automaton_stack.Peek () == (int) ParserToken.End)
+                        end_of_json = true;
+
+                    return true;
+                }
+
+                current_symbol = automaton_stack.Pop ();
+
+                ProcessSymbol ();
+
+                if (current_symbol == current_input) {
+                    if (! ReadToken ()) {
+                        if (automaton_stack.Peek () != (int) ParserToken.End)
+                            throw new JsonException (
+                                "Input doesn't evaluate to proper JSON text");
+
+                        if (parser_return)
+                            return true;
+
+                        return false;
+                    }
+
+                    continue;
+                }
+
+                try {
+
+                    entry_symbols =
+                        parse_table[current_symbol][current_input];
+
+                } catch (KeyNotFoundException e) {
+                    throw new JsonException ((ParserToken) current_input, e);
+                }
+
+                if (entry_symbols[0] == (int) ParserToken.Epsilon)
+                    continue;
+
+                for (int i = entry_symbols.Length - 1; i >= 0; i--)
+                    automaton_stack.Push (entry_symbols[i]);
+            }
+        }
+
+    }
+}
diff --git a/Main/Common/LitJson/JsonReader.cs.meta b/Main/Common/LitJson/JsonReader.cs.meta
new file mode 100644
index 0000000..d231136
--- /dev/null
+++ b/Main/Common/LitJson/JsonReader.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ab4ffde22b1fefb41900344a190ab56e
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Common/LitJson/JsonWriter.cs b/Main/Common/LitJson/JsonWriter.cs
new file mode 100644
index 0000000..4bfaaac
--- /dev/null
+++ b/Main/Common/LitJson/JsonWriter.cs
@@ -0,0 +1,484 @@
+#region Header
+/**
+ * JsonWriter.cs
+ *   Stream-like facility to output JSON text.
+ *
+ * The authors disclaim copyright to this source code. For more details, see
+ * the COPYING file included with this distribution.
+ **/
+#endregion
+
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+
+
+namespace LitJson
+{
+    internal enum Condition
+    {
+        InArray,
+        InObject,
+        NotAProperty,
+        Property,
+        Value
+    }
+
+    internal class WriterContext
+    {
+        public int  Count;
+        public bool InArray;
+        public bool InObject;
+        public bool ExpectingValue;
+        public int  Padding;
+    }
+
+    public class JsonWriter
+    {
+        #region Fields
+        private static readonly NumberFormatInfo number_format;
+
+        private WriterContext        context;
+        private Stack<WriterContext> ctx_stack;
+        private bool                 has_reached_end;
+        private char[]               hex_seq;
+        private int                  indentation;
+        private int                  indent_value;
+        private StringBuilder        inst_string_builder;
+        private bool                 pretty_print;
+        private bool                 validate;
+        private bool                 lower_case_properties;
+        private TextWriter           writer;
+        #endregion
+
+
+        #region Properties
+        public int IndentValue {
+            get { return indent_value; }
+            set {
+                indentation = (indentation / indent_value) * value;
+                indent_value = value;
+            }
+        }
+
+        public bool PrettyPrint {
+            get { return pretty_print; }
+            set { pretty_print = value; }
+        }
+
+        public TextWriter TextWriter {
+            get { return writer; }
+        }
+
+        public bool Validate {
+            get { return validate; }
+            set { validate = value; }
+        }
+
+        public bool LowerCaseProperties {
+            get { return lower_case_properties; }
+            set { lower_case_properties = value; }
+        }
+        #endregion
+
+
+        #region Constructors
+        static JsonWriter ()
+        {
+            number_format = NumberFormatInfo.InvariantInfo;
+        }
+
+        public JsonWriter ()
+        {
+            inst_string_builder = new StringBuilder ();
+            writer = new StringWriter (inst_string_builder);
+
+            Init ();
+        }
+
+        public JsonWriter (StringBuilder sb) :
+            this (new StringWriter (sb))
+        {
+        }
+
+        public JsonWriter (TextWriter writer)
+        {
+            if (writer == null)
+                throw new ArgumentNullException ("writer");
+
+            this.writer = writer;
+
+            Init ();
+        }
+        #endregion
+
+
+        #region Private Methods
+        private void DoValidation (Condition cond)
+        {
+            if (! context.ExpectingValue)
+                context.Count++;
+
+            if (! validate)
+                return;
+
+            if (has_reached_end)
+                throw new JsonException (
+                    "A complete JSON symbol has already been written");
+
+            switch (cond) {
+            case Condition.InArray:
+                if (! context.InArray)
+                    throw new JsonException (
+                        "Can't close an array here");
+                break;
+
+            case Condition.InObject:
+                if (! context.InObject || context.ExpectingValue)
+                    throw new JsonException (
+                        "Can't close an object here");
+                break;
+
+            case Condition.NotAProperty:
+                if (context.InObject && ! context.ExpectingValue)
+                    throw new JsonException (
+                        "Expected a property");
+                break;
+
+            case Condition.Property:
+                if (! context.InObject || context.ExpectingValue)
+                    throw new JsonException (
+                        "Can't add a property here");
+                break;
+
+            case Condition.Value:
+                if (! context.InArray &&
+                    (! context.InObject || ! context.ExpectingValue))
+                    throw new JsonException (
+                        "Can't add a value here");
+
+                break;
+            }
+        }
+
+        private void Init ()
+        {
+            has_reached_end = false;
+            hex_seq = new char[4];
+            indentation = 0;
+            indent_value = 4;
+            pretty_print = false;
+            validate = true;
+            lower_case_properties = false;
+
+            ctx_stack = new Stack<WriterContext> ();
+            context = new WriterContext ();
+            ctx_stack.Push (context);
+        }
+
+        private static void IntToHex (int n, char[] hex)
+        {
+            int num;
+
+            for (int i = 0; i < 4; i++) {
+                num = n % 16;
+
+                if (num < 10)
+                    hex[3 - i] = (char) ('0' + num);
+                else
+                    hex[3 - i] = (char) ('A' + (num - 10));
+
+                n >>= 4;
+            }
+        }
+
+        private void Indent ()
+        {
+            if (pretty_print)
+                indentation += indent_value;
+        }
+
+
+        private void Put (string str)
+        {
+            if (pretty_print && ! context.ExpectingValue)
+                for (int i = 0; i < indentation; i++)
+                    writer.Write (' ');
+
+            writer.Write (str);
+        }
+
+        private void PutNewline ()
+        {
+            PutNewline (true);
+        }
+
+        private void PutNewline (bool add_comma)
+        {
+            if (add_comma && ! context.ExpectingValue &&
+                context.Count > 1)
+                writer.Write (',');
+
+            if (pretty_print && ! context.ExpectingValue)
+                writer.Write (Environment.NewLine);
+        }
+
+        private void PutString (string str)
+        {
+            Put (String.Empty);
+
+            writer.Write ('"');
+
+            int n = str.Length;
+            for (int i = 0; i < n; i++) {
+                switch (str[i]) {
+                case '\n':
+                    writer.Write ("\\n");
+                    continue;
+
+                case '\r':
+                    writer.Write ("\\r");
+                    continue;
+
+                case '\t':
+                    writer.Write ("\\t");
+                    continue;
+
+                case '"':
+                case '\\':
+                    writer.Write ('\\');
+                    writer.Write (str[i]);
+                    continue;
+
+                case '\f':
+                    writer.Write ("\\f");
+                    continue;
+
+                case '\b':
+                    writer.Write ("\\b");
+                    continue;
+                }
+
+                if ((int) str[i] >= 32 && (int) str[i] <= 126) {
+                    writer.Write (str[i]);
+                    continue;
+                }
+
+                // Default, turn into a \uXXXX sequence
+                IntToHex ((int) str[i], hex_seq);
+                writer.Write ("\\u");
+                writer.Write (hex_seq);
+            }
+
+            writer.Write ('"');
+        }
+
+        private void Unindent ()
+        {
+            if (pretty_print)
+                indentation -= indent_value;
+        }
+        #endregion
+
+
+        public override string ToString ()
+        {
+            if (inst_string_builder == null)
+                return String.Empty;
+
+            return inst_string_builder.ToString ();
+        }
+
+        public void Reset ()
+        {
+            has_reached_end = false;
+
+            ctx_stack.Clear ();
+            context = new WriterContext ();
+            ctx_stack.Push (context);
+
+            if (inst_string_builder != null)
+                inst_string_builder.Remove (0, inst_string_builder.Length);
+        }
+
+        public void Write (bool boolean)
+        {
+            DoValidation (Condition.Value);
+            PutNewline ();
+
+            Put (boolean ? "true" : "false");
+
+            context.ExpectingValue = false;
+        }
+
+        public void Write (decimal number)
+        {
+            DoValidation (Condition.Value);
+            PutNewline ();
+
+            Put (Convert.ToString (number, number_format));
+
+            context.ExpectingValue = false;
+        }
+
+        public void Write (double number)
+        {
+            DoValidation (Condition.Value);
+            PutNewline ();
+
+            string str = Convert.ToString (number, number_format);
+            Put (str);
+
+            if (str.IndexOf ('.') == -1 &&
+                str.IndexOf ('E') == -1)
+                writer.Write (".0");
+
+            context.ExpectingValue = false;
+        }
+
+        public void Write(float number)
+        {
+            DoValidation(Condition.Value);
+            PutNewline();
+
+            string str = Convert.ToString(number, number_format);
+            Put(str);
+
+            context.ExpectingValue = false;
+        }
+
+        public void Write (int number)
+        {
+            DoValidation (Condition.Value);
+            PutNewline ();
+
+            Put (Convert.ToString (number, number_format));
+
+            context.ExpectingValue = false;
+        }
+
+        public void Write (long number)
+        {
+            DoValidation (Condition.Value);
+            PutNewline ();
+
+            Put (Convert.ToString (number, number_format));
+
+            context.ExpectingValue = false;
+        }
+
+        public void Write (string str)
+        {
+            DoValidation (Condition.Value);
+            PutNewline ();
+
+            if (str == null)
+                Put ("null");
+            else
+                PutString (str);
+
+            context.ExpectingValue = false;
+        }
+
+        [CLSCompliant(false)]
+        public void Write (ulong number)
+        {
+            DoValidation (Condition.Value);
+            PutNewline ();
+
+            Put (Convert.ToString (number, number_format));
+
+            context.ExpectingValue = false;
+        }
+
+        public void WriteArrayEnd ()
+        {
+            DoValidation (Condition.InArray);
+            PutNewline (false);
+
+            ctx_stack.Pop ();
+            if (ctx_stack.Count == 1)
+                has_reached_end = true;
+            else {
+                context = ctx_stack.Peek ();
+                context.ExpectingValue = false;
+            }
+
+            Unindent ();
+            Put ("]");
+        }
+
+        public void WriteArrayStart ()
+        {
+            DoValidation (Condition.NotAProperty);
+            PutNewline ();
+
+            Put ("[");
+
+            context = new WriterContext ();
+            context.InArray = true;
+            ctx_stack.Push (context);
+
+            Indent ();
+        }
+
+        public void WriteObjectEnd ()
+        {
+            DoValidation (Condition.InObject);
+            PutNewline (false);
+
+            ctx_stack.Pop ();
+            if (ctx_stack.Count == 1)
+                has_reached_end = true;
+            else {
+                context = ctx_stack.Peek ();
+                context.ExpectingValue = false;
+            }
+
+            Unindent ();
+            Put ("}");
+        }
+
+        public void WriteObjectStart ()
+        {
+            DoValidation (Condition.NotAProperty);
+            PutNewline ();
+
+            Put ("{");
+
+            context = new WriterContext ();
+            context.InObject = true;
+            ctx_stack.Push (context);
+
+            Indent ();
+        }
+
+        public void WritePropertyName (string property_name)
+        {
+            DoValidation (Condition.Property);
+            PutNewline ();
+            string propertyName = (property_name == null || !lower_case_properties)
+                ? property_name
+                : property_name.ToLowerInvariant();
+
+            PutString (propertyName);
+
+            if (pretty_print) {
+                if (propertyName.Length > context.Padding)
+                    context.Padding = propertyName.Length;
+
+                for (int i = context.Padding - propertyName.Length;
+                     i >= 0; i--)
+                    writer.Write (' ');
+
+                writer.Write (": ");
+            } else
+                writer.Write (':');
+
+            context.ExpectingValue = true;
+        }
+    }
+}
diff --git a/Main/Common/LitJson/JsonWriter.cs.meta b/Main/Common/LitJson/JsonWriter.cs.meta
new file mode 100644
index 0000000..feb35a1
--- /dev/null
+++ b/Main/Common/LitJson/JsonWriter.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7ef909f080345c44a8305ebd799ba7ce
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Common/LitJson/Lexer.cs b/Main/Common/LitJson/Lexer.cs
new file mode 100644
index 0000000..cb62d55
--- /dev/null
+++ b/Main/Common/LitJson/Lexer.cs
@@ -0,0 +1,912 @@
+#region Header
+/**
+ * Lexer.cs
+ *   JSON lexer implementation based on a finite state machine.
+ *
+ * The authors disclaim copyright to this source code. For more details, see
+ * the COPYING file included with this distribution.
+ **/
+#endregion
+
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+
+namespace LitJson
+{
+    internal class FsmContext
+    {
+        public bool  Return;
+        public int   NextState;
+        public Lexer L;
+        public int   StateStack;
+    }
+
+
+    internal class Lexer
+    {
+        #region Fields
+        private delegate bool StateHandler (FsmContext ctx);
+
+        private static readonly int[]          fsm_return_table;
+        private static readonly StateHandler[] fsm_handler_table;
+
+        private bool          allow_comments;
+        private bool          allow_single_quoted_strings;
+        private bool          end_of_input;
+        private FsmContext    fsm_context;
+        private int           input_buffer;
+        private int           input_char;
+        private TextReader    reader;
+        private int           state;
+        private StringBuilder string_buffer;
+        private string        string_value;
+        private int           token;
+        private int           unichar;
+        #endregion
+
+
+        #region Properties
+        public bool AllowComments {
+            get { return allow_comments; }
+            set { allow_comments = value; }
+        }
+
+        public bool AllowSingleQuotedStrings {
+            get { return allow_single_quoted_strings; }
+            set { allow_single_quoted_strings = value; }
+        }
+
+        public bool EndOfInput {
+            get { return end_of_input; }
+        }
+
+        public int Token {
+            get { return token; }
+        }
+
+        public string StringValue {
+            get { return string_value; }
+        }
+        #endregion
+
+
+        #region Constructors
+        static Lexer ()
+        {
+            PopulateFsmTables (out fsm_handler_table, out fsm_return_table);
+        }
+
+        public Lexer (TextReader reader)
+        {
+            allow_comments = true;
+            allow_single_quoted_strings = true;
+
+            input_buffer = 0;
+            string_buffer = new StringBuilder (128);
+            state = 1;
+            end_of_input = false;
+            this.reader = reader;
+
+            fsm_context = new FsmContext ();
+            fsm_context.L = this;
+        }
+        #endregion
+
+
+        #region Static Methods
+        private static int HexValue (int digit)
+        {
+            switch (digit) {
+            case 'a':
+            case 'A':
+                return 10;
+
+            case 'b':
+            case 'B':
+                return 11;
+
+            case 'c':
+            case 'C':
+                return 12;
+
+            case 'd':
+            case 'D':
+                return 13;
+
+            case 'e':
+            case 'E':
+                return 14;
+
+            case 'f':
+            case 'F':
+                return 15;
+
+            default:
+                return digit - '0';
+            }
+        }
+
+        private static void PopulateFsmTables (out StateHandler[] fsm_handler_table, out int[] fsm_return_table)
+        {
+            // See section A.1. of the manual for details of the finite
+            // state machine.
+            fsm_handler_table = new StateHandler[28] {
+                State1,
+                State2,
+                State3,
+                State4,
+                State5,
+                State6,
+                State7,
+                State8,
+                State9,
+                State10,
+                State11,
+                State12,
+                State13,
+                State14,
+                State15,
+                State16,
+                State17,
+                State18,
+                State19,
+                State20,
+                State21,
+                State22,
+                State23,
+                State24,
+                State25,
+                State26,
+                State27,
+                State28
+            };
+
+            fsm_return_table = new int[28] {
+                (int) ParserToken.Char,
+                0,
+                (int) ParserToken.Number,
+                (int) ParserToken.Number,
+                0,
+                (int) ParserToken.Number,
+                0,
+                (int) ParserToken.Number,
+                0,
+                0,
+                (int) ParserToken.True,
+                0,
+                0,
+                0,
+                (int) ParserToken.False,
+                0,
+                0,
+                (int) ParserToken.Null,
+                (int) ParserToken.CharSeq,
+                (int) ParserToken.Char,
+                0,
+                0,
+                (int) ParserToken.CharSeq,
+                (int) ParserToken.Char,
+                0,
+                0,
+                0,
+                0
+            };
+        }
+
+        private static char ProcessEscChar (int esc_char)
+        {
+            switch (esc_char) {
+            case '"':
+            case '\'':
+            case '\\':
+            case '/':
+                return Convert.ToChar (esc_char);
+
+            case 'n':
+                return '\n';
+
+            case 't':
+                return '\t';
+
+            case 'r':
+                return '\r';
+
+            case 'b':
+                return '\b';
+
+            case 'f':
+                return '\f';
+
+            default:
+                // Unreachable
+                return '?';
+            }
+        }
+
+        private static bool State1 (FsmContext ctx)
+        {
+            while (ctx.L.GetChar ()) {
+                if (ctx.L.input_char == ' ' ||
+                    ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r')
+                    continue;
+
+                if (ctx.L.input_char >= '1' && ctx.L.input_char <= '9') {
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    ctx.NextState = 3;
+                    return true;
+                }
+
+                switch (ctx.L.input_char) {
+                case '"':
+                    ctx.NextState = 19;
+                    ctx.Return = true;
+                    return true;
+
+                case ',':
+                case ':':
+                case '[':
+                case ']':
+                case '{':
+                case '}':
+                    ctx.NextState = 1;
+                    ctx.Return = true;
+                    return true;
+
+                case '-':
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    ctx.NextState = 2;
+                    return true;
+
+                case '0':
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    ctx.NextState = 4;
+                    return true;
+
+                case 'f':
+                    ctx.NextState = 12;
+                    return true;
+
+                case 'n':
+                    ctx.NextState = 16;
+                    return true;
+
+                case 't':
+                    ctx.NextState = 9;
+                    return true;
+
+                case '\'':
+                    if (! ctx.L.allow_single_quoted_strings)
+                        return false;
+
+                    ctx.L.input_char = '"';
+                    ctx.NextState = 23;
+                    ctx.Return = true;
+                    return true;
+
+                case '/':
+                    if (! ctx.L.allow_comments)
+                        return false;
+
+                    ctx.NextState = 25;
+                    return true;
+
+                default:
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        private static bool State2 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            if (ctx.L.input_char >= '1' && ctx.L.input_char<= '9') {
+                ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                ctx.NextState = 3;
+                return true;
+            }
+
+            switch (ctx.L.input_char) {
+            case '0':
+                ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                ctx.NextState = 4;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State3 (FsmContext ctx)
+        {
+            while (ctx.L.GetChar ()) {
+                if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') {
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    continue;
+                }
+
+                if (ctx.L.input_char == ' ' ||
+                    ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') {
+                    ctx.Return = true;
+                    ctx.NextState = 1;
+                    return true;
+                }
+
+                switch (ctx.L.input_char) {
+                case ',':
+                case ']':
+                case '}':
+                    ctx.L.UngetChar ();
+                    ctx.Return = true;
+                    ctx.NextState = 1;
+                    return true;
+
+                case '.':
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    ctx.NextState = 5;
+                    return true;
+
+                case 'e':
+                case 'E':
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    ctx.NextState = 7;
+                    return true;
+
+                default:
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        private static bool State4 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            if (ctx.L.input_char == ' ' ||
+                ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') {
+                ctx.Return = true;
+                ctx.NextState = 1;
+                return true;
+            }
+
+            switch (ctx.L.input_char) {
+            case ',':
+            case ']':
+            case '}':
+                ctx.L.UngetChar ();
+                ctx.Return = true;
+                ctx.NextState = 1;
+                return true;
+
+            case '.':
+                ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                ctx.NextState = 5;
+                return true;
+
+            case 'e':
+            case 'E':
+                ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                ctx.NextState = 7;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State5 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') {
+                ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                ctx.NextState = 6;
+                return true;
+            }
+
+            return false;
+        }
+
+        private static bool State6 (FsmContext ctx)
+        {
+            while (ctx.L.GetChar ()) {
+                if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') {
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    continue;
+                }
+
+                if (ctx.L.input_char == ' ' ||
+                    ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') {
+                    ctx.Return = true;
+                    ctx.NextState = 1;
+                    return true;
+                }
+
+                switch (ctx.L.input_char) {
+                case ',':
+                case ']':
+                case '}':
+                    ctx.L.UngetChar ();
+                    ctx.Return = true;
+                    ctx.NextState = 1;
+                    return true;
+
+                case 'e':
+                case 'E':
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    ctx.NextState = 7;
+                    return true;
+
+                default:
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        private static bool State7 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            if (ctx.L.input_char >= '0' && ctx.L.input_char<= '9') {
+                ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                ctx.NextState = 8;
+                return true;
+            }
+
+            switch (ctx.L.input_char) {
+            case '+':
+            case '-':
+                ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                ctx.NextState = 8;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State8 (FsmContext ctx)
+        {
+            while (ctx.L.GetChar ()) {
+                if (ctx.L.input_char >= '0' && ctx.L.input_char<= '9') {
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    continue;
+                }
+
+                if (ctx.L.input_char == ' ' ||
+                    ctx.L.input_char >= '\t' && ctx.L.input_char<= '\r') {
+                    ctx.Return = true;
+                    ctx.NextState = 1;
+                    return true;
+                }
+
+                switch (ctx.L.input_char) {
+                case ',':
+                case ']':
+                case '}':
+                    ctx.L.UngetChar ();
+                    ctx.Return = true;
+                    ctx.NextState = 1;
+                    return true;
+
+                default:
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        private static bool State9 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'r':
+                ctx.NextState = 10;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State10 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'u':
+                ctx.NextState = 11;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State11 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'e':
+                ctx.Return = true;
+                ctx.NextState = 1;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State12 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'a':
+                ctx.NextState = 13;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State13 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'l':
+                ctx.NextState = 14;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State14 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 's':
+                ctx.NextState = 15;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State15 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'e':
+                ctx.Return = true;
+                ctx.NextState = 1;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State16 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'u':
+                ctx.NextState = 17;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State17 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'l':
+                ctx.NextState = 18;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State18 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'l':
+                ctx.Return = true;
+                ctx.NextState = 1;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State19 (FsmContext ctx)
+        {
+            while (ctx.L.GetChar ()) {
+                switch (ctx.L.input_char) {
+                case '"':
+                    ctx.L.UngetChar ();
+                    ctx.Return = true;
+                    ctx.NextState = 20;
+                    return true;
+
+                case '\\':
+                    ctx.StateStack = 19;
+                    ctx.NextState = 21;
+                    return true;
+
+                default:
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    continue;
+                }
+            }
+
+            return true;
+        }
+
+        private static bool State20 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case '"':
+                ctx.Return = true;
+                ctx.NextState = 1;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State21 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'u':
+                ctx.NextState = 22;
+                return true;
+
+            case '"':
+            case '\'':
+            case '/':
+            case '\\':
+            case 'b':
+            case 'f':
+            case 'n':
+            case 'r':
+            case 't':
+                ctx.L.string_buffer.Append (
+                    ProcessEscChar (ctx.L.input_char));
+                ctx.NextState = ctx.StateStack;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State22 (FsmContext ctx)
+        {
+            int counter = 0;
+            int mult    = 4096;
+
+            ctx.L.unichar = 0;
+
+            while (ctx.L.GetChar ()) {
+
+                if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9' ||
+                    ctx.L.input_char >= 'A' && ctx.L.input_char <= 'F' ||
+                    ctx.L.input_char >= 'a' && ctx.L.input_char <= 'f') {
+
+                    ctx.L.unichar += HexValue (ctx.L.input_char) * mult;
+
+                    counter++;
+                    mult /= 16;
+
+                    if (counter == 4) {
+                        ctx.L.string_buffer.Append (
+                            Convert.ToChar (ctx.L.unichar));
+                        ctx.NextState = ctx.StateStack;
+                        return true;
+                    }
+
+                    continue;
+                }
+
+                return false;
+            }
+
+            return true;
+        }
+
+        private static bool State23 (FsmContext ctx)
+        {
+            while (ctx.L.GetChar ()) {
+                switch (ctx.L.input_char) {
+                case '\'':
+                    ctx.L.UngetChar ();
+                    ctx.Return = true;
+                    ctx.NextState = 24;
+                    return true;
+
+                case '\\':
+                    ctx.StateStack = 23;
+                    ctx.NextState = 21;
+                    return true;
+
+                default:
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    continue;
+                }
+            }
+
+            return true;
+        }
+
+        private static bool State24 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case '\'':
+                ctx.L.input_char = '"';
+                ctx.Return = true;
+                ctx.NextState = 1;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State25 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case '*':
+                ctx.NextState = 27;
+                return true;
+
+            case '/':
+                ctx.NextState = 26;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State26 (FsmContext ctx)
+        {
+            while (ctx.L.GetChar ()) {
+                if (ctx.L.input_char == '\n') {
+                    ctx.NextState = 1;
+                    return true;
+                }
+            }
+
+            return true;
+        }
+
+        private static bool State27 (FsmContext ctx)
+        {
+            while (ctx.L.GetChar ()) {
+                if (ctx.L.input_char == '*') {
+                    ctx.NextState = 28;
+                    return true;
+                }
+            }
+
+            return true;
+        }
+
+        private static bool State28 (FsmContext ctx)
+        {
+            while (ctx.L.GetChar ()) {
+                if (ctx.L.input_char == '*')
+                    continue;
+
+                if (ctx.L.input_char == '/') {
+                    ctx.NextState = 1;
+                    return true;
+                }
+
+                ctx.NextState = 27;
+                return true;
+            }
+
+            return true;
+        }
+        #endregion
+
+
+        private bool GetChar ()
+        {
+            if ((input_char = NextChar ()) != -1)
+                return true;
+
+            end_of_input = true;
+            return false;
+        }
+
+        private int NextChar ()
+        {
+            if (input_buffer != 0) {
+                int tmp = input_buffer;
+                input_buffer = 0;
+
+                return tmp;
+            }
+
+            return reader.Read ();
+        }
+
+        public bool NextToken ()
+        {
+            StateHandler handler;
+            fsm_context.Return = false;
+
+            while (true) {
+                handler = fsm_handler_table[state - 1];
+
+                if (! handler (fsm_context))
+                    throw new JsonException (input_char);
+
+                if (end_of_input)
+                    return false;
+
+                if (fsm_context.Return) {
+                    string_value = string_buffer.ToString ();
+                    string_buffer.Remove (0, string_buffer.Length);
+                    token = fsm_return_table[state - 1];
+
+                    if (token == (int) ParserToken.Char)
+                        token = input_char;
+
+                    state = fsm_context.NextState;
+
+                    return true;
+                }
+
+                state = fsm_context.NextState;
+            }
+        }
+
+        private void UngetChar ()
+        {
+            input_buffer = input_char;
+        }
+    }
+}
diff --git a/Main/Common/LitJson/Lexer.cs.meta b/Main/Common/LitJson/Lexer.cs.meta
new file mode 100644
index 0000000..357faad
--- /dev/null
+++ b/Main/Common/LitJson/Lexer.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: cc76231e1fd6e994b9c978577dd26c0b
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Common/LitJson/Netstandard15Polyfill.cs b/Main/Common/LitJson/Netstandard15Polyfill.cs
new file mode 100644
index 0000000..55b02a2
--- /dev/null
+++ b/Main/Common/LitJson/Netstandard15Polyfill.cs
@@ -0,0 +1,24 @@
+#if NETSTANDARD1_5
+using System;
+using System.Reflection;
+namespace LitJson
+{
+    internal static class Netstandard15Polyfill
+    {
+        internal static Type GetInterface(this Type type, string name)
+        {
+            return type.GetTypeInfo().GetInterface(name); 
+        }
+
+        internal static bool IsClass(this Type type)
+        {
+            return type.GetTypeInfo().IsClass;
+        }
+
+        internal static bool IsEnum(this Type type)
+        {
+            return type.GetTypeInfo().IsEnum;
+        }
+    }
+}
+#endif
\ No newline at end of file
diff --git a/Main/Common/LitJson/Netstandard15Polyfill.cs.meta b/Main/Common/LitJson/Netstandard15Polyfill.cs.meta
new file mode 100644
index 0000000..a03a2ca
--- /dev/null
+++ b/Main/Common/LitJson/Netstandard15Polyfill.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7b5650e72413e15478074fd1672dbbfc
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Common/LitJson/ParserToken.cs b/Main/Common/LitJson/ParserToken.cs
new file mode 100644
index 0000000..e23d477
--- /dev/null
+++ b/Main/Common/LitJson/ParserToken.cs
@@ -0,0 +1,44 @@
+#region Header
+/**
+ * ParserToken.cs
+ *   Internal representation of the tokens used by the lexer and the parser.
+ *
+ * The authors disclaim copyright to this source code. For more details, see
+ * the COPYING file included with this distribution.
+ **/
+#endregion
+
+
+namespace LitJson
+{
+    internal enum ParserToken
+    {
+        // Lexer tokens (see section A.1.1. of the manual)
+        None = System.Char.MaxValue + 1,
+        Number,
+        True,
+        False,
+        Null,
+        CharSeq,
+        // Single char
+        Char,
+
+        // Parser Rules (see section A.2.1 of the manual)
+        Text,
+        Object,
+        ObjectPrime,
+        Pair,
+        PairRest,
+        Array,
+        ArrayPrime,
+        Value,
+        ValueRest,
+        String,
+
+        // End of input
+        End,
+
+        // The empty rule
+        Epsilon
+    }
+}
diff --git a/Main/Common/LitJson/ParserToken.cs.meta b/Main/Common/LitJson/ParserToken.cs.meta
new file mode 100644
index 0000000..ba77ef9
--- /dev/null
+++ b/Main/Common/LitJson/ParserToken.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f20c9771c3db31240b02dcb1de323d48
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Extensions.meta b/Main/Extensions.meta
new file mode 100644
index 0000000..b03a07b
--- /dev/null
+++ b/Main/Extensions.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: c8b5029bcc3e1ae4f8ef4fe0786d47a7
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Extensions/DOTweenExtensions.cs b/Main/Extensions/DOTweenExtensions.cs
new file mode 100644
index 0000000..e759c48
--- /dev/null
+++ b/Main/Extensions/DOTweenExtensions.cs
@@ -0,0 +1,45 @@
+using UnityEngine;
+using UnityEngine.UI;
+using DG.Tweening;
+
+/// <summary>
+/// DOTween 鎵╁睍鏂规硶锛屼负涓嶅悓缁勪欢鎻愪緵鍔ㄧ敾鍔熻兘
+/// </summary>
+public static class DOTweenExtensions
+{
+    /// <summary>
+    /// 涓� CanvasGroup 鎻愪緵娣″叆娣″嚭鍔ㄧ敾
+    /// </summary>
+    /// <param name="target">鐩爣 CanvasGroup</param>
+    /// <param name="endValue">鐩爣閫忔槑搴﹀�� (0-1)</param>
+    /// <param name="duration">鍔ㄧ敾鎸佺画鏃堕棿</param>
+    /// <returns>Tweener 瀹炰緥</returns>
+    public static Tweener DOFade(this CanvasGroup target, float endValue, float duration)
+    {
+        return DOTween.To(() => target.alpha, x => target.alpha = x, endValue, duration);
+    }
+
+    /// <summary>
+    /// 涓� RectTransform 鎻愪緵绉诲姩鍔ㄧ敾
+    /// </summary>
+    /// <param name="target">鐩爣 RectTransform</param>
+    /// <param name="endValue">鐩爣浣嶇疆</param>
+    /// <param name="duration">鍔ㄧ敾鎸佺画鏃堕棿</param>
+    /// <returns>Tweener 瀹炰緥</returns>
+    public static Tweener DOAnchorPos(this RectTransform target, Vector2 endValue, float duration)
+    {
+        return DOTween.To(() => target.anchoredPosition, x => target.anchoredPosition = x, endValue, duration);
+    }
+
+    /// <summary>
+    /// 涓� Transform 鎻愪緵缂╂斁鍔ㄧ敾
+    /// </summary>
+    /// <param name="target">鐩爣 Transform</param>
+    /// <param name="endValue">鐩爣缂╂斁鍊�</param>
+    /// <param name="duration">鍔ㄧ敾鎸佺画鏃堕棿</param>
+    /// <returns>Tweener 瀹炰緥</returns>
+    public static Tweener DOScale(this Transform target, Vector3 endValue, float duration)
+    {
+        return DOTween.To(() => target.localScale, x => target.localScale = x, endValue, duration);
+    }
+}
\ No newline at end of file
diff --git a/Main/Extensions/DOTweenExtensions.cs.meta b/Main/Extensions/DOTweenExtensions.cs.meta
new file mode 100644
index 0000000..e236516
--- /dev/null
+++ b/Main/Extensions/DOTweenExtensions.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0e89b51ad990b594da7083af980fc740
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Main.asmdef b/Main/Main.asmdef
new file mode 100644
index 0000000..bc3c97a
--- /dev/null
+++ b/Main/Main.asmdef
@@ -0,0 +1,18 @@
+{
+    "name": "Main",
+    "rootNamespace": "",
+    "references": [
+        "GUID:3ffa07c58a98b0445a7a34376b165fd1",
+        "GUID:4129704b5a1a13841ba16f230bf24a57",
+        "GUID:f51ebe6a0ceec4240a699833d6309b23"
+    ],
+    "includePlatforms": [],
+    "excludePlatforms": [],
+    "allowUnsafeCode": false,
+    "overrideReferences": false,
+    "precompiledReferences": [],
+    "autoReferenced": true,
+    "defineConstraints": [],
+    "versionDefines": [],
+    "noEngineReferences": false
+}
\ No newline at end of file
diff --git a/Main/Main.asmdef.meta b/Main/Main.asmdef.meta
new file mode 100644
index 0000000..be2d720
--- /dev/null
+++ b/Main/Main.asmdef.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: eac12500b66aea340bf118070ac14bec
+AssemblyDefinitionImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Main.cs b/Main/Main.cs
new file mode 100644
index 0000000..981ab79
--- /dev/null
+++ b/Main/Main.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using Cysharp.Threading;
+using Cysharp.Threading.Tasks;
+
+/// <summary>
+/// Main绫伙紝浣滀负鐑洿鏂扮▼搴忛泦鐨勫叆鍙g偣
+/// </summary>
+public class Main
+{
+    /// <summary>
+    /// 鍒濆鍖栧嚱鏁帮紝鐢盠aunch绫昏皟鐢�
+    /// </summary>
+    public static void Init()
+    {
+        Debug.Log("Main.Init() 琚皟鐢�");
+        // 1. 鍒濆鍖栨父鎴忕郴缁�
+        InitializeGameSystems();
+        
+        // 2. 鍔犺浇閰嶇疆
+        LoadConfigurations();
+        
+        // 3. 鎵撳紑鐧诲綍鐣岄潰
+        OpenLoginUI();
+    }
+    
+    
+    /// <summary>
+    /// 鍒濆鍖栨父鎴忕郴缁�
+    /// </summary>
+    private static void InitializeGameSystems()
+    {
+        Debug.Log("鍒濆鍖栨父鎴忕郴缁�");
+        
+        // 杩欓噷鍙互鍒濆鍖栧悇绉嶆父鎴忕郴缁燂紝濡傝祫婧愮鐞嗐�乁I绠$悊銆侀煶棰戠鐞嗙瓑
+        
+    }
+    
+    /// <summary>
+    /// 鍔犺浇閰嶇疆
+    /// </summary>
+    private static void LoadConfigurations()
+    {
+        Debug.Log("鍔犺浇娓告垙閰嶇疆");
+        
+        // 杩欓噷鍙互鍔犺浇娓告垙閰嶇疆锛屽娓告垙鍙傛暟銆佽〃鏍兼暟鎹瓑
+        
+    }
+    
+    /// <summary>
+    /// 鎵撳紑鐧诲綍鐣岄潰
+    /// </summary>
+    private static void OpenLoginUI()
+    {
+        Debug.Log("鍏抽棴鍔犺浇鐣岄潰");
+
+        LaunchLoadingWin.Instance.CloseWindow();
+
+        Debug.Log("鎵撳紑鐧诲綍鐣岄潰");
+        
+        // 鑾峰彇Launch涓殑IsUseSDK鏍囧織
+        bool isUseSDK = Launch.Instance.IsUseSDK;
+        
+        // 鏍规嵁IsUseSDK鏍囧織鏄剧ず涓嶅悓鐨勭櫥褰曠晫闈�
+        if (isUseSDK)
+        {
+            Debug.Log("鏄剧ずSDK鐧诲綍鐣岄潰");
+            // 鍦ㄨ繖閲屽疄鐜癝DK鐧诲綍鐣岄潰鐨勬樉绀洪�昏緫
+            // 渚嬪锛歎IManager.Instance.OpenUI("SDKLoginUI");
+        }
+        else
+        {
+            Debug.Log("鏄剧ず鏅�氱櫥褰曠晫闈�");
+            // 鍦ㄨ繖閲屽疄鐜版櫘閫氱櫥褰曠晫闈㈢殑鏄剧ず閫昏緫
+            // 渚嬪锛歎IManager.Instance.OpenUI("NormalLoginUI");
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/Main.cs.meta b/Main/Main.cs.meta
new file mode 100644
index 0000000..e5ff7aa
--- /dev/null
+++ b/Main/Main.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 17a7465a9ee75c042b0a45aa823fdc70
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/UI.meta b/Main/UI.meta
new file mode 100644
index 0000000..ced7062
--- /dev/null
+++ b/Main/UI.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 723c0b1daebf8d34eac4b16d94dd88bb
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/UI/UIBase.cs b/Main/UI/UIBase.cs
new file mode 100644
index 0000000..84e3717
--- /dev/null
+++ b/Main/UI/UIBase.cs
@@ -0,0 +1,590 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using DG.Tweening; // DOTween 鎻掍欢寮曠敤
+
+public enum UILayer
+{
+    Static, // 闈欐�乁I 閫傚悎鍋� 甯搁┗鐢ㄧ殑濡� 涓荤晫闈�
+    Bottom, // 鏈�搴曞眰 閫傚悎鍋� 涓荤晫闈笂闈㈢殑 涓�绾х獥鍙� 涓�绾х晫闈�
+    Mid,    // 閫傚悎鍋� 浜岀骇绐楀彛 浜岀骇鐣岄潰
+    Top,    // 閫傚悎鍋氭彁绀哄脊绐�
+    System  // 缃戠粶寮圭獥/鍏朵粬閲嶈寮圭獥/绯荤粺鍏憡
+}
+
+public enum UIAnimationType
+{
+    None,       // 鏃犲姩鐢�
+    FadeInOut,  // 娣″叆娣″嚭
+    ScaleInOut, // 缂╂斁
+    SlideFromTop, // 浠庨《閮ㄦ粦鍏�
+    SlideFromBottom, // 浠庡簳閮ㄦ粦鍏�
+    SlideFromLeft, // 浠庡乏渚ф粦鍏�
+    SlideFromRight // 浠庡彸渚ф粦鍏�
+}
+
+public class UIBase : MonoBehaviour
+{
+    #region 灞炴�у拰鍙橀噺
+
+    // UI鍩烘湰灞炴��
+    [SerializeField] public UILayer uiLayer = UILayer.Mid;
+    [SerializeField] public string uiName;
+    [SerializeField] public bool isMainUI = false;
+    
+    // 鎸佷箙鍖栫浉鍏�
+    [SerializeField] public bool isPersistent = false;
+    [SerializeField] public int maxIdleRounds = 20;
+    
+    // 鍔ㄧ敾鐩稿叧
+    [SerializeField] public UIAnimationType openAnimationType = UIAnimationType.FadeInOut;
+    [SerializeField] public UIAnimationType closeAnimationType = UIAnimationType.FadeInOut;
+    [SerializeField] public float animationDuration = 0.3f;
+    [SerializeField] public Ease animationEase = Ease.OutQuad; // 纭繚浣跨敤 DG.Tweening.Ease
+    
+    // 杩愯鏃剁姸鎬�
+    [HideInInspector] public int lastUsedRound = 0;
+    [HideInInspector] public UIBase parentUI;
+    
+    // 瀛怳I绠$悊
+    [HideInInspector] public List<UIBase> childrenUI = new List<UIBase>();
+    
+    // 鍐呴儴鐘舵��
+    protected bool isActive = false;
+    protected bool isAnimating = false;
+    
+    // 缁勪欢寮曠敤
+    protected Canvas canvas;
+    protected CanvasGroup canvasGroup;
+    protected RectTransform rectTransform;
+    
+    // 鍔ㄧ敾鐩稿叧
+    protected Vector3 originalScale;
+    protected Vector3 originalPosition;
+    protected Sequence currentAnimation;
+
+    #endregion
+
+    #region Unity鐢熷懡鍛ㄦ湡
+
+    protected virtual void Awake()
+    {
+        // 纭繚 DOTween 宸插垵濮嬪寲
+        DOTween.SetTweensCapacity(500, 50);
+        
+        // 鍦ˋwake涓繘琛屽熀鏈垵濮嬪寲
+        InitComponent();
+        
+        // 淇濆瓨鍘熷鍊肩敤浜庡姩鐢�
+        if (rectTransform != null)
+        {
+            originalScale = rectTransform.localScale;
+            originalPosition = rectTransform.anchoredPosition;
+        }
+    }
+
+    protected virtual void Start()
+    {
+        // 瀛愮被鍙互閲嶅啓姝ゆ柟娉曡繘琛岄澶栧垵濮嬪寲
+    }
+    
+    protected virtual void OnDestroy()
+    {
+        // 纭繚鍔ㄧ敾琚纭竻鐞�
+        if (currentAnimation != null)
+        {
+            currentAnimation.Kill();
+            currentAnimation = null;
+        }
+    }
+
+    #endregion
+
+    #region 鍒濆鍖栨柟娉�
+
+    // 鑾峰彇蹇呰鐨勭粍浠�
+    protected virtual void InitComponent()
+    {
+        // 鑾峰彇鎴栨坊鍔燙anvas缁勪欢
+        canvas = GetComponent<Canvas>();
+        if (canvas == null)
+        {
+            canvas = gameObject.AddComponent<Canvas>();
+        }
+        
+        // 璁剧疆Canvas灞炴��
+        canvas.overrideSorting = true;
+        
+        // 鑾峰彇鎴栨坊鍔燙anvasGroup缁勪欢
+        canvasGroup = GetComponent<CanvasGroup>();
+        if (canvasGroup == null)
+        {
+            canvasGroup = gameObject.AddComponent<CanvasGroup>();
+        }
+        
+        // 娣诲姞GraphicRaycaster缁勪欢锛堝鏋滄病鏈夛級
+        if (GetComponent<UnityEngine.UI.GraphicRaycaster>() == null)
+        {
+            gameObject.AddComponent<UnityEngine.UI.GraphicRaycaster>();
+        }
+        
+        // 鑾峰彇RectTransform缁勪欢
+        rectTransform = GetComponent<RectTransform>();
+    }
+    
+    // 鍒濆鍖朥I
+    public virtual void Init()
+    {
+        // 纭繚缁勪欢宸插垵濮嬪寲
+        InitComponent();
+    }
+
+    #endregion
+
+    #region UI鎿嶄綔鏂规硶
+
+    // 璁剧疆UI灞傜骇
+    public void SetSortingOrder(int order)
+    {
+        if (canvas != null)
+        {
+            canvas.sortingOrder = order;
+        }
+    }
+    
+    // 鎵撳紑UI
+    public virtual void Open()
+    {
+        // 濡傛灉姝e湪鎾斁鍔ㄧ敾锛屽厛鍋滄
+        StopCurrentAnimation();
+        
+        gameObject.SetActive(true);
+        
+        // 鏍规嵁鍔ㄧ敾绫诲瀷鎾斁鎵撳紑鍔ㄧ敾
+        PlayOpenAnimation();
+        
+        isActive = true;
+        OnOpen();
+    }
+    
+    // 鍏抽棴UI
+    public virtual void Close()
+    {
+        // 濡傛灉姝e湪鎾斁鍔ㄧ敾锛屽厛鍋滄
+        StopCurrentAnimation();
+        
+        // 鏍规嵁鍔ㄧ敾绫诲瀷鎾斁鍏抽棴鍔ㄧ敾
+        PlayCloseAnimation();
+        
+        isActive = false;
+        OnClose();
+        
+        // 鍏抽棴鎵�鏈夊瓙UI
+        for (int i = childrenUI.Count - 1; i >= 0; i--)
+        {
+            if (childrenUI[i] != null && childrenUI[i].isActive)
+            {
+                childrenUI[i].Close();
+            }
+        }
+    }
+    
+    // 鍒锋柊UI
+    public virtual void Refresh()
+    {
+        // 瀛愮被鍙互閲嶅啓姝ゆ柟娉曞疄鐜癠I鍒锋柊閫昏緫
+    }
+    
+    // 閿�姣乁I
+    public virtual void Destroy()
+    {
+        // 鍋滄鎵�鏈夊姩鐢�
+        StopCurrentAnimation();
+        
+        ClearChildrenUI();
+        
+        if (parentUI != null)
+        {
+            parentUI.RemoveChildUI(this);
+        }
+        
+        Destroy(gameObject);
+    }
+
+    #endregion
+
+    #region 鍔ㄧ敾鏂规硶
+
+    // 鍋滄褰撳墠姝e湪鎾斁鐨勫姩鐢�
+    protected void StopCurrentAnimation()
+    {
+        if (currentAnimation != null && currentAnimation.IsActive() && !currentAnimation.IsComplete())
+        {
+            currentAnimation.Kill(false); // 涓嶈瀹屾垚鍔ㄧ敾锛岀洿鎺ュ仠姝�
+            currentAnimation = null;
+        }
+        isAnimating = false;
+    }
+    
+    // 鎾斁鎵撳紑鍔ㄧ敾
+    protected virtual void PlayOpenAnimation()
+    {
+        if (openAnimationType == UIAnimationType.None)
+        {
+            // 鏃犲姩鐢伙紝鐩存帴鍚敤浜や簰
+            if (canvasGroup != null)
+            {
+                canvasGroup.alpha = 1f;
+                canvasGroup.interactable = true;
+                canvasGroup.blocksRaycasts = true;
+            }
+            return;
+        }
+        
+        isAnimating = true;
+        
+        // 鍒濆鍖栧姩鐢诲墠鐨勭姸鎬�
+        switch (openAnimationType)
+        {
+            case UIAnimationType.FadeInOut:
+                if (canvasGroup != null)
+                {
+                    canvasGroup.alpha = 0f;
+                    canvasGroup.interactable = false;
+                    canvasGroup.blocksRaycasts = false;
+                }
+                break;
+                
+            case UIAnimationType.ScaleInOut:
+                if (rectTransform != null)
+                {
+                    rectTransform.localScale = Vector3.zero;
+                }
+                if (canvasGroup != null)
+                {
+                    canvasGroup.alpha = 0f;
+                    canvasGroup.interactable = false;
+                    canvasGroup.blocksRaycasts = false;
+                }
+                break;
+                
+            case UIAnimationType.SlideFromTop:
+                if (rectTransform != null)
+                {
+                    Vector2 startPos = originalPosition;
+                    startPos.y = Screen.height;
+                    rectTransform.anchoredPosition = startPos;
+                }
+                if (canvasGroup != null)
+                {
+                    canvasGroup.alpha = 0f;
+                    canvasGroup.interactable = false;
+                    canvasGroup.blocksRaycasts = false;
+                }
+                break;
+                
+            case UIAnimationType.SlideFromBottom:
+                if (rectTransform != null)
+                {
+                    Vector2 startPos = originalPosition;
+                    startPos.y = -Screen.height;
+                    rectTransform.anchoredPosition = startPos;
+                }
+                if (canvasGroup != null)
+                {
+                    canvasGroup.alpha = 0f;
+                    canvasGroup.interactable = false;
+                    canvasGroup.blocksRaycasts = false;
+                }
+                break;
+                
+            case UIAnimationType.SlideFromLeft:
+                if (rectTransform != null)
+                {
+                    Vector2 startPos = originalPosition;
+                    startPos.x = -Screen.width;
+                    rectTransform.anchoredPosition = startPos;
+                }
+                if (canvasGroup != null)
+                {
+                    canvasGroup.alpha = 0f;
+                    canvasGroup.interactable = false;
+                    canvasGroup.blocksRaycasts = false;
+                }
+                break;
+                
+            case UIAnimationType.SlideFromRight:
+                if (rectTransform != null)
+                {
+                    Vector2 startPos = originalPosition;
+                    startPos.x = Screen.width;
+                    rectTransform.anchoredPosition = startPos;
+                }
+                if (canvasGroup != null)
+                {
+                    canvasGroup.alpha = 0f;
+                    canvasGroup.interactable = false;
+                    canvasGroup.blocksRaycasts = false;
+                }
+                break;
+        }
+        
+        try
+        {
+            // 鍒涘缓鍔ㄧ敾搴忓垪
+            currentAnimation = DOTween.Sequence();
+            
+            // 娣诲姞鍔ㄧ敾
+            switch (openAnimationType)
+            {
+                case UIAnimationType.FadeInOut:
+                    if (canvasGroup != null)
+                    {
+                        currentAnimation.Append(canvasGroup.DOFade(1f, animationDuration).SetEase(animationEase));
+                    }
+                    break;
+                    
+                case UIAnimationType.ScaleInOut:
+                    if (rectTransform != null)
+                    {
+                        currentAnimation.Append(rectTransform.DOScale(originalScale, animationDuration).SetEase(animationEase));
+                    }
+                    if (canvasGroup != null)
+                    {
+                        currentAnimation.Join(canvasGroup.DOFade(1f, animationDuration).SetEase(animationEase));
+                    }
+                    break;
+                    
+                case UIAnimationType.SlideFromTop:
+                case UIAnimationType.SlideFromBottom:
+                case UIAnimationType.SlideFromLeft:
+                case UIAnimationType.SlideFromRight:
+                    if (rectTransform != null)
+                    {
+                        currentAnimation.Append(rectTransform.DOAnchorPos(originalPosition, animationDuration).SetEase(animationEase));
+                    }
+                    if (canvasGroup != null)
+                    {
+                        currentAnimation.Join(canvasGroup.DOFade(1f, animationDuration).SetEase(animationEase));
+                    }
+                    break;
+            }
+            
+            // 鍔ㄧ敾瀹屾垚鍚庣殑鍥炶皟
+            currentAnimation.OnComplete(() => {
+                isAnimating = false;
+                
+                // 鍚敤浜や簰
+                if (canvasGroup != null)
+                {
+                    canvasGroup.interactable = true;
+                    canvasGroup.blocksRaycasts = true;
+                }
+            });
+        }
+        catch (System.Exception e)
+        {
+            Debug.LogError($"鎾斁鎵撳紑鍔ㄧ敾鏃跺嚭閿�: {e.Message}");
+            
+            // 鍑洪敊鏃剁‘淇漊I鍙骞跺彲浜や簰
+            if (canvasGroup != null)
+            {
+                canvasGroup.alpha = 1f;
+                canvasGroup.interactable = true;
+                canvasGroup.blocksRaycasts = true;
+            }
+            isAnimating = false;
+        }
+    }
+    
+    // 鎾斁鍏抽棴鍔ㄧ敾
+    protected virtual void PlayCloseAnimation()
+    {
+        if (closeAnimationType == UIAnimationType.None)
+        {
+            // 鏃犲姩鐢伙紝鐩存帴绂佺敤浜や簰
+            if (canvasGroup != null)
+            {
+                canvasGroup.alpha = 0f;
+                canvasGroup.interactable = false;
+                canvasGroup.blocksRaycasts = false;
+            }
+            return;
+        }
+        
+        isAnimating = true;
+        
+        // 绂佺敤浜や簰锛屼絾淇濇寔鍙
+        if (canvasGroup != null)
+        {
+            canvasGroup.interactable = false;
+            canvasGroup.blocksRaycasts = false;
+        }
+        
+        try
+        {
+            // 鍒涘缓鍔ㄧ敾搴忓垪
+            currentAnimation = DOTween.Sequence();
+            
+            // 娣诲姞鍔ㄧ敾
+            switch (closeAnimationType)
+            {
+                case UIAnimationType.FadeInOut:
+                    if (canvasGroup != null)
+                    {
+                        currentAnimation.Append(canvasGroup.DOFade(0f, animationDuration).SetEase(animationEase));
+                    }
+                    break;
+                    
+                case UIAnimationType.ScaleInOut:
+                    if (rectTransform != null)
+                    {
+                        currentAnimation.Append(rectTransform.DOScale(Vector3.zero, animationDuration).SetEase(animationEase));
+                    }
+                    if (canvasGroup != null)
+                    {
+                        currentAnimation.Join(canvasGroup.DOFade(0f, animationDuration).SetEase(animationEase));
+                    }
+                    break;
+                    
+                case UIAnimationType.SlideFromTop:
+                    if (rectTransform != null)
+                    {
+                        Vector2 endPos = originalPosition;
+                        endPos.y = Screen.height;
+                        currentAnimation.Append(rectTransform.DOAnchorPos(endPos, animationDuration).SetEase(animationEase));
+                    }
+                    if (canvasGroup != null)
+                    {
+                        currentAnimation.Join(canvasGroup.DOFade(0f, animationDuration).SetEase(animationEase));
+                    }
+                    break;
+                    
+                case UIAnimationType.SlideFromBottom:
+                    if (rectTransform != null)
+                    {
+                        Vector2 endPos = originalPosition;
+                        endPos.y = -Screen.height;
+                        currentAnimation.Append(rectTransform.DOAnchorPos(endPos, animationDuration).SetEase(animationEase));
+                    }
+                    if (canvasGroup != null)
+                    {
+                        currentAnimation.Join(canvasGroup.DOFade(0f, animationDuration).SetEase(animationEase));
+                    }
+                    break;
+                    
+                case UIAnimationType.SlideFromLeft:
+                    if (rectTransform != null)
+                    {
+                        Vector2 endPos = originalPosition;
+                        endPos.x = -Screen.width;
+                        currentAnimation.Append(rectTransform.DOAnchorPos(endPos, animationDuration).SetEase(animationEase));
+                    }
+                    if (canvasGroup != null)
+                    {
+                        currentAnimation.Join(canvasGroup.DOFade(0f, animationDuration).SetEase(animationEase));
+                    }
+                    break;
+                    
+                case UIAnimationType.SlideFromRight:
+                    if (rectTransform != null)
+                    {
+                        Vector2 endPos = originalPosition;
+                        endPos.x = Screen.width;
+                        currentAnimation.Append(rectTransform.DOAnchorPos(endPos, animationDuration).SetEase(animationEase));
+                    }
+                    if (canvasGroup != null)
+                    {
+                        currentAnimation.Join(canvasGroup.DOFade(0f, animationDuration).SetEase(animationEase));
+                    }
+                    break;
+            }
+            
+            // 鍔ㄧ敾瀹屾垚鍚庣殑鍥炶皟
+            currentAnimation.OnComplete(() => {
+                isAnimating = false;
+                
+                // 纭繚UI涓嶅彲瑙佷笖涓嶅彲浜や簰
+                if (canvasGroup != null)
+                {
+                    canvasGroup.alpha = 0f;
+                    canvasGroup.interactable = false;
+                    canvasGroup.blocksRaycasts = false;
+                }
+                
+                // 寤惰繜绂佺敤GameObject锛岄伩鍏嶉绻佺殑Enable/Disable鎿嶄綔
+                // 濡傛灉闇�瑕佺珛鍗抽噴鏀捐祫婧愶紝鍙互鍙栨秷娉ㄩ噴涓嬮潰鐨勪唬鐮�
+                // gameObject.SetActive(false);
+            });
+        }
+        catch (System.Exception e)
+        {
+            Debug.LogError($"鎾斁鍏抽棴鍔ㄧ敾鏃跺嚭閿�: {e.Message}");
+            
+            // 鍑洪敊鏃剁‘淇漊I涓嶅彲瑙佷笖涓嶅彲浜や簰
+            if (canvasGroup != null)
+            {
+                canvasGroup.alpha = 0f;
+                canvasGroup.interactable = false;
+                canvasGroup.blocksRaycasts = false;
+            }
+            isAnimating = false;
+        }
+    }
+    
+    #endregion
+
+    #region 瀛怳I绠$悊
+
+    // 娣诲姞瀛怳I
+    public void AddChildUI(UIBase childUI)
+    {
+        if (childUI != null && !childrenUI.Contains(childUI))
+        {
+            childrenUI.Add(childUI);
+            childUI.parentUI = this;
+        }
+    }
+    
+    // 绉婚櫎瀛怳I
+    public void RemoveChildUI(UIBase childUI)
+    {
+        if (childUI != null && childrenUI.Contains(childUI))
+        {
+            childrenUI.Remove(childUI);
+            childUI.parentUI = null;
+        }
+    }
+    
+    // 娓呯┖鎵�鏈夊瓙UI
+    public void ClearChildrenUI()
+    {
+        for (int i = childrenUI.Count - 1; i >= 0; i--)
+        {
+            if (childrenUI[i] != null)
+            {
+                childrenUI[i].parentUI = null;
+            }
+        }
+        
+        childrenUI.Clear();
+    }
+
+    #endregion
+
+    #region 鍥炶皟鏂规硶
+
+    // UI鎵撳紑鏃剁殑鍥炶皟
+    protected virtual void OnOpen()
+    {
+        // 瀛愮被鍙互閲嶅啓姝ゆ柟娉曞疄鐜版墦寮�UI鏃剁殑閫昏緫
+    }
+    
+    // UI鍏抽棴鏃剁殑鍥炶皟
+    protected virtual void OnClose()
+    {
+        // 瀛愮被鍙互閲嶅啓姝ゆ柟娉曞疄鐜板叧闂璘I鏃剁殑閫昏緫
+    }
+
+    #endregion
+}
\ No newline at end of file
diff --git a/Main/UI/UIBase.cs.meta b/Main/UI/UIBase.cs.meta
new file mode 100644
index 0000000..071830c
--- /dev/null
+++ b/Main/UI/UIBase.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 98b79f8446db7de4289c11a4109a9009
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/UI/UIManager.cs b/Main/UI/UIManager.cs
new file mode 100644
index 0000000..56abadf
--- /dev/null
+++ b/Main/UI/UIManager.cs
@@ -0,0 +1,586 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System;
+
+public class UIManager : Singleton<UIManager>
+{
+    // 鍗曚緥瀹炰緥
+
+    #region 鍙橀噺瀹氫箟
+    
+    // UI鏍硅妭鐐�
+    private Transform uiRoot;
+    private Transform staticTrans;
+    private Transform bottomTrans;
+    private Transform midTrans;
+    private Transform topTrans;
+    private Transform systemTrans;  
+    
+    // 鍩虹鎺掑簭椤哄簭
+    private const int BASE_SORTING_ORDER = 10;
+    private const int SORTING_ORDER_STEP = 10;
+    
+    // 宸插姞杞界殑UI瀛楀吀
+    private Dictionary<string, UIBase> uiDict = new Dictionary<string, UIBase>();
+    
+    // 褰撳墠鎵撳紑鐨刄I鏍�
+    private Stack<UIBase> uiStack = new Stack<UIBase>();
+    
+    // 褰撳墠鏈�楂樼殑鎺掑簭椤哄簭
+    private int currentHighestSortingOrder = 0;
+    
+    // 褰撳墠鍥炲悎鏁�
+    private int currentRound = 0;
+    
+    #endregion
+
+    #region 鍒濆鍖栨柟娉�
+    
+    // 鍒濆鍖�
+    private void Init()
+    {
+        InitUIRoot();
+    }
+    
+    // 鍒涘缓UI鏍硅妭鐐�
+    private void InitUIRoot()
+    {
+        GameObject root = GameObject.Instantiate(Resources.Load<GameObject>("UIRoot"));
+        uiRoot = root.transform;
+        uiRoot.position = Vector3.zero;
+
+        // 鍒濆鍖栧悇灞傜骇鐨凾ransform
+        staticTrans = uiRoot.Find("Static");
+        bottomTrans = uiRoot.Find("Bottom");
+        midTrans = uiRoot.Find("Mid");
+        topTrans = uiRoot.Find("Top");
+        systemTrans = uiRoot.Find("System");
+
+        // // 娣诲姞鍩虹Canvas
+        // Canvas rootCanvas = root.AddComponent<Canvas>();
+        // rootCanvas.renderMode = RenderMode.ScreenSpaceOverlay;
+        // rootCanvas.sortingOrder = 0;
+
+        // // 娣诲姞CanvasScaler
+        // UnityEngine.UI.CanvasScaler scaler = root.AddComponent<UnityEngine.UI.CanvasScaler>();
+        // scaler.uiScaleMode = UnityEngine.UI.CanvasScaler.ScaleMode.ScaleWithScreenSize;
+        // scaler.referenceResolution = new Vector2(1920, 1080);
+        // scaler.screenMatchMode = UnityEngine.UI.CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
+        // scaler.matchWidthOrHeight = 1.0f;
+
+        // // 娣诲姞GraphicRaycaster
+        // root.AddComponent<UnityEngine.UI.GraphicRaycaster>();
+    }
+    
+    #endregion
+
+    #region 杈呭姪鏂规硶
+    
+    // 鑾峰彇UI灞傜骇瀵瑰簲鐨勫熀纭�鎺掑簭椤哄簭
+    private int GetBaseSortingOrderForLayer(UILayer layer)
+    {
+        switch (layer)
+        {
+            case UILayer.Static:
+                return BASE_SORTING_ORDER;
+            case UILayer.Bottom:
+                return BASE_SORTING_ORDER * 10;
+            case UILayer.Mid:
+                return BASE_SORTING_ORDER * 100;
+            case UILayer.Top:
+                return BASE_SORTING_ORDER * 1000;
+            case UILayer.System:
+                return BASE_SORTING_ORDER * 10000;
+            default:
+                return BASE_SORTING_ORDER * 10;
+        }
+    }
+
+    // 鑾峰彇灞傜骇瀵瑰簲鐨凾ransform
+    private Transform GetTransForLayer(UILayer layer)
+    {
+        switch (layer)
+        {
+            case UILayer.Static:
+                return staticTrans;
+            case UILayer.Bottom:
+                return bottomTrans;
+            case UILayer.Mid:
+                return midTrans;
+            case UILayer.Top:
+                return topTrans;
+            case UILayer.System:
+                return systemTrans;
+            default:
+                return bottomTrans;
+        }
+    }
+    
+    // 鑾峰彇UI瀹炰緥锛屽鏋滀笉瀛樺湪鍒欒繑鍥瀗ull
+    private UIBase GetUI(string uiName)
+    {
+        if (string.IsNullOrEmpty(uiName))
+        {
+            Debug.LogError("UI鍚嶇О涓虹┖");
+            return null;
+        }
+        
+        UIBase ui;
+        if (uiDict.TryGetValue(uiName, out ui))
+        {
+            return ui;
+        }
+        
+        return null;
+    }
+    
+    // 鏇存柊鐖剁骇UI鐨勫洖鍚堟暟
+    private void UpdateParentUIRounds(UIBase ui)
+    {
+        if (ui == null)
+            return;
+            
+        UIBase parentUI = ui.parentUI;
+        while (parentUI != null)
+        {
+            parentUI.lastUsedRound = currentRound;
+            parentUI = parentUI.parentUI;
+        }
+    }
+    
+    // 閫掑綊鏀堕泦鎵�鏈夊瓙UI
+    private void CollectChildrenUI(UIBase ui, List<UIBase> result)
+    {
+        if (ui == null || ui.childrenUI == null || ui.childrenUI.Count == 0)
+            return;
+        
+        foreach (var childUI in ui.childrenUI)
+        {
+            if (!result.Contains(childUI))
+            {
+                result.Add(childUI);
+                // 閫掑綊鏀堕泦瀛怳I鐨勫瓙UI
+                CollectChildrenUI(childUI, result);
+            }
+        }
+    }
+    
+    #endregion
+
+    #region UI璧勬簮绠$悊
+    
+    // 鍔犺浇UI棰勫埗浣�
+    private UIBase LoadUIResource(string uiName)
+    {
+        // 杩欓噷鏄祫婧愬姞杞介儴鍒嗭紝鏍规嵁椤圭洰瀹為檯鎯呭喌瀹炵幇
+        // 鍙互浣跨敤Resources.Load鎴栬�呭叾浠栬祫婧愮鐞嗙郴缁�
+
+        // 绀轰緥浠g爜锛屽疄闄呴」鐩腑闇�瑕佹浛鎹负鐪熷疄鐨勮祫婧愬姞杞介�昏緫
+        GameObject prefab = null;
+
+        // TODO: 鍦ㄨ繖閲屽疄鐜拌祫婧愬姞杞介�昏緫
+        // prefab = Resources.Load<GameObject>("UI/" + uiName);
+
+        if (prefab == null)
+        {
+            Debug.LogError($"鍔犺浇UI棰勫埗浣撳け璐�: {uiName}");
+            return null;
+        }
+
+        GameObject uiObject = GameObject.Instantiate(prefab);
+        UIBase uiBase = uiObject.GetComponent<UIBase>();
+
+        if (uiBase == null)
+        {
+            Debug.LogError($"UI棰勫埗浣� {uiName} 娌℃湁 UIBase 缁勪欢");
+            return null;
+        }
+
+        uiBase.uiName = uiName;
+
+        // 璁剧疆鐖惰妭鐐逛负UI鏍硅妭鐐�
+        uiObject.transform.SetParent(GetTransForLayer(uiBase.uiLayer), false);
+
+        // 鍒濆鍖朥I
+        uiBase.Init();
+
+        // 璁剧疆鎺掑簭椤哄簭
+        int baseSortingOrder = GetBaseSortingOrderForLayer(uiBase.uiLayer);
+        uiBase.SetSortingOrder(baseSortingOrder);
+
+        return uiBase;
+    }
+    
+    #endregion
+
+    #region UI鎺掑簭绠$悊
+    
+    // 鏇存柊UI鎺掑簭椤哄簭
+    private void UpdateUISortingOrder()
+    {
+        currentHighestSortingOrder = 0;
+        
+        // 閬嶅巻UI鏍堬紝璁剧疆鎺掑簭椤哄簭
+        UIBase[] uiArray = new UIBase[uiStack.Count];
+        uiStack.CopyTo(uiArray, 0);
+        
+        // 鍏堟寜鐓ILayer杩涜鎺掑簭锛岀劧鍚庡啀鎸夌収鏍堥『搴忔帓搴�
+        Array.Sort(uiArray, (a, b) => {
+            int layerCompare = a.uiLayer.CompareTo(b.uiLayer);
+            if (layerCompare != 0)
+                return layerCompare;
+                
+            // 鍚屽眰绾у唴锛屾寜鐓ф爤涓殑椤哄簭鎺掑簭
+            int aIndex = Array.IndexOf(uiArray, a);
+            int bIndex = Array.IndexOf(uiArray, b);
+            return aIndex.CompareTo(bIndex);
+        });
+        
+        for (int i = 0; i < uiArray.Length; i++)
+        {
+            UIBase ui = uiArray[i];
+            int baseSortingOrder = GetBaseSortingOrderForLayer(ui.uiLayer);
+            int sortingOrder = baseSortingOrder + i * SORTING_ORDER_STEP;
+            
+            ui.SetSortingOrder(sortingOrder);
+            
+            if (sortingOrder > currentHighestSortingOrder)
+            {
+                currentHighestSortingOrder = sortingOrder;
+            }
+        }
+    }
+    
+    #endregion
+
+    #region UI鏍堢鐞�
+    
+    // 浠嶶I鏍堜腑绉婚櫎鎸囧畾UI
+    private void RemoveFromUIStack(UIBase ui)
+    {
+        if (ui == null || !uiStack.Contains(ui))
+            return;
+            
+        RemoveFromUIStack(new List<UIBase> { ui });
+    }
+
+    // 浠嶶I鏍堜腑绉婚櫎澶氫釜UI
+    private void RemoveFromUIStack(List<UIBase> uisToRemove)
+    {
+        if (uisToRemove == null || uisToRemove.Count == 0)
+            return;
+            
+        Stack<UIBase> tempStack = new Stack<UIBase>();
+        while (uiStack.Count > 0)
+        {
+            UIBase topUI = uiStack.Pop();
+            if (!uisToRemove.Contains(topUI))
+            {
+                tempStack.Push(topUI);
+            }
+        }
+        
+        // 鎭㈠UI鏍�
+        while (tempStack.Count > 0)
+        {
+            uiStack.Push(tempStack.Pop());
+        }
+        
+        // 鏇存柊鎺掑簭椤哄簭
+        UpdateUISortingOrder();
+    }
+    
+    #endregion
+
+    #region 鍏叡鎺ュ彛鏂规硶
+    
+    // 鎵撳紑鍗曚釜UI绐楀彛
+    public UIBase OpenWindow(string uiName)
+    {
+        if (string.IsNullOrEmpty(uiName))
+        {
+            Debug.LogError("灏濊瘯鎵撳紑绌哄悕绉扮殑UI绐楀彛");
+            return null;
+        }
+        
+        // 澧炲姞鍥炲悎鏁�
+        currentRound++;
+        
+        // 鍏堝皾璇曡幏鍙栧凡鍔犺浇鐨刄I
+        UIBase ui = GetUI(uiName);
+        
+        // 濡傛灉UI涓嶅瓨鍦紝鍒欏姞杞�
+        if (ui == null)
+        {
+            ui = LoadUIResource(uiName);
+            if (ui == null)
+                return null;
+                
+            // 灏嗘柊鍔犺浇鐨刄I娣诲姞鍒板瓧鍏镐腑
+            uiDict[uiName] = ui;
+        }
+        
+        // 鏇存柊UI鐨勬渶鍚庝娇鐢ㄥ洖鍚堟暟
+        ui.lastUsedRound = currentRound;
+        
+        // 鏇存柊鎵�鏈夌埗绾I鐨勫洖鍚堟暟
+        UpdateParentUIRounds(ui);
+        
+        if (ui.uiLayer != UILayer.System && !ui.isMainUI)
+        {
+            if (uiStack.Contains(ui))
+            {
+                // 鍦∣penWindow鏂规硶涓慨鏀瑰叧闂璘I鐨勯�昏緫
+                // 鎵惧埌UI鍦ㄦ爤涓殑浣嶇疆
+                List<UIBase> uiList = new List<UIBase>(uiStack);
+                int index = uiList.IndexOf(ui);
+
+                // 鍏抽棴璇I涔嬪悗鐨勭浉鍏砋I锛屼絾淇濈暀System灞傜骇鐨刄I
+                Stack<UIBase> tempStack = new Stack<UIBase>();
+                while (uiStack.Count > index)
+                {
+                    UIBase topUI = uiStack.Pop();
+
+                    // 濡傛灉鏄疭ystem灞傜骇鐨刄I锛屼繚鐣欏畠
+                    if (topUI.uiLayer == UILayer.System || topUI.isMainUI)
+                    {
+                        tempStack.Push(topUI);
+                        continue;
+                    }
+
+                    // 濡傛灉涓嶆槸褰撳墠UI閾句笂鐨刄I锛屼篃淇濈暀瀹�
+                    // 鍒ゆ柇鏄惁灞炰簬褰撳墠UI閾剧殑閫昏緫锛氭鏌ユ槸鍚︽湁鐖跺瓙鍏崇郴
+                    bool isInCurrentChain = false;
+                    UIBase parent = ui;
+                    while (parent != null)
+                    {
+                        if (parent == topUI || parent.childrenUI.Contains(topUI))
+                        {
+                            isInCurrentChain = true;
+                            break;
+                        }
+                        parent = parent.parentUI;
+                    }
+
+                    if (!isInCurrentChain)
+                    {
+                        tempStack.Push(topUI);
+                        continue;
+                    }
+
+                    // 鍏抽棴褰撳墠UI閾句笂鐨勯潪System灞俇I
+                    topUI.Close();
+
+                    // 娓呯悊鐖跺瓙鍏崇郴
+                    if (topUI.parentUI != null)
+                    {
+                        topUI.parentUI.RemoveChildUI(topUI);
+                        topUI.parentUI = null; // 娓呯悊鑷繁瀵圭埗UI鐨勫紩鐢�
+                    }
+                    topUI.ClearChildrenUI();
+                }
+
+                // 鎭㈠淇濈暀鐨刄I鍒版爤涓�
+                while (tempStack.Count > 0)
+                {
+                    uiStack.Push(tempStack.Pop());
+                }
+            }
+        }
+
+        ui.Open();
+        
+        // 濡傛灉鏍堜腑鏈夊叾浠朥I锛屽垯灏嗘爤椤禪I璁句负鐖禪I
+        if (!ui.isMainUI && ui.uiLayer != UILayer.System && uiStack.Count > 0)
+        {
+            UIBase topUI = uiStack.Peek();
+            
+            if (topUI != null)
+            {
+                // System灞傜骇UI涓嶅簲璇ユ垚涓哄叾浠朥I鐨勭埗UI锛屼篃涓嶅簲璇ユ垚涓哄叾浠朥I鐨勫瓙UI
+                if (topUI.uiLayer != UILayer.System)
+                {
+                    // 娓呯悊鏃х殑鐖跺瓙鍏崇郴
+                    if (ui.parentUI != null && ui.parentUI != topUI)
+                    {
+                        ui.parentUI.RemoveChildUI(ui);
+                    }
+                    
+                    // 璁剧疆鏂扮殑鐖跺瓙鍏崇郴
+                    topUI.AddChildUI(ui);
+                }
+            }
+        }
+        
+        // 娣诲姞鍒癠I鏍�
+        uiStack.Push(ui);
+        
+        // 鏇存柊鎺掑簭椤哄簭
+        UpdateUISortingOrder();
+        
+        // 鍦ㄦ墦寮�鐣岄潰鍚庢鏌I鐢熷懡鍛ㄦ湡
+        CheckUILifecycle();
+        
+        return ui;
+    }
+
+    // 鎸夐『搴忔墦寮�澶氱骇UI绐楀彛
+    public UIBase OpenWindow(params string[] uiNames)
+    {
+        if (uiNames == null || uiNames.Length == 0)
+            return null;
+
+        UIBase ui = null;
+
+        for (int i = 0; i < uiNames.Length; i++)
+        {
+            string uiName = uiNames[i];
+            ui = OpenWindow(uiName);
+        }
+
+        return ui;
+    }
+    
+    // 鍏抽棴鎸囧畾UI绐楀彛
+    public void CloseWindow(UIBase ui)
+    {
+        if (ui == null)
+            return;
+        
+        // 鍒涘缓涓�涓垪琛ㄦ潵瀛樺偍闇�瑕佸叧闂殑UI
+        List<UIBase> uisToClose = new List<UIBase>();
+        uisToClose.Add(ui);
+        
+        // 閫掑綊鏀堕泦鎵�鏈夊瓙UI
+        CollectChildrenUI(ui, uisToClose);
+        
+        // 鏇存柊鐖剁骇UI鐨勫洖鍚堟暟
+        if (ui.parentUI != null)
+        {
+            UpdateParentUIRounds(ui.parentUI);
+        }
+        
+        // 鍏抽棴鎵�鏈夋敹闆嗗埌鐨刄I
+        foreach (var uiToClose in uisToClose)
+        {
+            // 鍏抽棴UI
+            uiToClose.Close();
+            
+            // 娓呯悊鐖跺瓙鍏崇郴
+            if (uiToClose.parentUI != null)
+            {
+                uiToClose.parentUI.RemoveChildUI(uiToClose);
+                uiToClose.parentUI = null;
+            }
+            
+            // 妫�鏌ユ槸鍚﹂渶瑕佺珛鍗抽攢姣�
+            // 濡傛灉鏄潪鎸佷箙鍖朥I涓旇秴杩囦簡鏈�澶х┖闂插洖鍚堟暟锛岀珛鍗抽攢姣�
+            if (!uiToClose.isPersistent && (currentRound - uiToClose.lastUsedRound) > uiToClose.maxIdleRounds)
+            {
+                DestroyUI(uiToClose);
+            }
+        }
+        
+        // 浣跨敤鍏叡鏂规硶浠嶶I鏍堜腑绉婚櫎鎵�鏈夊叧闂殑UI
+        RemoveFromUIStack(uisToClose);
+    }
+    
+    // 鍏抽棴鎵�鏈塙I绐楀彛
+    public void CloseAllWindows()
+    {
+        foreach (var ui in uiDict.Values)
+        {
+            if (ui != null)
+            {
+                ui.Close();
+            }
+        }
+        
+        uiStack.Clear();
+    }
+
+    // 杩斿洖涓婁竴绾I
+    public void GoBack()
+    {
+        if (uiStack.Count <= 1)
+            return;
+        
+        // 鍏抽棴褰撳墠UI
+        UIBase currentUI = uiStack.Pop();
+        currentUI.Close();
+        
+        // 鏇存柊鎺掑簭椤哄簭
+        UpdateUISortingOrder();
+    }
+    
+    // 閿�姣佹寚瀹歎I瀵硅薄
+    public void DestroyUI(UIBase ui)
+    {
+        if (ui == null)
+            return;
+    
+        // 鍏抽棴UI
+        ui.Destroy();
+    
+        uiDict.Remove(ui.uiName);
+        
+        // 浣跨敤鍏叡鏂规硶浠嶶I鏍堜腑绉婚櫎UI
+        RemoveFromUIStack(ui);
+    }
+
+    // 閿�姣佹寚瀹氬悕绉扮殑UI
+    public void DestroyUI(string uiName)
+    {
+        if (string.IsNullOrEmpty(uiName))
+            return;
+
+        UIBase ui;
+        if (uiDict.TryGetValue(uiName, out ui))
+        {
+            DestroyUI(ui);
+        }
+    }
+
+    // 閿�姣佹墍鏈塙I
+    public void DestroyAllUI()
+    {
+        foreach (var ui in uiDict.Values)
+        {
+            if (ui != null)
+            {
+                DestroyUI(ui);
+            }
+        }
+        
+        uiDict.Clear();
+        uiStack.Clear();
+    }
+    
+    #endregion
+
+    #region 鐢熷懡鍛ㄦ湡绠$悊
+    
+    // 妫�鏌I鐢熷懡鍛ㄦ湡
+    private void CheckUILifecycle()
+    {
+        // 浣跨敤涓存椂鍒楄〃瀛樺偍闇�瑕侀攢姣佺殑UI鍚嶇О锛岄伩鍏嶅湪杩唬杩囩▼涓慨鏀瑰瓧鍏�
+        List<string> uiToDestroy = new List<string>();
+        
+        foreach (var pair in uiDict)
+        {
+            if (!pair.Value.isPersistent && !uiStack.Contains(pair.Value) && 
+                (currentRound - pair.Value.lastUsedRound) > pair.Value.maxIdleRounds)
+            {
+                uiToDestroy.Add(pair.Key);
+            }
+        }
+        
+        foreach (var uiName in uiToDestroy)
+        {
+            DestroyUI(uiName);
+        }
+    }
+    
+    #endregion
+}
diff --git a/Main/UI/UIManager.cs.meta b/Main/UI/UIManager.cs.meta
new file mode 100644
index 0000000..ed264fb
--- /dev/null
+++ b/Main/UI/UIManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 12e9bc19be52dcd46a138ce4cc477853
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/VersionCheck.cs b/Main/VersionCheck.cs
new file mode 100644
index 0000000..78d970d
--- /dev/null
+++ b/Main/VersionCheck.cs
@@ -0,0 +1,48 @@
+using System;
+using UnityEngine;
+using Cysharp.Threading.Tasks;
+
+/// <summary>
+/// 鐗堟湰妫�鏌ョ被锛岀敤浜庤幏鍙栧綋鍓嶅簲鐢ㄧ増鏈俊鎭�
+/// </summary>
+public class VersionCheck
+{
+    /// <summary>
+    /// 鑾峰彇鏈湴鐗堟湰淇℃伅
+    /// 閫傜敤浜庡畨鍗撱�乮OS銆乄ebGL鍜孭C骞冲彴
+    /// </summary>
+    /// <returns>鐗堟湰瀛楃涓诧紝鏍煎紡涓� x.y.z</returns>
+    public static async UniTask<string> GetLocalVersionAsync()
+    {
+        try
+        {
+            // 棣栧厛灏濊瘯浠嶳esources鍔犺浇鐗堟湰鏂囦欢
+            TextAsset versionAsset = Resources.Load<TextAsset>("version");
+            
+            if (versionAsset != null)
+            {
+                string versionText = versionAsset.text.Trim();
+                Debug.Log($"浠嶳esources鍔犺浇鐗堟湰淇℃伅: {versionText}");
+                return versionText;
+            }
+            
+            // 濡傛灉Resources涓病鏈夌増鏈枃浠讹紝鍒欎娇鐢ㄥ簲鐢ㄧ▼搴忕増鏈�
+            string appVersion = Application.version;
+            Debug.Log($"浣跨敤搴旂敤绋嬪簭鐗堟湰: {appVersion}");
+            
+            // 纭繚鐗堟湰鍙锋牸寮忔纭�
+            if (string.IsNullOrEmpty(appVersion))
+            {
+                Debug.LogWarning("搴旂敤绋嬪簭鐗堟湰涓虹┖锛屼娇鐢ㄩ粯璁ょ増鏈� 1.0.0");
+                appVersion = "1.0.0";
+            }
+            
+            return appVersion;
+        }
+        catch (Exception e)
+        {
+            Debug.LogError($"鑾峰彇鏈湴鐗堟湰淇℃伅澶辫触: {e.Message}");
+            return "1.0.0"; // 杩斿洖榛樿鐗堟湰
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/VersionCheck.cs.meta b/Main/VersionCheck.cs.meta
new file mode 100644
index 0000000..7f3c4fd
--- /dev/null
+++ b/Main/VersionCheck.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e39b0cc9263ecba46b308a67dbea5e9c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility.meta b/Utility.meta
new file mode 100644
index 0000000..5755f78
--- /dev/null
+++ b/Utility.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ac01d5885c825374abc749094d98214e
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/Bezier.cs b/Utility/Bezier.cs
new file mode 100644
index 0000000..316bf5e
--- /dev/null
+++ b/Utility/Bezier.cs
@@ -0,0 +1,39 @@
+锘縰sing UnityEngine;
+
+public class Bezier
+{
+
+    /// <summary>  
+    ///   
+    /// </summary>  
+    /// <param name="P0"></param>  
+    /// <param name="P1"></param>  
+    /// <param name="P2"></param>  
+    /// <param name="t">0.0 >= t <= 1.0 </param>  
+    /// <returns></returns>  
+    public static Vector3 BezierCurve(Vector3 P0, Vector3 P1, Vector3 P2, float t)
+    {
+        var t1 = (1 - t) * (1 - t);
+        var t2 = t * (1 - t);
+        var t3 = t * t;
+        return P0 * t1 + 2 * t2 * P1 + t3 * P2;
+    }
+
+    /// <summary>  
+    ///   
+    /// </summary>  
+    /// <param name="P0"></param>  
+    /// <param name="P1"></param>  
+    /// <param name="P2"></param>  
+    /// <param name="P3"></param>  
+    /// <param name="t">0.0 >= t <= 1.0 </param>  
+    /// <returns></returns>  
+    public static Vector3 BezierCurve(Vector3 P0, Vector3 P1, Vector3 P2, Vector3 P3, float t)
+    {
+        var t1 = (1 - t) * (1 - t) * (1 - t);
+        var t2 = (1 - t) * (1 - t) * t;
+        var t3 = t * t * (1 - t);
+        var t4 = t * t * t;
+        return P0 * t1 + 3 * t2 * P1 + 3 * t3 * P2 + P3 * t4;
+    }
+}
\ No newline at end of file
diff --git a/Utility/Bezier.cs.meta b/Utility/Bezier.cs.meta
new file mode 100644
index 0000000..f57adee
--- /dev/null
+++ b/Utility/Bezier.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: caa3615b3dcba6043bb477fb08595237
+timeCreated: 1517921303
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/BezierMove.cs b/Utility/BezierMove.cs
new file mode 100644
index 0000000..4629f1c
--- /dev/null
+++ b/Utility/BezierMove.cs
@@ -0,0 +1,45 @@
+锘縰sing System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System;
+
+public class BezierMove : MonoBehaviour
+{
+    public float duration = 2f;
+    float timer = 0f;
+
+    Vector3 p1;
+    Vector3 p2;
+    Vector3 p3;
+
+    Action onEnd;
+
+    public void Begin(Vector3 _p1, Vector3 _p2, Vector3 _p3, Action _callBack)
+    {
+        p1 = _p1;
+        p2 = _p2;
+        p3 = _p3;
+        onEnd = _callBack;
+
+        this.SetActive(true);
+        timer = 0f;
+    }
+
+    void LateUpdate()
+    {
+        timer += Time.deltaTime;
+        var t = Mathf.Clamp01(timer / duration);
+        this.transform.position = Bezier.BezierCurve(p1, p2, p3, t);
+
+        if (timer > duration)
+        {
+            if (onEnd != null)
+            {
+                onEnd();
+                onEnd = null;
+            }
+            this.SetActive(false);
+        }
+    }
+
+}
diff --git a/Utility/BezierMove.cs.meta b/Utility/BezierMove.cs.meta
new file mode 100644
index 0000000..208285c
--- /dev/null
+++ b/Utility/BezierMove.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 078ac05e7902bb849a3a1eb7f71f16f6
+timeCreated: 1517921416
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/CameraManager.cs b/Utility/CameraManager.cs
new file mode 100644
index 0000000..2a40109
--- /dev/null
+++ b/Utility/CameraManager.cs
@@ -0,0 +1,30 @@
+锘縰sing UnityEngine;
+using System.Collections;
+
+public class CameraManager
+{
+    /// <summary>
+    /// UI Camera 
+    /// </summary>
+    private static Camera m_UICamera = null;
+    public static Camera uiCamera
+    {
+        get
+        {
+            return m_UICamera;
+        }
+        set
+        {
+            m_UICamera = value;
+        }
+    }
+
+    private static Camera m_SceneCamera = null;
+    public static Camera sceneCamera
+    {
+        get { return m_SceneCamera; }
+        set { m_SceneCamera = value; }
+    }
+
+
+}
diff --git a/Utility/CameraManager.cs.meta b/Utility/CameraManager.cs.meta
new file mode 100644
index 0000000..b34313b
--- /dev/null
+++ b/Utility/CameraManager.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 925054b4729561f41b2ce58347f58fb1
+timeCreated: 1504310430
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/ColorUtility.cs b/Utility/ColorUtility.cs
new file mode 100644
index 0000000..ab63973
--- /dev/null
+++ b/Utility/ColorUtility.cs
@@ -0,0 +1,31 @@
+锘縰sing System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public static class ColorUtility {
+
+    public static readonly Color dwhite = new Color(1f,1f,1f,1f);
+    public static readonly Color dgray = new Color(0.5f,0.5f,0.5f,1f);
+
+    public static Color SetR(this Color color,float r) {
+        color.r = r;
+        return color;
+    }
+
+    public static Color SetG(this Color color,float g) {
+        color.g = g;
+        return color;
+    }
+
+    public static Color SetB(this Color color,float b) {
+        color.b = b;
+        return color;
+    }
+
+    public static Color SetA(this Color color,float a) {
+        color.a = a;
+        return color;
+    }
+
+}
+
diff --git a/Utility/ColorUtility.cs.meta b/Utility/ColorUtility.cs.meta
new file mode 100644
index 0000000..39c8439
--- /dev/null
+++ b/Utility/ColorUtility.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 8e10b61b636b268438bf36bb6f6bc564
+timeCreated: 1500642557
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/ComponentExtersion.cs b/Utility/ComponentExtersion.cs
new file mode 100644
index 0000000..7ebd110
--- /dev/null
+++ b/Utility/ComponentExtersion.cs
@@ -0,0 +1,234 @@
+锘縰sing UnityEngine;
+using UnityEngine.UI;
+using UnityEngine.Events;
+using System;
+
+
+public static class ComponentExtersion
+{
+
+    public static Component FindComponent(this Component _component, string _type, string _path)
+    {
+        try
+        {
+            if (_component == null)
+            {
+                return null;
+            }
+
+            var transform = _component.transform.Find(_path);
+            if (transform == null)
+            {
+                return null;
+            }
+
+            return transform.GetComponent(_type);
+        }
+        catch (Exception ex)
+        {
+            Debug.Log(ex);
+            return null;
+        }
+
+    }
+
+    public static T AddMissingComponent<T>(this Component _compoent) where T : Component
+    {
+        if (_compoent == null)
+        {
+            return null;
+        }
+
+        T component = _compoent.GetComponent<T>();
+        if (component == null)
+        {
+            component = _compoent.gameObject.AddComponent<T>();
+        }
+
+        return component;
+    }
+
+    public static T AddMissingComponent<T>(this Transform _transform) where T : Component
+    {
+        if (_transform == null)
+        {
+            return null;
+        }
+
+        T component = _transform.GetComponent<T>();
+        if (component == null)
+        {
+            component = _transform.gameObject.AddComponent<T>();
+        }
+
+        return component;
+    }
+
+    public static T AddMissingComponent<T>(this GameObject _gameObject) where T : Component
+    {
+        if (_gameObject == null)
+        {
+            return null;
+        }
+
+        T component = _gameObject.GetComponent<T>();
+        if (component == null)
+        {
+            component = _gameObject.AddComponent<T>();
+        }
+
+        return component;
+    }
+
+    
+    public static void AddListener(this Button _button, UnityAction _action)
+    {
+        if (_button == null)
+        {
+            return;
+        }
+        _button.onClick.RemoveAllListeners();
+        //_button.onClick.RemoveListener(_action);
+        _button.onClick.AddListener(_action);
+    }
+
+    
+    public static void RemoveAllListeners(this Button _button)
+    {
+        if (_button == null)
+        {
+            return;
+        }
+        _button.onClick.RemoveAllListeners();
+    }
+
+    
+    public static void SetListener(this Button button, UnityAction action)
+    {
+        if (button == null)
+        {
+            return;
+        }
+
+        button.onClick.RemoveAllListeners();
+        button.AddListener(action);
+    }
+
+    public static void AddListener(this Toggle _toggle, UnityAction<bool> _action)
+    {
+        if (_toggle == null)
+        {
+            return;
+        }
+        _toggle.onValueChanged.AddListener(_action);
+    }
+
+    
+    public static void SetListener(this Toggle toggle, UnityAction<bool> action)
+    {
+        if (toggle == null)
+        {
+            return;
+        }
+
+        toggle.onValueChanged.RemoveAllListeners();
+        toggle.onValueChanged.AddListener(action);
+    }
+
+    public static void RemoveAllListeners(this Toggle _toggle)
+    {
+        if (_toggle == null)
+        {
+            return;
+        }
+        _toggle.onValueChanged.RemoveAllListeners();
+    }
+
+    
+    public static void AddListener(this Slider _slider, UnityAction<float> _action)
+    {
+        if (_slider == null)
+        {
+            return;
+        }
+        _slider.onValueChanged.AddListener(_action);
+    }
+
+    
+    public static void SetListener(this Slider slider, UnityAction<float> action)
+    {
+        if (slider == null)
+        {
+            return;
+        }
+
+        slider.onValueChanged.RemoveAllListeners();
+        slider.onValueChanged.AddListener(action);
+    }
+
+    public static void RemoveAllListeners(this Slider _slider)
+    {
+        if (_slider == null)
+        {
+            return;
+        }
+        _slider.onValueChanged.RemoveAllListeners();
+    }
+
+    
+    public static void AddListener(this InputField _inputField, UnityAction<string> _action)
+    {
+        if (_inputField == null)
+        {
+            return;
+        }
+        _inputField.onValueChanged.AddListener(_action);
+    }
+
+    public static void SetListener(this InputField inputField, UnityAction<string> action)
+    {
+        if (inputField == null)
+        {
+            return;
+        }
+
+        inputField.onValueChanged.RemoveAllListeners();
+        inputField.onValueChanged.AddListener(action);
+    }
+
+    
+    public static void RemoveAllListeners(this InputField _inputField)
+    {
+        if (_inputField == null)
+        {
+            return;
+        }
+        _inputField.onValueChanged.RemoveAllListeners();
+    }
+
+    public static void SetListener(this Dropdown dropdown, UnityAction<int> action)
+    {
+        if (dropdown == null)
+        {
+            return;
+        }
+        dropdown.onValueChanged.RemoveAllListeners();
+        dropdown.onValueChanged.AddListener(action);
+    }
+
+    public static void SetActive(this Component compoent, bool active)
+    {
+        if (compoent != null)
+        {
+            if (active && !compoent.gameObject.activeSelf)
+            {
+                compoent.gameObject.SetActive(true);
+            }
+            else if (!active && compoent.gameObject.activeSelf)
+            {
+                compoent.gameObject.SetActive(false);
+            }
+        }
+    }
+
+}
diff --git a/Utility/ComponentExtersion.cs.meta b/Utility/ComponentExtersion.cs.meta
new file mode 100644
index 0000000..ea27ddf
--- /dev/null
+++ b/Utility/ComponentExtersion.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 90e4f0ac41cdbbd488e7f23237b1ea8b
+timeCreated: 1497925347
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/Datumline.cs b/Utility/Datumline.cs
new file mode 100644
index 0000000..7c7ba16
--- /dev/null
+++ b/Utility/Datumline.cs
@@ -0,0 +1,167 @@
+锘縰sing System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+[ExecuteAlways]
+[RequireComponent(typeof(RectTransform))]
+public class Datumline : MonoBehaviour {
+
+    [System.NonSerialized] RectTransform m_Rect;
+    public RectTransform rectTransform
+    {
+        get
+        {
+            return m_Rect ?? (m_Rect = GetComponent<RectTransform>());
+        }
+    }
+    [System.NonSerialized] Canvas m_Canva;
+    public Canvas canvas
+    {
+        get
+        {
+            return m_Canva ?? (m_Canva = GetComponentInParent<Canvas>());
+        }
+    }
+
+    public List<DatumlineData> datumlines { get; private set; }
+    private List<DatumlineData> horizonlines = new List<DatumlineData>();
+    private List<DatumlineData> verticallins = new List<DatumlineData>();
+
+    private int m_SelectDatumline = 0;
+    public int SelectDatumline
+    {
+        get
+        {
+            return m_SelectDatumline;
+        }
+    }
+
+    private void Awake()
+    {
+        datumlines = new List<DatumlineData>();
+    }
+
+    private void OnEnable()
+    {
+        if (datumlines == null)
+        {
+            datumlines = new List<DatumlineData>();
+        }
+        if (datumlines.Count == 0)
+        {
+            Add();
+        }
+    }
+
+    private void OnDisable()
+    {
+        
+    }
+
+    public void Add()
+    {
+        var _datumline = new DatumlineData();
+        _datumline.type = HorizonOrVertical.Vertical;
+        _datumline.from = new Vector3(0, rectTransform.rect.height / 2, 0);
+        _datumline.to = new Vector3(0, -rectTransform.rect.height / 2, 0);
+        _datumline.color = Color.white;
+        datumlines.Add(_datumline);
+    }
+
+    public DatumlineData Add(DatumlineData _line)
+    {
+        var _datumline = new DatumlineData();
+        _datumline.type = _line.type;
+        _datumline.from = _line.from;
+        _datumline.to = _line.to;
+        _datumline.color = _line.color;
+        datumlines.Add(_datumline);
+        return _datumline;
+    }
+
+    public void ChangeVector(int _index)
+    {
+        var _datumline = datumlines[_index];
+        _datumline.type = 1 - _datumline.type;
+        if (_datumline.type == HorizonOrVertical.Horizon)
+        {
+            _datumline.from = new Vector3(-rectTransform.rect.width / 2, _datumline.from.x, 0);
+            _datumline.to = new Vector3(rectTransform.rect.width / 2, _datumline.from.x, 0);
+        }
+        else
+        {
+            _datumline.from = new Vector3(_datumline.from.y, rectTransform.rect.height / 2, 0);
+            _datumline.to = new Vector3(_datumline.from.y, -rectTransform.rect.height / 2, 0);
+        }
+    }
+
+    public void Remove(int _index)
+    {
+        if (datumlines.Count == 1)
+        {
+            return;
+        }
+        datumlines.RemoveAt(_index);
+    }
+
+    public Vector3 ToWorldValue(Vector3 _pos)
+    {
+        return _pos * canvas.transform.localScale.x;
+    }
+
+    public float ToScenceValue(float _value)
+    {
+        return _value / canvas.transform.localScale.x;
+    }
+
+    public void SetSelect(int _index)
+    {
+        if (_index < datumlines.Count)
+        {
+            m_SelectDatumline = _index;
+        }
+    }
+
+    public List<DatumlineData> GetLines(HorizonOrVertical _type)
+    {
+        var _list = datumlines.FindAll((x) =>
+        {
+            return x.type == _type;
+        });
+        if (_list != null)
+        {
+            switch (_type)
+            {
+                case HorizonOrVertical.Horizon:
+                    horizonlines.Clear();
+                    horizonlines.AddRange(_list);
+                    horizonlines.Sort(Compare);
+                    break;
+                case HorizonOrVertical.Vertical:
+                    verticallins.Clear();
+                    verticallins.AddRange(_list);
+                    verticallins.Sort(Compare);
+                    break;
+            }
+        }
+        return _type == HorizonOrVertical.Horizon ? horizonlines : verticallins;
+    }
+
+    private int Compare(DatumlineData x, DatumlineData y)
+    {
+        return x.type == HorizonOrVertical.Horizon ? x.from.y.CompareTo(y.from.y) : x.from.x.CompareTo(y.from.x);
+    }
+
+    public class DatumlineData
+    {
+        public Vector3 from { get; set; }
+        public Vector3 to { get; set; }
+        public HorizonOrVertical type { get; set; }
+        public Color color { get; set; }
+    }
+
+    public enum HorizonOrVertical
+    {
+        Horizon,
+        Vertical,
+    }
+}
diff --git a/Utility/Datumline.cs.meta b/Utility/Datumline.cs.meta
new file mode 100644
index 0000000..5d2934f
--- /dev/null
+++ b/Utility/Datumline.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: f04e620a7f20b5c47b45b74e06905e6f
+timeCreated: 1517580893
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/DeviceUtility.cs b/Utility/DeviceUtility.cs
new file mode 100644
index 0000000..fb289db
--- /dev/null
+++ b/Utility/DeviceUtility.cs
@@ -0,0 +1,169 @@
+锘縰sing System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System.Net.NetworkInformation;
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.IO;
+using System.Text.RegularExpressions;
+
+#if UNITY_IOS
+using UnityEngine.iOS;
+#endif
+
+
+public class DeviceUtility
+{
+
+    static string mac = string.Empty;
+    public static string GetMac()
+    {
+        if (string.IsNullOrEmpty(mac))
+        {
+            try
+            {
+                var netInterfaces = NetworkInterface.GetAllNetworkInterfaces();
+                if (netInterfaces != null && netInterfaces.Length > 0)
+                {
+                    mac = netInterfaces[0].GetPhysicalAddress().ToString();
+                }
+            }
+            catch (Exception ex)
+            {
+                Debug.Log(ex);
+            }
+        }
+
+        return mac;
+    }
+
+    static string ipPattern = "[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}";
+    static string ip = string.Empty;
+    public static string GetIp()
+    {
+        try
+        {
+            if (string.IsNullOrEmpty(ip))
+            {
+                string url = "http://pv.sohu.com/cityjson";
+                WebRequest wRequest = WebRequest.Create(url);
+                wRequest.Method = "GET";
+                wRequest.ContentType = "text/html;charset=UTF-8";
+                WebResponse wResponse = wRequest.GetResponse();
+                Stream stream = wResponse.GetResponseStream();
+                StreamReader reader = new StreamReader(stream, System.Text.Encoding.Default);
+                string str = reader.ReadToEnd();
+
+                reader.Close();
+                wResponse.Close();
+
+                var match = Regex.Match(str, ipPattern);
+                if (match != null)
+                {
+                    ip = match.Value;
+                }
+            }
+        }
+        catch (Exception ex)
+        {
+            Debug.Log(ex);
+        }
+
+        return ip;
+    }
+
+    public static string GetDeviceUniquenessIdentify()
+    {
+#if UNITY_IOS
+        return UnityEngine.iOS.Device.advertisingIdentifier;
+#else
+        return SystemInfo.deviceUniqueIdentifier;
+#endif
+    }
+
+    public static string GetDeviceOSLevel()
+    {
+#if UNITY_IOS
+        return UnityEngine.iOS.Device.systemVersion;
+#else
+        return SystemInfo.operatingSystem;
+#endif
+    }
+
+    public static string GetDeviceName()
+    {
+#if UNITY_IOS
+        return UnityEngine.iOS.Device.generation.ToString();
+#else
+        return SystemInfo.deviceName;
+#endif
+    }
+
+    public static string GetDeviceModel()
+    {
+#if UNITY_IOS
+        return UnityEngine.iOS.Device.generation.ToString();
+#else
+        return SystemInfo.deviceModel;
+#endif
+    }
+
+    public static bool IsLowMemory()
+    {
+#if UNITY_IOS
+        if (Application.platform == RuntimePlatform.IPhonePlayer)
+        {
+            switch (Device.generation)
+            {
+                case DeviceGeneration.iPadMini2Gen:
+                case DeviceGeneration.iPhone5S:
+                case DeviceGeneration.iPhone6:
+                case DeviceGeneration.iPhone6Plus:
+                    return true;
+                default:
+                    return false;
+            }
+        }
+        else
+        {
+            return false;
+        }
+#endif
+        return false;
+    }
+
+    public static int cpu = 2;
+    public static int memory = 2 * 1024;
+
+    public static void GetCpuAndMemory(out int _cpu, out int _memory)//鍐呭瓨鍗曚綅鏄疢B
+    {
+        try
+        {
+            _cpu = Environment.ProcessorCount;
+            switch (Application.platform)
+            {
+                case RuntimePlatform.Android:
+                    _memory = 0; //TODO YL collect device memory //ynmbxxjUtil.Instance.Device.totalMemory;
+                    break;
+                case RuntimePlatform.IPhonePlayer:
+                    _memory = IsLowMemory() ? 1 : 2 * 1024;
+                    break;
+                default:
+                    _memory = 4 * 1024;
+                    break;
+            }
+
+            cpu = _cpu;
+            memory = _memory;
+        }
+        catch (Exception ex)
+        {
+            Debug.Log(ex);
+            _cpu = 2;
+            _memory = 2 * 1024;
+        }
+
+    }
+
+}
diff --git a/Utility/DeviceUtility.cs.meta b/Utility/DeviceUtility.cs.meta
new file mode 100644
index 0000000..1b39a8a
--- /dev/null
+++ b/Utility/DeviceUtility.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 12d6400835d396d45a4eb858d5c70b89
+timeCreated: 1511236803
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/DrawUtility.cs b/Utility/DrawUtility.cs
new file mode 100644
index 0000000..2e3c252
--- /dev/null
+++ b/Utility/DrawUtility.cs
@@ -0,0 +1,62 @@
+锘縰sing UnityEngine;
+
+public class DrawUtility {
+
+    // ------------------------------------------------------------------ 
+    // Desc: DrawCircle
+    // ------------------------------------------------------------------ 
+
+    // DrawCircleX
+    public static void DrawCircleX(Vector3 _center, float _radius, Color _color, float _duration = 0.0f, bool _depthTets = true) {
+        DrawCircle(Quaternion.Euler(0.0f, 0.0f, 90.0f), _center, _radius, _color, _duration, _depthTets);
+    }
+
+    // DrawCircleY
+    public static void DrawCircleY(Vector3 _center, float _radius, Color _color, float _duration = 0.0f, bool _depthTets = true) {
+        DrawCircle(Quaternion.identity, _center, _radius, _color, _duration, _depthTets);
+    }
+
+    // DrawCircleZ
+    public static void DrawCircleZ(Vector3 _center, float _radius, Color _color, float _duration = 0.0f, bool _depthTets = true) {
+        DrawCircle(Quaternion.Euler(90.0f, 0.0f, 0.0f), _center, _radius, _color, _duration, _depthTets);
+    }
+
+    public static void DrawTriangle(Vector3 p1, Vector3 p2, Vector3 p3, Color color) {
+        Debug.DrawLine(p1, p2, color);
+        Debug.DrawLine(p2, p3, color);
+        Debug.DrawLine(p3, p1, color);
+    }
+
+
+    public static void DrawCircle(Quaternion _rot, Vector3 _center, float _radius, Color _color, float _duration = 0.0f, bool _depthTets = true) {
+#if UNITY_EDITOR
+        //
+        float two_pi = 2.0f * Mathf.PI;
+        float segments = 32.0f;
+        float step = two_pi / segments;
+        float theta = 0.0f;
+
+        //
+        Vector3 last = _center + _rot * (_radius * new Vector3(Mathf.Cos(theta), 0.0f, Mathf.Sin(theta)));
+        theta += step;
+
+        //
+        for (int i = 1; i <= segments; ++i) {
+            Vector3 cur = _center + _rot * (_radius * new Vector3(Mathf.Cos(theta), 0.0f, Mathf.Sin(theta)));
+            Debug.DrawLine(last, cur, _color, _duration, _depthTets);
+            last = cur;
+            theta += step;
+        }
+#endif
+    }
+
+    // ------------------------------------------------------------------ 
+    // Desc: 
+    // ------------------------------------------------------------------ 
+
+    public static void DrawBall(Vector3 _center, float _radius, Color _color, float _duration = 0.0f, bool _depthTets = true) {
+        DrawCircleX(_center, _radius, _color, _duration, _depthTets);
+        DrawCircleY(_center, _radius, _color, _duration, _depthTets);
+        DrawCircleZ(_center, _radius, _color, _duration, _depthTets);
+    }
+}
diff --git a/Utility/DrawUtility.cs.meta b/Utility/DrawUtility.cs.meta
new file mode 100644
index 0000000..0e2c679
--- /dev/null
+++ b/Utility/DrawUtility.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: a6cba0bc475260a41ab2a1ed16db6b3c
+timeCreated: 1497860655
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/EffectRenderSort.cs b/Utility/EffectRenderSort.cs
new file mode 100644
index 0000000..1464439
--- /dev/null
+++ b/Utility/EffectRenderSort.cs
@@ -0,0 +1,21 @@
+锘縰sing System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class EffectRenderSort : MonoBehaviour
+{
+
+    [SerializeField] int m_RendererOrder;
+
+    Renderer m_Renderer;
+    new Renderer renderer { get { return m_Renderer ?? (m_Renderer = this.GetComponent<Renderer>()); } }
+
+    private void OnEnable()
+    {
+        if (renderer!=null)
+        {
+            renderer.sortingOrder = m_RendererOrder;
+        }
+    }
+
+}
diff --git a/Utility/EffectRenderSort.cs.meta b/Utility/EffectRenderSort.cs.meta
new file mode 100644
index 0000000..2430500
--- /dev/null
+++ b/Utility/EffectRenderSort.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 644f267571076be42bee2f66aba2c823
+timeCreated: 1520909627
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/EnumHelper.cs b/Utility/EnumHelper.cs
new file mode 100644
index 0000000..5d19094
--- /dev/null
+++ b/Utility/EnumHelper.cs
@@ -0,0 +1,1922 @@
+锘�
+
+public enum E_ActorClassType
+{
+    UnDefine,
+    Hero,
+    Player,
+    Guard,
+    NpcFightNorm,
+    NpcFightBoss,
+    NpcSummonFunc,
+    NpcCollect,
+    NpcSummonFight,
+    NpcFunc,
+    Pet,
+    NpcTouchKilled,
+    NpcClientFightNorm,
+    NpcClientFightBoss,
+    NpcClientFunc,
+    NpcFightVirtualPlayer,
+    PlayerXmzz,
+    ClientPlayer,
+    PlayerZZ,
+    PlayerSgzcRobot,
+    PVPClientPlayer,
+    ILClientPlayer,
+    NpcClientCollect,
+    JiaPlayer,
+
+}
+
+
+public enum E_ActorState
+{
+    Idle,
+    CtrlRun,
+    AutoRun,
+    Hurt,
+    Die,
+    CommonAtk,
+    CastSkill,
+    DaZuo,
+    Roll,
+    Mocked,
+
+}
+
+public enum E_4012Status
+{
+    Normal,//鏃� 0
+    Freezed,//瀹氳韩鐘舵�� 1
+    Slow,//鍑忛�熺姸鎬� 2
+    LoseBlood,//鎸佺画鎺夎鐘舵�� 3
+    Shield,//楹掗簾浣戣韩4
+    DamBackShield,//涓滅殗闄勪綋5
+    Sneer,//鍢茶 6
+    Stun,//鏅曠湬鐘舵�� 7
+    AddAtk,//鍔犳敾鐘舵�� 8
+    WeakDef,//鍑忛槻鐘舵�� 9
+    LimitSkill,//绂侀瓟鐘舵�� 10
+    LimitAddHP,//绂佺枟鐘舵�� 11
+    Blind,//鑷寸洸鐘舵�� 12
+    Burn,//鐏肩儳 13
+    LoseBlood2,//鑱屼笟2鎸佺画鎺夎鐘舵�� 14
+    LoseBlood3,//鑱屼笟3鎸佺画鎺夎鐘舵�� 15
+    MissSneerAtk,//瀵瑰槻璁芥敾鍑诲厤鐤〃鐜颁负miss 16
+    BeInAir,//娴┖锛堝仛娉曞悓鐪╂檿绫伙級 17
+    zqdlj,//绱皵涓滄潵閲戠伒鏍规妧鑳界姸鎬� 18
+    Ice,//瀵掑啺鐘舵�侊紙鍚屽噺閫燂級 19
+
+}
+
+
+public enum E_BuffType
+{
+    bfBuff = 1,     // buff
+    bfDeBuff,       // debuff
+    bfAura,         // aura,鍏夌幆
+    bfIncBuff,      // inc buff澧炲�糂UFF 鐜╁涓嶅彲鎵嬪姩娓呴櫎
+    btPassiveBuf,   // 琚姩BUF
+    bfEquipBuff,    // 瑁呭BUF
+    bfMapBuff,      // 鍦烘櫙BUF
+    bfActionBuff,   // 琛屼负Buf
+    bfProcessBuff,  // 涓�瀹氶棿闅斿鐞嗕竴娆℃寔缁竴瀹氭椂闂寸殑Buff
+    bfProcessDeBuff,// 涓�瀹氶棿闅斿鐞嗕竴娆★紝鎸佺画涓�瀹氭椂闂寸殑DeBuff
+
+    btBufMax        // BUF绫诲瀷鏁�
+}
+
+public enum E_MonsterType
+{
+    Normal,//0 鏅�氭��;
+    Elite,//1 绮捐嫳鎬�;
+    BlueBoss,//2 钃滲OSS;
+    PurpleBoss,//3 绱獴OSS;
+    Danger,//4 鍗遍櫓鎬�;
+    DarkGoldBoss,//5 鏆楅噾BOSS,
+    SmallLead,//6 灏忓ご鐩�,
+    MissionBoss,//7 浠诲姟BOSS
+
+}
+
+public enum E_ActorGroup
+{
+    User,
+    Player,
+    Enemy,
+    Neutral,
+    Collect,// 鏀堕泦绫�
+    FuncNpc,// 鍔熻兘鎬pc
+
+}
+
+
+public enum E_ClientNpcType
+{
+    Func,
+    Fight,
+
+}
+
+
+public enum E_NpcType
+{
+    Func = 0,//鍔熻兘NPC濉啓鈥�0鈥�
+    Defend = 1,//瀹堝崼NPC濉啓鈥�1鈥�
+    Fight = 2,//鎴樻枟NPC濉啓鈥�2鈥�
+    Summon = 3,//鍙敜NPC濉啓鈥�3鈥�
+    Ghost = 4,//鐏礜PC濉啓  鈥�4鈥�
+    Trap = 5,//闄烽槺NPC濉啓 "5"
+    Car = 6,//闀栬溅NPC濉啓 "6"
+    Sprite = 7,//绮剧伒NPC濉啓 "7"
+    VirtualPlayer = 8,// 铏氭嫙鍔╂垬鑻遍泟
+    Flag = 9,//鏃楃被NPC濉啓 "9"
+    Collect = 14,//閲囬泦NPC濉畾 "14"
+    Catch = 15,//鍙崟鎹夛籍锛帮迹銆�15
+    Pet = 16,//瀹犵墿         16
+    TouchKilled = 17,//瀹堟姢     17
+    FMBoss = 18,// 灏侀瓟鍧沚oss    18
+    BreakableObj = 19,//鍦烘櫙鍙鏀诲嚮鐗�     19
+    FightAssist = 20,// 鍔╂垬
+    SGZC_FightAssist = 21,// 涓婂彜鎴樺満鍔╂垬
+    MonsterTime = 22,// 鎸夋椂闂存帀琛�
+    PersonalEnemy = 23,// 涓撳睘鏁屼汉
+    PersonalEnemyPVP = 24,// 涓撳睘鏁屼汉
+
+    OpenWorldMap = 99,// 鎵撳紑涓栫晫鍦板浘
+}
+
+
+public enum E_MovingState
+{
+    Normal,
+    Fly,
+    Ride,
+
+}
+
+
+public enum WindowType
+{
+    Base = 0,
+    Normal = 1,
+    Modal = 2,
+    Tip = 3,
+    System = 4,
+    Loading = 5,
+
+    Flag = 99,
+}
+
+
+public enum GestureType
+{
+    Left,
+    Right,
+    Up,
+    Down
+}
+
+
+public enum UnityPlatform
+{
+    Editor,
+    Android,
+    Iphone,
+    Standalone,
+}
+
+
+public enum RoleRenameResult
+{
+    MoneyErr = 0, //閲戦挶涓嶈冻
+    NameRuleErr = 1, //鍚嶅瓧涓嶅悎娉�
+    NameLengErr = 2, //鍚嶅瓧闀垮害閿欒
+    NameRepeatErr = 3, //閲嶅悕
+    RenameFailErr = 4, //鏀瑰悕澶辫触
+    RenameSuccess = 5, //鎴愬姛
+}
+
+
+/// <summary>
+/// <para>鏃犳剰涔� 0</para>
+/// <para>鑷繁 1</para>
+/// <para>闃熶紞 2</para>
+/// <para>鍙嬪ソ 3</para>
+/// <para>鍙敾鍑� 4</para>
+/// <para>鑷繁鍙婂弸濂� 5</para>
+/// <para>鐜╁灏镐綋 6</para>
+/// <para>闈炴浜$帺瀹� 7</para>
+/// <para>鍙敾鍑绘�墿 8</para>
+/// <para>鍙敾鍑荤帺瀹� 9</para>
+/// <para>鎵�鏈夊崟浣� 10</para>
+/// <para>瀹犵墿瀵逛富浜� 11</para>
+/// <para>鍙敜鐗╁涓讳汉 12</para>
+/// <para>灏忔�寘鎷簿鑻� 13</para>
+/// </summary>
+public enum E_SkillCastTarget
+{
+    None,
+    Self,
+    TeamMate,
+    Friend,
+    CanAttacked,
+    SelfAndFriend,
+    PlayerDeadBody,
+    UnDeadPlayer,
+    CanAttackedMonster,
+    CanAttackedPlayer,
+    All,
+    PetToOwner,
+    SummonToOwner,
+    Monster,
+    FriendNpc,
+
+}
+
+
+/// <summary>
+/// 鎶�鑳界被鍨�
+/// </summary>
+public enum E_SkillType
+{
+    Special, // 鐗规畩   0
+    Attack, // 鏀诲嚮绫�   1
+    Recover,// 鎭㈠绫�   2
+    ContinuousGain, // 鎸佺画澧炵泭BUFF  3
+    SustainedReduction,// 鎸佺画鍑忕泭BUFF  4
+    GainBuff,// 澧炵泭BUFF 5
+    ReductionBuff,// 鍑忕泭BUFF 6
+    Passive,// 琚姩鎶�   7
+    Reborn,// 澶嶆椿     8
+    ValueAdded,// 澧炲�兼妧鑳斤紙涓嶅彲娓呴櫎锛�9  
+    Halo,// 鍏夌幆鎶�鑳�  10
+    Equip,// 瑁呭鎶�鑳�  11
+    Area,// 鍖哄煙鎶�鑳�  12
+    Summon,// 鍙敜      13
+    ControlBuff,// 鎺у埗鍨婤UFF 14
+    MutilHurtBuffAtk,// 澶氭浼ゅbuff鏀诲嚮绫诲瀷锛堢被xp鎶�鑳斤級 15
+    PassiveGainBuff,// 琚姩瑙﹀彂澧炵泭绫籦uff 16
+    PassiveReductionBuff,// 琚姩瑙﹀彂鍑忕泭绫籦uff 17
+    PassiveControlBuff,// 琚姩瑙﹀彂鐨勬帶鍒剁被buff 18
+    Property,// 灞炴�х被鎶�鑳� 20锛堝鍧愰獞灞炴�э紝瀹犵墿灞炴�э級
+    PassiveBuff,// 琚姩buff 19锛堟殏鏃朵笉鐭ラ亾骞插暐鐨勶級
+    PassiveContinuousGain,// 琚姩瑙﹀彂鎸佺画绫诲鐩婄被buff 21
+    PassiveSustainedReduction,// 琚姩瑙﹀彂鎸佺画绫诲噺鐩婄被buff 22
+
+}
+
+
+public enum E_SkillFuncType
+{
+    Common,// 0涓洪�氱敤鎶�鑳�
+    FaBaoActiveSkill,// 1涓烘硶瀹濆姛鑳借幏寰楃殑涓诲姩鎶�鑳�
+    FaBaoPassiveSkills,// 2涓烘硶瀹濆姛鑳借幏寰楃殑琚姩鎶�鑳�
+    FaBaoSpSkill,// 3涓烘硶瀹濆姛鑳借幏寰楃殑SP鎶�鑳�
+    TalentSkills,// 4涓哄ぉ璧嬫妧鑳�
+    RiderSkill,// 5涓哄潗楠戞妧鑳�
+    PetSkill,// 6涓哄疇鐗╂妧鑳�
+    GodWeaponSkill,// 7涓虹鍏垫妧鑳�
+    NormalAttack,// 8涓烘櫘鏀�
+    SpLv15Skill,// 9涓簊p15绾ф妧鑳�
+    Roll,// 10涓虹炕婊�
+    RealmSkill,// 11涓哄鐣�
+    MythicalAnimal,// 12涓虹鍏芥妧鑳�
+    ZhuxianSkill,// 13涓鸿瘺浠欐妧鑳�
+
+}
+
+
+/// <summary>
+/// <para>鏃犲璞� 0</para>
+/// <para>鏈夊璞� 1</para>
+/// <para>鍦伴潰 2</para>
+/// </summary>
+public enum E_SkillCastType
+{
+    None,// 鏃犲璞� 0
+    NeedTarget,// 鏈夊璞� 1
+    Ground,// 鍦伴潰 2
+}
+
+
+public enum MapTransferType
+{
+    WorldTransport = 1,
+    BigMapTransport = 2,
+    MissionTransport = 3,
+
+}
+
+
+public enum DropItemType
+{
+    Pattern0 = 0,
+    Pattern1 = 1,
+    Pattern2 = 2,
+    Pattern3 = 3,
+
+}
+
+
+public enum DailyQuestType
+{
+    BountyMission = 1,
+    IceCrystal = 2,
+    FairyFeast = 3,
+    BlastStove = 4,
+    Kirin = 5,
+    FairyLand = 6,
+    GuardSky = 7,
+    Demon = 8,
+    Trial = 9,
+    AncientBattleGround = 10,
+    EmperorRelic = 11,
+    WyTaiChi = 12,
+    FairyLeague = 13,
+    HeavenBattle = 14,
+    Prayer = 15,
+    WorldBoss = 16,
+    DemonJar = 17,
+    FairyTask = 18,
+    RuneTowerSweep = 19,
+    RuneTower = 21,
+    TreasureCollectSoul = 22,
+    BossHome = 24,
+    PersonalBoss = 25,
+    ElderGodArea = 26,
+    FairyGrabBoss = 27,
+    KillMonster = 28,
+    DungeonAssist = 29,
+    GatherSoulDungeon = 30,
+    CrossServerPk = 31,
+    AllianceBoss = 32,
+    RidingPetActivity = 34,
+    HazyRegion = 35,
+    SkyTower = 36,
+    Auction = 37,
+    JadeDynastyBoss = 38,
+    CrossServerBoss = 39,
+    FairyChuanGong = 40, //浠欑洘浼犲姛
+    ActivityPlace = 41, //绉樺鎺㈢储
+    ArenaPK = 43,//绔炴妧鍦篜K
+    //鍚庣画IL寮�鍙戞坊鍔犻璁�
+    default1,
+    default2,
+    default3,   //46 浠欑洘鎵撳潗
+    default4,   //47 鍙ょ鎴樺満
+    default5,   //48 閫氱敤鍓湰
+    default6,   //49 閫氱敤鍓湰
+    default7,   //50 閫氱敤鍓湰
+    default8,   //51 閫氱敤鍓湰
+    default9,   //52 鑱氶瓊閫氱敤鍓湰
+    default10,
+    default11,
+    default12,
+    default13,
+    default14,
+    default15,
+    default16,
+    default17,
+    default18,
+    default19,
+    default20,
+}
+
+
+/// <summary>
+/// 鏈嶅姟绔笅鍙戠殑鍓湰鍊掕鏃剁被鍨�
+/// </summary>
+public enum DungeonCoolDownType
+{
+    LeaveMap = 0,//閫�鍑哄�掕鏃�
+    WaitStart = 1,//寮�濮嬪�掕鏃�
+    FightStart = 2,//鎴樻枟鍊掕鏃�
+    FlagTake = 3,
+    NextRound = 4,//涓嬩竴娉㈠�掕鏃�
+    FBAddTime = 6,
+    ElderGodAreaDeadTime = 7,//鍙ょ绂佸湴鍊掕鏃�
+    PickUpTime = 8,//鍓湰鎹¤澶囧�掕鏃�
+    WaitPlayer = 9, //绛夊緟瀵规墜鍊掕鏃�
+    PlayerLeave = 10, //瀵规墜鎺夌嚎鍊掕鏃�
+
+}
+
+
+/// <summary>
+/// 瑁呭閮ㄤ綅绱㈠紩
+/// </summary>
+public enum RoleEquipType
+{
+    Weapon = 1,         // 涓绘墜
+    Weapon2 = 2,       // 鍓墜
+    Hat = 3,                // 甯藉瓙
+    Clothes = 4,          // 琛f湇
+    Belt = 5,                // 鑵板甫
+    Trousers = 6,         // 瑁ゅ瓙
+    Shoes = 7,             // 闉嬪瓙
+    Glove = 8,              //鎵嬪
+    Neck = 9,               //椤归摼
+    FairyCan1 = 10,      //浠欏櫒
+    FairyCan2 = 11,      //浠欏櫒
+    Jade = 12,              //鐜変僵
+
+    Wing = 13,               //缈呰唨
+    Guard = 14,            //瀹堟姢
+
+    PeerlessWeapon1 = 16,//缁濅笘姝﹀櫒
+    PeerlessWeapon2 = 17,//缁濅笘鍓墜
+
+    Mount = 19,              //褰撳墠鐨勫潗楠�
+
+    FashionWeapon = 20,//鏃惰姝﹀櫒
+    FashionClothes = 21, //鏃惰琛f湇
+    FashionWeapon2 = 22,//鏃惰鍓墜
+
+
+    retMax,
+};
+
+
+
+//tagObjInfoRefresh,鏇存柊鏋氫妇鍊煎繀椤诲悓鏃舵洿鏂版敞閲�
+/**涓昏灞炴�у埛鏂扮被鍨�*/
+public enum PlayerDataType
+{
+    AccountID = 0,             //甯愬彿鍚�   璇ヨ鑹叉墍鍦ㄧ殑甯愬彿鐨勭敤鎴峰悕 0,
+    PlayerID = 1,                     //瑙掕壊ID,1,
+    PlayerName = 2,                   //瑙掕壊鍚�,size , 14  2,
+    Sex = 3,                          //鎬у埆    3,
+    Hair = 4,                         //鍙戝瀷  1.鏍囧噯鍨嬶紙鐢凤級 2.鍚嶄粫鍨� 3.娴瓙鍨� 4.鏍囧噯鍨嬶紙濂筹級 5.椹鍨� 6.濡╁獨鍨�    4,
+    HairColor = 5,                    //澶村彂棰滆壊  5绉�  5,
+    Face = 6,                         //鍩烘湰鑴稿瀷 6,
+    Job = 7,                          //鑱屼笟  
+    LV = 8,                           //绛夌骇 8,
+    TotalExp = 9,                     //鎬荤粡楠�    9,
+    Family = 10,                       //瀹舵棌 10,
+    Country = 11,                       //鍥藉  0.绉﹀浗 1.榄忓浗 2.妤氬浗   闃佃惀   11,
+    TeamHornor = 12,                    //缁勯槦鑽h獕   12,
+    PKValue = 13,                      //PK鍊� 13,
+    FamilyHornor = 14,                  //瀹舵棌璐$尞 14,
+    FamilyActiveValue = 15,             //瀹舵棌娲昏穬搴� 15,
+    CountryHornor = 16,                 //鏈懆鍥藉鑽h獕鍊�   16,
+    Mate = 17,                         //浼翠荆,17,
+    Gold = 18,                          //閲戝瓙   18,
+    GoldPaper = 19,                     //閲戠エ  19,
+    Silver = 20,                       //閾跺瓙 20,
+    SilverPaper = 21,                  //閾剁エ    21,
+    FightPoint = 22,                   //鎴樻枟鍊�  22,
+    HappyPoint = 23,                   //濞变箰鍊�  23,
+    MapID = 24,                        //瑙掕壊鎵�鍦ㄥ湴鍥�  24,
+    PosX = 25,                         //瑙掕壊鍧愭爣 25,
+    PosY = 26,                         //26,
+    State = 27,                        //瑙掕壊鐘舵��   1.灏佸瓨 2.姝讳骸 3.姝e父  浠ュ悗杩樻湁闄嗙画娣诲姞 27,
+    MaxHP = 28,                        //鏈�澶P    28,
+    HP = 29,                           //褰撳墠HP   29,
+    MaxMP = 30,                        //鏈�澶P    30,
+    MP = 31,                           //褰撳墠MP   31,
+    XP = 32,                           //褰撳墠XP   32
+    HPRestoreSetting = 33,             //灏戜簬杩欎釜鍊�%鑷姩鍠濊 33,
+    MPRestoreSetting = 34,             //灏戜簬杩欎釜鍊�%鑷姩鍠濋瓟 34,
+    ExpRate = 35,                      //褰撳墠缁忛獙鍊嶇巼    鍗曚綅涓虹櫨鍒嗘瘮  35,
+    FreePoint = 36,                    //鏈垎閰嶇偣鏁� 36,
+    FreeSkillPoint = 37,               //鏈垎閰嶆妧鑳界偣鏁�   37,
+    STR = 38,                          //鍔涢噺    38,
+    PNE = 39,                          //鐏靛姏    39,
+    PHY = 40,                          //韬硶    40,
+    CON = 41,                          //浣撹川    41,
+    DEF = 42,                          //闃插尽    42,
+    MINATK = 43,                        //澶栨敾鏈�灏� 43
+    MAXATK = 44,                        //澶栨敾鏈�澶� 44
+    MAtkMin = 45,                       //鍐呭姛鏈�澶� 45
+    MAtkMax = 46,                       //鍐呭姛鏈�灏� 46
+    MDef = 47,                          //鍐呴槻     47
+    HIT = 48,                           //鍛戒腑 48
+
+    POISIONATK = 49,                    //姣掓敾 49
+    FIREATK = 50,                       //鐏敾 50
+    REALATK = 51,                        //鐪熷疄浼ゅ 51
+    THUNDERATK = 52,                    //闆锋敾 52
+    WINDATK = 53,                       //椋庢敾 53
+    POISIONDEF = 54,                    //姣掗槻 54
+    FIREDEF = 55,                       //鐏槻 55
+    REALDEF = 56,                        //鐪熷疄鎶垫姉 56
+    THUNDERDEF = 57,                    //闆烽槻 57
+    WINDDEF = 58,                       //椋庨槻 58
+
+    Miss = 59,                         //闂伩   59,
+    SuperHit = 60,                     //鏆村嚮浼ゅ 60,
+    Buff = 61,                         //鏈�澶�12涓狟UFF 濡傛灉瓒呰繃12涓寜鍏堣繘鍏堝嚭鐨勯『搴忚鐩�  61,
+    Skill = 62,                        //璇ョ帺瀹舵墍瀛︿細鐨勫叏閮ㄦ妧鑳� 鐩墠鏈�澶�22涓� 鏃ュ悗鍙兘鍐嶅鍔�   62,
+    Mark = 63,                         //绉板彿璇ョ帺瀹舵墍鎷ユ湁鐨勫叏閮ㄧО鍙凤紝涓婇檺鏈畾   63,
+    SettingH = 64,                     //蹇嵎鏍忥紙妯級   64,
+    SettingV = 65,                     //蹇嵎鏍忥紙绔栵級   65,
+    FightPK = 66,                      //琛¢噺PK鑳藉姏鐨勪竴椤瑰睘鎬� 鐢辨敾闃茶绠楄�屽緱   66,
+    ActiveValue = 67,                  //鍑绘潃鏁屽浗闃佃惀鐜╁鍜孨PC鐨勭粺璁″��    67,
+    PlayerType = 68,                   //瑙掕壊鐨勪簲琛屽睘鎬э紝缁勯槦鐢� 1. 閲� 2. 鏈� 3. 姘� 4. 鍦� 5. 鐏�   68,
+    NameColor = 69,                    //瑙掕壊鍚嶅瓧棰滆壊  69,
+    AtkInterval = 70,                  //鏀诲嚮閫熷害 70,
+    Speed = 71,                        //閫熷害   71,
+    SuperHitRate = 72,                 //鏆村嚮鐜� 72,
+    PickupDist = 73,                   //鎷惧彇璺濈 73,
+    CountryLastWeekHornor = 74,        //涓婂懆鍥藉鑽h獕鍊�   74,
+    LastWeekOnlineTime = 75,           //涓婂懆鍦ㄧ嚎鏃堕棿  75,
+    LastWeekFamilyActiveValue = 76,    //涓婂懆娲昏穬搴�  76,
+    FBID = 77,                         //鐜╁鐨勫壇鏈琁D    77,
+    FamilyLV = 78,                     //瀹舵棌绛夌骇 78,
+    RealMapID = 79,                    //鏁版嵁鍦板浘ID   79,
+    GMLevel = 80,                      //gm绛夌骇鏀瑰彉   80,
+    TeamID = 81,                       //gm绛夌骇鏀瑰彉    81,
+    TeamLV = 82,                       //gm绛夌骇鏀瑰彉    82,
+    FightPower = 83,                    //鎴樻枟鍔�    83,
+    RebornMapID = 84,                   //閲嶇敓鍦板浘ID  84,
+    RebornPosX = 85,                    //閲嶇敓鐐箈   85,
+    RebornPosY = 86,                    //閲嶇敓鐐箉   86,
+    Coin = 87,                         //褰撳墠鐐瑰埜鏁扮洰   87,
+    BillboardLV = 88,                  //鎺掕姒滅瓑绾�  88,
+    Tick = 89,                         //褰撳墠Tick   89,
+    CurrentPlayerType = 90,            //褰撳墠浜旇 90,
+    FriendFavor = 91,                   //濂藉弸浜烘皵鍊煎埛鏂�   91
+    BackpackLV = 92,                    //鑳屽寘绛夌骇   92
+    ReincarnationLV = 93,               //杞敓绛夌骇 93
+    BaseSTR = 94,                      //瑁镐綋鍔涢噺    94,
+    BasePNE = 95,                      //瑁镐綋绮剧    95,
+    BasePHY = 96,                      //瑁镐綋鏁忔嵎    96,
+    BaseCON = 97,                      //瑁镐綋浣撹川    97,
+    //  BaseINT ,                      //瑁镐綋鏅哄姏
+    //  BaseLUCK ,                     //瑁镐綋骞歌繍
+    ReceivedSalary = 98,                //鐜╁鏈棰嗗彇鐨勫伐璧�    98
+    WarehouseLV = 99,                   //浠撳簱绛夌骇   99
+    EquipShowSwitch = 100,               //瑁呭鏄鹃殣寮�鍏�   100
+    LuckValue = 101,                     //骞歌繍鍊�   101
+    ExAttr1 = 102,                       //鎵╁睍灞炴��1   102榄斾粏浼ゅ24
+    ExAttr2 = 103,                       //鎵╁睍灞炴��2   103缁勯槦鏄惁闇�瑕佸鏍�
+    ExAttr3 = 104,                       //鎵╁睍灞炴��3   104鍏冪礌鏀诲嚮26
+    ExAttr4 = 105,                       //鎵╁睍灞炴��4   105鍏冪礌闃插尽27
+    ExAttr5 = 106,                       //鎵╁睍灞炴��5   106
+    Faction = 107,                       //闃佃惀        107
+    InfamyValue = 108,                   //鎭跺悕鍊�      108
+    RealmLevel = 109,                  //瀹橀樁        109
+    IsFindByLabel = 110,                  //鏄惁鍏佽鏍囩妫�绱�        110
+    IsCloseFriendLabel = 111,            //鏄惁鍏抽棴濂藉弸绛惧悕        111
+    ChangeCoinPointTotal = 112,           //鍏戞崲鐨勭偣鏁版�昏        112
+    VIPLv = 113,                          //VIP绛夌骇         113
+    ExAttr6 = 114,                       //鎵╁睍灞炴��6   114娴佽浼ゅ31
+    ExAttr7 = 115,                       //鎵╁睍灞炴��7   娉曞疂sp锛岄潪浜夸綅
+    ExAttr8 = 116,                       //鎵╁睍灞炴��8   娉曞疂sp锛屼嚎浣�
+    ExAttr9 = 117,                       //鎵╁睍灞炴��9   117鎺у埗鎶垫姉34
+    ExAttr10 = 118,                       //鎵╁睍灞炴��10  118杈撳嚭浼ゅ35
+    ModelMark = 119,                       //鍙樺舰妯″瀷Mark  119
+    PrizeCoin = 120,                       //濂栧姳鐐瑰埜鏁�   120
+    ExAttr11 = 121,                       //鎵╁睍灞炴��11  121 鐜伴噾浠e竵锛堜唬閲戝埜锛�
+    ExAttr12 = 122,                       //鎵╁睍灞炴��12 閫�鍑轰粰鐩熸椂闂�
+    ExAttr13 = 123,                       //鎵╁睍灞炴��13 鏈嶅姟鍣ㄧ粍ID
+    ExAttr14 = 124,                       //鎵╁睍灞炴��14  124
+
+    SkillAtkRate = 125,                  ///鎴樻枟灞炴��--鎶�鑳芥敾鍑讳激瀹�     125
+    LuckyHitRate = 126,                  ///鎴樻枟灞炴��--浼氬績涓�鍑绘満鐜囦竾鍒嗙巼  126
+    LuckyHitVal = 127,                   ///鎴樻枟灞炴��--浼氬績涓�鍑婚澶栦激瀹�    127
+    GreatHitRate = 128,                  ///鎴樻枟灞炴��--鍗撹秺涓�鍑绘満鐜囦竾鍒嗙巼  128
+    GreatHitVal = 129,                   ///鎴樻枟灞炴��--鍗撹秺涓�鍑婚澶栦激瀹�    129
+    KillBackHP = 130,                    ///鎴樻枟灞炴��--鏉�鎬洖琛�            130
+    KillBackMP = 131,                    ///鎴樻枟灞炴��--鏉�鎬洖榄�            131
+    DamageReduceRate = 132,              ///娌℃湁浣跨敤
+    DamageBackRate = 133,                ///鎴樻枟灞炴��--鍙嶄激涓囧垎姣�          133
+    GoldFoundRate = 134,                 ///鎴樻枟灞炴��--閲戦挶瀵昏幏鍔犳垚涓囧垎姣�  134
+    IgnoreDefRate = 135,                 ///鎴樻枟灞炴��--鏃犺闃插尽鏈虹巼涓囧垎鐜�  135
+    BattleValEx1 = 136,                  ///鎴樻枟灞炴��--鎵╁睍1 鏀婚��              136
+    BattleValEx2 = 137,                  //鎴樻枟灞炴��--鎵╁睍2   鏀诲嚮鍥炶            137
+    BattleValEx3 = 138,                  //鎴樻枟灞炴��--鎵╁睍3               138  澧炰激
+    BattleValEx4 = 139,                  //鎴樻枟灞炴��--鎵╁睍4               139
+    BattleValEx5 = 140,                  //鎴樻枟灞炴��--鎵╁睍5               140
+    HPRestorePer = 141,                  //鐢熷懡鍥炲                141
+    LVEx = 142,                          //鐜╁绛夌骇鍓湰锛岀敤浜庤浆鐢�        142
+    LV2 = 143,                           //澶у笀绛夌骇                      143
+    ExpPoint = 144,                      //鎵╁睍缁忛獙鐐规暟                  144
+    OperateInfo = 145,                   //鐜╁杩愯惀鍟嗛檮鍔犱俊鎭紝濡俀Q榛勯捇绛�145
+    SuperHitReduce = 146,                //鏆村嚮鎶楁��                   146
+    LuckyHitRateReduce = 147,                //浼氬績涓�鍑绘姉鎬�                   147
+    SkillAtkRateReduce = 148,               ///鎶�鑳藉噺浼�
+    DamagePVP = 149,                      //PVP澧炲姞浼ゅ       149 瀵瑰簲191 PVP澧炲姞鍑忓皯
+    SpeedValue = 150,                  //绉诲姩閫熷害                 150
+    DamagePVE = 151,                  ///鏆傛椂娌$敤                 151
+    PetDamPer = 152,                  //鐏靛吔澧炲姞浼ゅ                 152
+    IgnoreDefRateReduce = 153,                  //鏃犺闃插尽鎶楁��        153
+    DamChanceDef = 154,                  //鎶靛尽        154
+    BleedDamage = 155,                      //娴佽浼ゅ 155
+    FaintRate = 156,                    //鍑绘檿 156
+    FaintDefRate = 157,                       //鎺у埗鎶垫姉 157
+    FinalHurt = 158,                       //杈撳嚭浼ゅ158
+    FinalHurtReduce = 159,                //鍑忓皯鎵垮彈浼ゅ 159
+    DamagePerPVP = 160,              //PVP澧炲姞浼ゅ 160
+    DamagePerPVPReduce = 161,              //PVP鍑忓皯浼ゅ 161
+    ComboDamRate = 162,                    //杩炲嚮鍑犵巼162
+    ComboDamPer = 163,                    //杩炲嚮浼ゅ163
+    MaxProDef = 164,                    //鏈�澶ч槻鎶ゅ�� 164
+    FamilyContribution = 167,              //浠欑洘璐$尞搴�     167
+    FamilyStoreScore = 168,                //鑾峰彇浠欑洘浠撳簱绉垎
+    RuneSplinters = 169,                  //绗﹀嵃绮惧崕        169
+    Rune = 170,                  //绗﹀嵃纰庣墖        170
+    RealmPoint = 171,           //澧冪晫淇偧鐐�       171
+    MagicEssence = 172,//榄旂簿 172
+    UnionLiven = 173, //浠欑洘娲昏穬浠�
+    FBHelpPoint = 174,       //鍓湰鍔╂垬绉垎  174
+    PlayerPKState = 175, //鎴樻枟鐘舵��
+    IsAttackBossState = 176,  //鏄惁鍦ㄦ墦Boss 1 鍦� 0 涓嶅湪
+    BasicsMinimum = 177,//鍩虹鏈�灏忔敾鍑�
+    BasicsMaxAttack = 178,//鍩虹鏈�澶ф敾鍑�
+    BasicsLife = 179,//鍩虹鐢熷懡
+    BasicsDefense = 180,//鍩虹闃插尽
+    BasicsScoreAHit = 181,//鍩虹鍛戒腑
+    BasicsDodge = 182,//鍩虹闂伩
+    OnlyFinalHurt = 183,// 棰濆浼ゅ闄勫姞
+    CDBPlayerRefresh_ForbidenTalk = 184,//绂佽█
+    CDBPlayerRefresh_FuncDef = 185,  // 鍔熻兘灞傞槻寰�  185
+    CDBPlayerRefresh_TreasureScore = 186, //瀵诲疂鍟嗗簵绉垎
+    CDBPlayerRefresh_Danjing = 187,              // 涓圭簿 187
+    CDBPlayerRefresh_NPCHurtAddPer,//瀵规�墿浼ゅ鍔犳垚 188
+    FunalHurtPer = 189,// 鏈�缁堜激瀹冲姞鎴�
+    CDBPlayerRefresh_TalentPoint = 190,
+    CDBPlayerRefresh_GodWeaponLV_1 = 192,
+    CDBPlayerRefresh_GodWeaponLV_2 = 193,
+    CDBPlayerRefresh_GodWeaponLV_3 = 194,
+    CDBPlayerRefresh_GodWeaponLV_4 = 195,
+    CDBPlayerRefresh_SoulDust = 196,//鑱氶瓊-榄傚皹
+    CDBPlayerRefresh_SoulSplinters = 197,//鑱氶瓊-纰庣墖
+    CDBPlayerRefresh_SoulCore = 198,//鑱氶瓊-鏍稿績鐜�
+    CDBPlayerRefresh_Honor = 199, //# 鑽h獕鍊�
+    CDBPlayerRefresh_ZhuxianRate = 200,
+    CDBPlayerRefresh_Mater = 201, //# 鐏垫牴灞炴��-閲�
+    CDBPlayerRefresh_Wood = 202,//# 鐏垫牴灞炴��-鏈�
+    CDBPlayerRefresh_Water = 203,//# 鐏垫牴灞炴��-姘�
+    CDBPlayerRefresh_Fire = 204,//# 鐏垫牴灞炴��-鐏�
+    CDBPlayerRefresh_Earth = 205,//# 鐏垫牴灞炴��-鍦�
+    CDBPlayerRefresh_NormalHurt = 206,////灞炴�ф櫘閫氭敾鍑诲浼わ細鏅�氭敾鍑婚檮鍔犵殑鍥哄畾鍊间激瀹� 
+    CDBPlayerRefresh_NormalHurtPer = 207,////灞炴�ф櫘閫氭敾鍑诲浼わ細鏅�氭敾鍑婚檮鍔犵殑鍥哄畾鍊间激瀹� 
+    CDBPlayerRefresh_FabaoHurt = 208,// //灞炴�ф硶瀹濇妧鑳藉浼わ細娉曞疂鎶�鑳芥敾鍑婚檮鍔犵殑鍥哄畾鍊间激瀹�  
+    CDBPlayerRefresh_FabaoHurtPer = 209,//  //灞炴�ф硶瀹濇妧鑳藉姞鎴愶細娉曞疂鎶�鑳芥敾鍑婚檮鍔犵殑浼ゅ鐧惧垎姣� 
+    CDBPlayerRefresh_SuperHitRateReduce = 210,//鏆村嚮鎶楁��
+    CDBPlayerRefresh_LuckyHitReduce = 211,//浼氬績涓�鍑讳激瀹冲浐瀹氬�煎噺鍏�
+    CDBPlayerRefresh_FinalHurtReducePer = 212,//鏈�缁堜激瀹崇櫨鍒嗘瘮鍑忓皯
+    CDBPlayerRefresh_YinjiTime = 213,//鍗拌鎸佺画鏃堕棿锛屽崟浣嶆绉�
+    CDBPlayerRefresh_YinjiCount = 214,//鍗拌鎸佺画鏃堕棿锛屽崟浣嶆绉�
+
+    CDBPlayerRefresh_SkillAddPerA = 215,//瀹氭捣绁為拡鎶�鑳戒激瀹崇櫨鍒嗘瘮
+    CDBPlayerRefresh_SkillAddPerB = 216, //鐨撴湀鏋妧鑳戒激瀹崇櫨鍒嗘瘮
+    CDBPlayerRefresh_SkillAddPerC = 217, //楝肩墮鍒冩妧鑳戒激瀹崇櫨鍒嗘瘮
+    CDBPlayerRefresh_SkillAddPerD = 218, //纾愰緳鍗版妧鑳戒激瀹崇櫨鍒嗘瘮
+    CDBPlayerRefresh_SkillAddPerE = 219, //鏉忛粍鏃楁妧鑳戒激瀹崇櫨鍒嗘瘮
+    CDBPlayerRefresh_SkillAddPerF = 220,//鍡滃ぉ鏂ф妧鑳戒激瀹崇櫨鍒嗘瘮
+    CDBPlayerRefresh_SkillAddPerG = 221, //灏勬棩绁炲紦鎶�鑳戒激瀹崇櫨鍒嗘瘮
+    CDBPlayerRefresh_SkillReducePerA = 222, //瀹氭捣绁為拡鎶�鑳藉噺浼ょ櫨鍒嗘瘮
+    CDBPlayerRefresh_SkillReducePerB = 223, //鐨撴湀鏋妧鑳藉噺浼ょ櫨鍒嗘瘮
+    CDBPlayerRefresh_SkillReducePerC = 224, //楝肩墮鍒冩妧鑳藉噺浼ょ櫨鍒嗘瘮
+    CDBPlayerRefresh_SkillReducePerD = 225, //纾愰緳鍗版妧鑳藉噺浼ょ櫨鍒嗘瘮
+    CDBPlayerRefresh_SkillReducePerE = 226, //鏉忛粍鏃楁妧鑳藉噺浼ょ櫨鍒嗘瘮
+    CDBPlayerRefresh_SkillReducePerF = 227, //鍡滃ぉ鏂ф妧鑳藉噺浼ょ櫨鍒嗘瘮
+    CDBPlayerRefresh_SkillReducePerG = 228, //灏勬棩绁炲紦鎶�鑳藉噺浼ょ櫨鍒嗘瘮
+
+    //鍚庣画IL寮�鍙戞坊鍔犻璁�
+    default1,   // 229 
+    default2,   //230
+    default3,   // 鍔熻兘鐗规潈浠� 231
+    default4,   //  鐜繚鍊� 232
+    default5,   // 233浠欑帀璐熸暟 
+    default6,   // 234鐏电煶璐熸暟
+    default7,   
+    default8,
+    default9,   // 237 鍦板浘澧冪晫闅惧害
+    default10,  // 238 绂诲紑浠欑洘鏃堕棿鎴筹紙鍖呭惈涓诲姩閫�鍑烘垨琚涪
+    default11,  // 239 浠h〃榄呭姏绛夌骇
+    default12,
+    default13,  // 241 鍙ょ璐у竵
+    default14,  // 242 鍔熷痉鐐�
+    default15,
+    default16,
+    default17,  // 245 鏈虹紭鐐�
+    default18,
+    default19,  // 247 鎴愬氨绉垎
+    default20,  // 248 涓囩晫绉垎
+    default21,
+    default22,
+    default23,
+    default24,
+    default25,
+    default26,
+    default27,
+    default28,
+    default29,
+    default30,
+    default31,
+    default32,
+    default33,
+    default34,  // 262 鍑瘉绉垎
+    default35,  // 263 鑱氶瓊绮惧崕
+    default36,  // 264 Boss鏈�缁堜激瀹冲姞鎴�
+    default37,  // 265 楠戝疇绉垎
+    default38,  // 266 鍙ゅ疂鍏绘垚璐у竵
+    default39,  // 267 澶╅亾甯�
+    default40,
+    default41,  // 269 杩囨湡鍨嬩唬閲戝埜
+    default42,  // 270 浠欑紭绉垎
+    default43,  // 271 骞诲闃佺Н鍒�
+    default44,  
+    default45,
+    default46,
+    default47,
+    default48,
+    default49,
+    default50,
+};
+
+
+/** 鑳屽寘绫诲瀷鐮佸畾涔� */
+public enum PackType
+{
+    Deleted = 0, // 宸插垹闄ょ墿鍝侊紝寮冪敤
+    Equip = 1, // 瑁呭
+    Item = 2, // 鐗╁搧
+    Warehouse = 5, // 浠撳簱
+    Horse = 12, // 鍧愰獞鑳屽寘
+    AnyWhere = 13, // 涓囪兘鑳屽寘
+    InterimPack = 28,//涓存椂浜ゆ崲鑳屽寘
+    Treasure = 30, // 瀵诲疂鑳屽寘
+    PetPack = 31, //瀹犵墿鑳屽寘
+    DogzItem = 32, //绁炲吔鐗╁搧鑳屽寘
+    DogzEquip = 33, //绁炲吔瑁呭鑳屽寘锛堢鍏界┛鎴达級
+
+    //鍚庣画IL寮�鍙戞坊鍔犻璁�
+    default1,   //34 鍨冨溇鍥炴敹
+    default2,
+    default3,
+    default4,
+    default5,
+    default6,
+    default7,
+    default8,
+    default9,
+    default10,
+
+    GatherSoul = 254,//鑱氶瓊
+    RunePack = 255,//绗﹀嵃鑳屽寘
+}
+
+
+public enum ItemType
+{
+    Copper = 1,// 閾滈挶
+    Drugs = 7,// 鑽搧
+    Buff = 9, //Buff绫诲瀷
+    Gemstone = 25,// 瀹濈煶
+    ComposeSuitStone = 35, //濂楄鐭崇鐗�
+    WingsMat = 39,              //鍚堟垚缈呰唨鏉愭枡锛岀窘缈肩簿鐐兼潗鏂�
+    DropCopper = 43,           // 鎺夎惤閾滈挶
+    VipTools = 80,                 //vip閬撳叿
+    Box = 81,                         //瀹濈
+    Equip_Weapon = 101,         // 涓绘墜
+    Equip_Weapon2 = 102,       // 鍓墜
+    Equip_Hat = 103,                // 甯藉瓙
+    Equip_Clothes = 104,          // 琛f湇
+    Equip_Belt = 105,                // 鑵板甫
+    Equip_Trousers = 106,         // 瑁ゅ瓙
+    Equip_Shoes = 107,             // 闉嬪瓙
+    Equip_Glove = 108,              //鎵嬪
+    Equip_Neck = 109,               //椤归摼
+    Equip_FairyCan1 = 110,       //浠欏櫒
+    Equip_FairyCan2 = 111,       //浠欏櫒
+    Equip_Jade = 112,               //鐜変僵
+    Equip_Wing = 113,              // 缈呰唨
+    Guard_1 = 114,                  // 鐏靛畧 1
+    Guard_2 = 115,                   //鐏靛畧 2
+    
+}
+
+
+public enum MakeType
+{
+    OneKeySell = 3,          // 涓�閿嚭鍞洖搴�
+    EquipStarUpgrade = 8,         // 瑁呭鍗囨槦
+    ItemCompound = 13,      // 鐗╁搧鍚堟垚
+    DrugRefine = 18,            // 鐐间腹
+    DrugRecycle = 20, //涓硅嵂鍥炴敹
+    DogzEquipPlus = 21,// 绁炲吔瑁呭寮哄寲 
+    RuneCompound = 22,//绗﹀嵃鍚堟垚
+    GatherSoulCompound = 23,//鑱氶瓊鍚堟垚
+    GatherSoulDecompose = 24,//鑱氶瓊鍒嗚В
+
+}
+
+
+/// <summary>
+/// 绉板彿绫诲瀷
+/// </summary>
+public enum TitleType
+{
+    None = -1,
+    Get = 0,//宸茶幏寰�
+    Activity = 1, //娲诲姩绉板彿
+    Vip = 2,       //VIP绉板彿
+    Achivement = 3, //鎴愬氨绉板彿
+    UserDefined = 4, //鑷畾涔�
+
+}
+
+
+//鍔熻兘寮�鍚檺鍒剁被鍨�
+public enum FuncOpenEnum
+{
+    Strength = 1,//瑁呭寮哄寲
+    Gem = 2,//瀹濈煶闀跺祵
+    Wing = 3,//缈呰唨
+    Pet = 6,//鐏靛疇
+    Treasure = 7,//娉曞疂
+    Mounts = 8,//鍧愰獞
+    Rune = 9,//绗﹀嵃
+    Realm = 12, //澧冪晫
+    Fairy = 15,// 浠欑洘
+    FairyTask = 16,
+    GodWeapon = 20,  //绁炲叺
+    SelfBoss = 22,//涓汉Boss
+    Title = 24, //绉板彿
+    Talent = 149,//澶╄祴鎶�鑳�
+    Suit = 36,//濂楄杩涘寲
+    ExpPray = 60,//缁忛獙绁堟効
+    CoinPray = 61,//閾滈挶绁堟効
+    WorldLv = 71,//涓栫晫绛夌骇
+    Rank = 72,//鎺掕姒�
+    Friend = 73,//濂藉弸
+    TouchSky = 74,//鐧诲ぉ
+    Compose = 75,//鍚堟垚
+    HuntTreasure = 76,//鎵撳疂
+    Market = 77,//甯傚満
+    DayDaily = 78,//鏃ュ父
+    Store = 79,//鍟嗗煄
+    RuneTower = 80,//绗﹀嵃濉�
+    SignIn = 81,//绛惧埌
+    Potential = 82,//娼滃姏鍔犳垚
+    IceCrystal = 83,//鍐版櫠鐭胯剦
+    FairyFest = 84,//浠欑洘瀹翠細
+    Kylin = 85,//楹掗簾涔嬪簻
+    FairyLand = 86,//浠欑晫绉樺
+    BlastFurnace = 87,//鐐间腹
+    Munekado = 88,//瀹楅棬璇曠偧
+    GuardSky = 89,//瀹堝崼浜虹殗
+    WingRefine = 90,//缈呰唨绮剧偧
+    EquipRefine = 91,//瑁呭绮剧偧
+    ElderGods = 92,//鍙ょ绂佸湴
+    EquipCompose = 93,//瑁呭鍚堟垚
+    Guard = 94,//瀹堟姢
+    SkillTreasure = 95,//鎶�鑳芥硶瀹�
+    WingCompose = 97,//缈呰唨鍚堟垚
+    Demon = 98,//娣蜂贡濡栧煙
+    HappyFindTreasure = 99,//娆箰瀵诲疂
+    FightPromote = 100,//鎴樺姏鎻愬崌
+    AncientBattleGround = 101,//涓婂彜鎴樺満
+    Chat = 102,//鑱婂ぉ
+    FairyLeague = 111,//浠欑洘鑱旇禌
+    Recharge = 113,//鍏呭��
+    OpenServerRedEnvelope = 122,//寮�鏈嶇孩鍖�
+    EquipDecompose = 123, //瑁呭鍒嗚В
+    TreasureFindHost = 124, //娉曞疂璁や富
+    Dogz = 138, //绁炲吔
+    ReikiRoot = 145,//鐏垫牴
+    CrossServer = 157, //璺ㄦ湇澶╂璧�
+    CrossServerBoss = 162,
+    HazyRegion = 173,//缂ョ紙浠欏煙
+    DayOnline = 189, //姣忔棩鍦ㄧ嚎
+
+    //鍚庣画IL寮�鍙戞坊鍔犻璁�
+    default1,
+    default2,
+    default3,
+    default4,
+    default5,
+    default6,//绔炴妧鍦�
+    default7,
+    default8,
+    default9,
+    
+}
+
+
+//灞炴�х被鍨�
+public enum PropertyType
+{
+    LV = 1,//绛夌骇
+    POWER = 2,  //鍔涢噺
+    AGILITY = 3, //鏁忔嵎(韬硶)
+    PHYSIQUE = 4,//浣撹川
+    MENTALITY = 5,//鏅哄姏(鐏靛姏)
+    HP = 6, //鐢熷懡
+    ATK = 7, //鏀诲嚮
+    DEF = 8, //闃插尽
+    HIT = 9, //鍛戒腑
+    MISS = 10, //闂伩
+    ATKSPEED = 11,//鏀诲嚮閫熷害
+    CritChance = 12,//鏆村嚮鍑犵巼
+    CritHurt = 13,//鏆村嚮浼ゅ
+    CritResis = 14,//鏆村嚮鍑忎激
+    HeartHit = 15,//浼氬績涓�鍑�
+    HeartHurt = 16,//浼氬績浼ゅ
+    HeartResis = 17,//浼氬績鎶楁��
+    SkillHurt = 18,//鎶�鑳藉姞鎴�
+    PVPAddHurt = 19,//PVP澧炲姞浼ゅ
+    PVPReduceHurt = 20,//PVP鍑忓皯浼ゅ
+    LifeReply = 21,//鐢熷懡鍥炲
+    HurtReflect = 22,//浼ゅ鍙嶅皠
+    MoveSpeed = 23,//绉诲姩閫熷害
+    PetHurt = 24,//鐏靛吔浼ゅ
+    PetAddHurt = 25,//鐏靛吔澧炲姞浼ゅ
+    RealHurt = 26,//鐪熷疄浼ゅ
+    RealResis = 27,//鐪熷疄鎶垫姉
+    DefyDef = 28,//鏃犺闃插尽
+    DefyDefResis = 29,//鏃犺闃插尽鎶楁��
+    DefChance = 30,//闃插尽鍑犵巼
+    BloodHurt = 31,//娴佽浼ゅ
+    AktReplyBlood = 32,//鏀诲嚮鍥炶
+    Stun = 33,//鍑绘檿
+    CtrlResis = 34,//鎺у埗鎶垫姉
+    AddFinalHurt = 35,//闄勫姞浼ゅ
+    ReduceFinalHurt = 36,//闄勫姞浼ゅ鍑忓皯
+    PVPAddHurtPer = 37,//PVP鐧惧垎姣斿鍔犱激瀹�
+    PVPReduceHurtPer = 38,//PVP鐧惧垎姣斾激瀹冲噺灏�
+    DleHitChance = 39,//杩炲嚮鍑犵巼
+    DleHurt = 40,//杩炲嚮浼ゅ
+    BasicAtkPercent = 41, //鍩虹鏀诲嚮鐧惧垎姣�
+    BasicHpPercent = 42, //鍩虹鐢熷懡鐧惧垎姣�
+    BasicDefPercent = 43, //鍩虹闃插尽鐧惧垎姣�
+    HitPercent = 44, //鍛戒腑鐧惧垎姣�
+    DodgePercent = 45,//闂伩鐧惧垎姣�
+    KillMonsExpPercent = 46,//鏉�鎬粡楠岀櫨鍒嗘瘮
+    HorcruxBasicAttrPercent = 48, //榄傚櫒鍩虹灞炴��
+    ReduceSkillHurtPercent = 49, //鎶�鑳藉噺浼�
+    HpPercent = 50,//鐢熷懡鐧惧垎姣�
+    AtkPercent = 51, //鏀诲嚮鐧惧垎姣�
+    EveryLvAddAtk = 52, //姣�1绾�+%s鏀诲嚮
+    EveryLvAddHp = 53, //姣�1绾�+%s鐢熷懡
+    AddEquipDropPrecent = 54, //澧炲姞瑁呭鎺夎惤鐜�
+    AddCoinsPrecent = 55,//澧炲姞閲戝竵
+    AddRealHurtPer = 61,//鐧惧垎姣斿鍔犵湡瀹炰激瀹�
+    ReduceRealHurtPer = 62,//鐧惧垎姣斿噺灏戠湡瀹炰激瀹�
+    ArmorMaxHPPer = 63,//鍩虹瑁呭鐢熷懡
+    WeaponAtkPer = 65,//鍩虹瑁呭鏀诲嚮
+    ArmorDefPer = 66, //闃插叿闃插尽鐧惧垎姣�
+    MinAtk = 67, //鏈�灏忔敾鍑�
+    MaxAtk = 68, //鏈�澶ф敾鍑�
+    DefencePercent = 69,//闃插尽鐧惧垎姣�
+    CritHurtPercent = 70,//鏆村嚮浼ゅ
+    MoveSpeedPercent = 71, //绉诲姩閫熷害鐧惧垎姣�
+    MaxProDef = 72, //闃叉姢鍊�
+    ProDefHPPer = 73,//闃叉姢鍊肩櫨鍒嗘瘮
+    ProDefAbsorb = 74, //鎶ょ浘鍚告敹浼ゅ鐧惧垎姣�
+    BaseHitPer = 75, //鍩虹鍛戒腑鐧惧垎姣�
+    BaseMissPer = 76, //鍩虹闂伩鐧惧垎姣�
+    PetMinAtk = 77, //鐏靛疇鏈�灏忔敾鍑�
+    PetMaxAtk = 78, //鐏靛疇鏈�澶ф敾鍑�
+    OnlyFinalHurt = 79, //棰濆杈撳嚭浼ゅ
+    PVPAtkBackHP = 80, //PVP鏀诲嚮鍥炶
+    ChanceExpRate = 81, //缁忛獙鏆村嚮
+    HorseAtkPer = 82, //鍧愰獞鏀诲嚮
+    StoneBasePer = 83, //瀹濈煶鍩虹灞炴��
+    RealmBasePer = 84, //澧冪晫鍩虹灞炴��
+    PetSkillAtkRate = 85, //瀹犵墿鎶�鑳戒激瀹�
+    WingHPPer = 86, //缈呰唨鐢熷懡
+    SuiteBasePer = 87, //濂楄鍩虹灞炴��  
+    PlusBaseAtkPer = 88,  //寮哄寲鏀诲嚮
+    NpcHurtAddPer = 89,//鐧惧垎姣擯VE鎶�鑳藉姞鎴�
+    JobAHurtAddPer = 90,//瀵归緳榄備激瀹冲鍔犵櫨鍒嗘瘮
+    JobBHurtAddPer = 91,//瀵圭伒鐟朵激瀹冲鍔犵櫨鍒嗘瘮
+    JobCHurtAddPer = 92,//瀵瑰紦绠墜浼ゅ澧炲姞鐧惧垎姣�
+    JobAAtkReducePer = 93,//鎵垮彈榫欓瓊浼ゅ鍑忓皯鐧惧垎姣�
+    JobBAtkReducePer = 94,//鎵垮彈鐏电懚浼ゅ鍑忓皯鐧惧垎姣�
+    JobCAtkReducePer = 95, //鎵垮彈寮撶鎵嬩激瀹冲噺灏戠櫨鍒嗘瘮
+    ZXCloakAttrPer = 96, //璇涗粰路鎶灞炴�х櫨鍒嗘瘮
+    ZXMaskAttrPer = 97, //璇涗粰路闈㈢僵灞炴�х櫨鍒嗘瘮
+    ZXGloveAttrPer = 98,//璇涗粰路鎵嬪灞炴�х櫨鍒嗘瘮
+    ZXRuyiAttrPer = 99,//璇涗粰路濡傛剰灞炴�х櫨鍒嗘瘮
+    ZXPendantAttrPer = 100, //璇涗粰路鍚婂潬灞炴�х櫨鍒嗘瘮
+    ZXRingAttrPer = 101, //璇涗粰路鎴掓寚灞炴�х櫨鍒嗘瘮
+    SkillAddPerA = 102,//瀹氭捣绁為拡鎶�鑳戒激瀹崇櫨鍒嗘瘮
+    SkillAddPerB = 103, //鐨撴湀鏋妧鑳戒激瀹崇櫨鍒嗘瘮
+    SkillAddPerC = 104, //楝肩墮鍒冩妧鑳戒激瀹崇櫨鍒嗘瘮
+    SkillAddPerD = 105, //纾愰緳鍗版妧鑳戒激瀹崇櫨鍒嗘瘮
+    SkillAddPerE = 106, //鏉忛粍鏃楁妧鑳戒激瀹崇櫨鍒嗘瘮
+    SkillAddPerF = 107,//鍡滃ぉ鏂ф妧鑳戒激瀹崇櫨鍒嗘瘮
+    SkillAddPerG = 108, //灏勬棩绁炲紦鎶�鑳戒激瀹崇櫨鍒嗘瘮
+    SkillReducePerA = 109, //瀹氭捣绁為拡鎶�鑳藉噺浼ょ櫨鍒嗘瘮
+    SkillReducePerB = 110, //鐨撴湀鏋妧鑳藉噺浼ょ櫨鍒嗘瘮
+    SkillReducePerC = 111, //楝肩墮鍒冩妧鑳藉噺浼ょ櫨鍒嗘瘮
+    SkillReducePerD = 112, //纾愰緳鍗版妧鑳藉噺浼ょ櫨鍒嗘瘮
+    SkillReducePerE = 113, //鏉忛粍鏃楁妧鑳藉噺浼ょ櫨鍒嗘瘮
+    SkillReducePerF = 114, //鍡滃ぉ鏂ф妧鑳藉噺浼ょ櫨鍒嗘瘮
+    SkillReducePerG = 115, //灏勬棩绁炲紦鎶�鑳藉噺浼ょ櫨鍒嗘瘮
+    Luck = 120,//姘旇繍
+    LuckPer = 133,//姘旇繍鐧惧垎姣�
+
+    AddNormalHurt = 134,//鍥哄畾鍊煎鍔犳櫘閫氭敾鍑讳激瀹�
+    AddNormalHurtPer = 135,//鐧惧垎姣斿鍔犳櫘閫氭敾鍑讳激瀹�
+    AddSkillHurt = 136,//鍥哄畾鍊煎鍔犳妧鑳戒激瀹�
+    AddSkillHurtPer = 137,//鐧惧垎姣斿鍔犳妧鑳戒激瀹�
+
+    ReduceCrit = 138,//鍑忓皯鏆村嚮鐜�
+    ReduceHeartHurtPer = 139,//浼氬績鍑忎激
+    AddHeartHurtPer = 140,//鐧惧垎姣斿鍔犱細蹇冧竴鍑讳激瀹�
+    AddPVEHurt = 141,//鍥哄畾鍊煎鍔爌ve浼ゅ
+    AddFinalHurtPer = 142,//鐧惧垎姣斿鍔犳渶缁堜激瀹�
+    ReduceFinalHurtPer = 143,//鐧惧垎姣斿噺灏戞渶缁堜激瀹�
+
+    ReduceSkillCDPer = 149, //鍑忓皯鎵�鏈夋妧鑳紺D鐧惧垎姣�
+
+    //鍚庣画IL寮�鍙戞坊鍔犻璁�
+    default1,
+    default2,
+    default3,
+    default4,
+    default5,
+    default6,
+    default7,
+    default8,
+    default9,
+    default10,
+    default11,
+    default12,      //161 浠欑洘浜嬪姟閫熷害鍔犳垚
+    default13,      //浠欑洘BOSS浼ゅ鍔犳垚
+    default14,      //浠欑洘鑱旇禌鐢熷懡鍔犳垚
+    default15,      //浠欑洘鑱旇禌鏀诲嚮鍔犳垚
+    default16,      //浠欑洘鎵撳潗缁忛獙鍔犳垚
+    default17,
+
+    Mater = 201,//閲�
+    Wood = 202,//鏈�
+    Water = 203,//姘�
+    Fire = 204,//鐏�
+    Earth = 205,//鍦�
+
+}
+
+
+public enum TextColType
+{
+    None = 0,
+    White = 1,
+    Blue = 2,
+    Purple = 3,
+    Orange = 4,
+    Red = 5,
+    Pink = 6,
+    /// <summary>
+    /// 娣辫鑹� 401c06 (64, 28, 6, 255)
+    /// </summary>
+    NavyBrown,
+    Green = 9,//缁胯壊
+    Black = 10,
+    /// <summary>
+    /// 娣辩豢鑹� 109d06 (16, 157, 6, 255)
+    /// </summary>
+    DarkGreen = 12,
+    NavyYellow = 13,
+    LightGreen = 14,
+    /// <summary>
+    /// fff4cd
+    /// </summary>
+    LightYellow = 15,
+    /// <summary>
+    /// (204, 204, 204, 255)
+    /// </summary>
+    Gray = 16,
+
+}
+
+
+public enum E_ModelResType
+{
+    Weapon = 1, //姝﹀櫒 1
+    Wing, //缈呰唨 2
+    Horse, //鍧愰獞 3
+    Suit, //濂楄 4
+    Pet,// 瀹犵墿5
+    Secondary,// 鍓墜 6
+    Hand,// 鎵嬭噦 7
+    Spirit,//鐏靛櫒 8
+
+}
+
+
+public enum TreasureCategory
+{
+    Human = 1,
+    Demon = 2,
+    Fairy = 3,
+    King = 4,
+    Zerg = 5,
+
+}
+
+
+public enum TreasureState
+{
+    Collected,
+    Collecting,
+    Locked,
+}
+
+
+public enum FunctionUnlockType
+{
+    NoneType = 0,
+    Treasure = 1,
+    Normal = 2,
+    TreasureSkill = 3,
+    Skill = 4,
+    TreasureFunc = 5,
+    TreasureChapter = 6,
+
+}
+
+
+public enum RedPointState
+{
+    None = 0,
+    Simple = 1,
+    Quantity = 2,
+    Full = 3,
+    GetReward = 4,
+}
+
+
+public enum TeamInviteType
+{
+    Friend,
+    Fairy,
+    NearBy,
+
+}
+
+
+public enum TeammatePrepareState
+{
+    UnPrepared = 0,//鏈噯澶�
+    Prepared = 1,//宸插噯澶�
+    Rejected = 2,//鎷掔粷
+}
+
+
+public enum VipPrivilegeType
+{
+    TreasureAtk = 1,
+    GemHole = 2,
+    VipBuff = 3,
+    TradeTax = 4,
+    PrivateClerk = 5,
+    FreeTransfer = 6,
+    AutoFairyMisstion = 7,
+    Gather = 8,
+    Undead = 9,
+    KillMonsterExpUp = 10,
+    Minion = 11,
+    KillMonsterSp = 12,
+    GoldWish = 13,
+    ExpWish = 14,
+    SelfBoss = 15,   //涓汉boss鍩虹娆℃暟
+    BossHome = 16,
+    PetDungeon = 17,
+    BaptizeDungeon = 18,
+    ForbiddenArea = 19,
+    Fane = 20,
+    Chasm = 21,
+    DarkDorr = 22,
+    FairyDaimondGift = 23,
+    MarketPutawayPwd = 24,
+    DemonJar = 25,
+    BossHomeAwardLimit = 27,
+    DemonJarDouble = 28,
+    BindJadeWheel = 30,
+    PrayForDrug = 31,
+    DemonJarAuto = 32,
+    AssistXianYuanCoinsAdd = 33,//鍔╂垬浠欑紭甯佷笂闄愬姞鎴�
+    AssistXianYuanCoinsRatioAdd = 34,//鍔╂垬浠欑紭甯佽幏寰楀�嶇巼鍔犳垚锛堜竾鍒嗘瘮锛�
+    JadeDynastyBoss = 35,
+    BatchAlchemyFairy = 36,//鎵归噺鐐煎埗浠欎腹
+    BossHomeBuyTimes = 37,//boss涔嬪璐拱娆℃暟
+    SelfBossBuyTims = 38, //涓汉boss璐拱娆℃暟
+    
+}
+
+
+public enum E_AttackMode
+{
+    Peace,
+    All,
+    Country,
+    Group,
+    Team,
+    Family,
+    GoodEval,
+    Contest,
+
+}
+
+
+public enum E_ItemColor
+{
+    White = 1,
+    Blue,
+    Purple,
+    Orange,
+    Red,
+    Pink,
+
+}
+
+
+public enum FindPreciousType
+{
+    WorldBoss = 0,
+    BossHome = 1,
+    PersonalBoss = 2,
+    ElderGodArea = 3,
+    DemonJar = 4,
+    CrossServerBoss = 6,
+    JadeDynastyBoss = 7,
+
+    None = 99,
+}
+
+
+public enum GotServerRewardType
+{
+    Def_RewardType_Activity = 0,
+    Def_RewardType_FamilyActivity = 1,
+    Def_RewardType_ChampionFamilyDailyReward = 2,
+    Def_RewardType_XMZZWinCnt = 3,
+    Def_RewardType_FairyDayAward = 4,
+    Def_RewardType_XBXZ = 6, // 浠欏疂瀵讳富濂栧姳6
+    Def_RewardType_DayRealmPoint = 7,//鏃ュ父淇鐐�
+    Def_RewardType_GoldGiftFirst = 8,//棣栧啿绀煎寘
+    Def_RewardType_TreasureSoul = 9,//娉曞疂榄傚鍔�
+    Def_RewardType_ConsumeRebate = 11,//娑堣垂杩斿埄濂栧姳
+    Def_RewardType_BossReborn = 12,//boss澶嶆椿濂栧姳
+    Def_RewardType_FCRecharge = 13,// 浠欑晫鐩涘吀鍏呭�煎ぇ绀�13W
+    Def_RewardType_FCParty = 14,// 浠欑晫鐩涘吀鍏ㄦ皯鏉ュ棬14
+    Def_RewardType_WishingWell = 16,//  璁告効姹犲鍔�16
+    Def_RewardType_OpenFunc = 17,//鍔熻兘棰勫憡濂栧姳
+    Def_RewardType_TotalRecharge = 18,//绱鍏呭�煎鍔�
+    Def_RewardType_IceLodeStar = 19, //鍐版櫠鐭胯剦鏄熺骇濂栧姳19
+    Def_RewardType_WeekPartyAct = 20, //棰嗗彇鍛ㄧ媯娆㈡椿鍔ㄥ鍔�20
+    Def_RewardType_WeekPartyPoint = 21,// 棰嗗彇鍛ㄧ媯娆㈢Н鍒嗗鍔�21
+    Def_RewardType_ActLoginAwardAct = 22,// 棰嗗彇鐧诲綍濂栧姳娲诲姩濂栧姳22
+    Def_RewardType_NewFairyCRecharge = 23, // 鏂颁粰鐣岀洓鍏稿厖鍊煎ぇ绀�23
+    Def_RewardType_NewFairyCParty = 24, // 鏂颁粰鐣岀洓鍏稿叏姘戞潵鍡�24
+    Def_RewardType_FeastWeekPartyAct = 25, //棰嗗彇鑺傛棩宸$ぜ娲诲姩濂栧姳25
+    Def_RewardType_FeastWeekPartyPoint = 26, //棰嗗彇鑺傛棩宸$ぜ绉垎濂栧姳26
+    Def_RewardType_FairyAdventuresAward = 27,//缂ョ紙濂囬亣
+    Def_RewardType_HistoryChargeAward = 28,//绱鍏呭��
+    Def_RewardType_DayPackageFree = 29,//姣忔棩鍏嶈垂绀煎寘
+    Def_RewardType_ActivityPlace = 30,//娲昏穬鏀剧疆濂栧姳
+
+    Def_RewardType_HolidayLogin = 37,//鑺傛棩鐧诲綍濂栧姳
+    Def_RewardType_HolidayTravel = 38,//鑺傛棩娓稿巻濂栧姳
+    
+}
+
+
+public enum MapType
+{
+    OpenCountry = 0,//閲庡鍦板浘
+    SingleFB = 1,        //鍗曚汉鍓湰
+    MultipleFB = 2,    //缁勯槦鍓湰
+    FamilyFB = 3,       //瀹舵棌鍓湰
+    FamilyWarFB = 4, //瀹舵棌鎴樺壇鏈�
+    CountryExam = 5, //鍥藉绛旈
+    CountryFB = 6,      //鍥藉鍓湰
+    AllByCountry = 7,  //闃佃惀鍓湰
+    All = 8,                   //鎵�鏈�
+    VSRoom = 9,         //pk鎴块棿
+    CrossAll = 11,       //璺ㄦ湇鎵�鏈�
+
+}
+
+
+public enum GuideType
+{
+    NewBie = 1,
+    Functional = 2,
+}
+
+
+public enum GuideTriggerType
+{
+    None = 998,//鏃犻檺鍒�
+    FunctionOpen = 1,//鍔熻兘寮�鏀�
+    ManualFunctionOpen = 51,//鎵嬪姩鍔熻兘寮�鏀�
+    Level = 2,               //绛夌骇婊¤冻鏉′欢
+    Treasure = 3,//娉曞疂
+    EquipQuality = 4,//瑁呭鍝佽川
+    Item = 5,//鎸囧畾鐗╁搧
+    TreasureDungeon = 6,//娉曞疂鍓湰
+    Map = 11,//鍦板浘
+    RuneInlay = 12,//绗﹀嵃闀跺祵
+    RealmSitDown = 13,//澧冪晫鎵撳潗
+    ItemCompound = 14,//鐗╁搧鍚堟垚
+    HangUpResult = 15,//鎸傛満缁撶畻
+    TreasureCollectSoul = 16,//娉曞疂闆嗛瓊
+    TreasureAwaken = 17,//娉曞疂瑙夐啋
+    Pray = 18,//绁堟効
+    VIPExperience = 19,//vip浣撻獙
+    FairyLandBuyTimes = 20,//浠欑晫绉樺璐拱娆℃暟
+    TeamAutoAccept = 21,//鑷姩鎺ュ彈缁勯槦閭�璇�
+    TrialExchange = 22,//瀹楅棬璇曠偧鍏戞崲鏉愭枡
+
+    
+
+    QuestCanAccept = 100,//浠诲姟鍙帴
+    MainLineQuestCanDo = 101,//浠诲姟杩涜涓�
+    MainLineQuestCanAward = 102,//浠诲姟鍙濂�
+    MainLineQuestLimit = 106,//浠诲姟琚檺鍒�
+    MainLineQuestContinue = 110,//浠诲姟鍙户缁�
+
+    BranchQuestCando = 201,//鏀嚎浠诲姟鍙仛
+    BranchQuestCanAward = 202,//鏀嚎浠诲姟鍙濂�
+    BranchQuestLimit = 206,//鏀嚎浠诲姟琚檺鍒�
+    BranchQuestContinue = 210,//鏀嚎浠诲姟鍙户缁�
+}
+
+
+public enum FuncPowerType
+{
+    Role = 0,//瑙掕壊
+    Equip = 1,//瑁呭
+    Plus = 2,//寮哄寲
+    Stone = 3,//瀹濈煶
+    Reiki = 4,//鐏垫牴
+    Wing = 5,//缈呰唨
+    Wash = 6,//娲楃偧
+    Pet = 7,//鐏靛疇
+    Horse = 8,//鍧愰獞
+    Realm = 9,//澧冪晫
+    GodWeapon = 10,//绁炲叺
+    Title = 11,//绉板彿
+    Rune = 12,//绗﹀嵃
+    Star = 13,//鍗囨槦
+    Human = 14,//浜烘棌娉曞疂
+    Alchemy = 15,//鍏崷鐐�
+    Demon = 16,//榄旀棌娉曞疂
+    Fairy = 17,//浠欐棌娉曞疂
+    PetSoul = 18,//鐏靛疇榄傜煶
+    HorseSoul = 19,//鍧愰獞榄傜煶
+    Dogz = 21,//绁炲吔
+    GatherSoul = 22,//鑱氶瓊
+    King = 23,//鐜嬭�呮硶瀹�
+    FashionDress = 24,//鏃惰
+    JadeDynastyEquip = 25, //璇涗粰瑁呭
+
+    
+}
+
+
+public enum E_AtkType
+{
+    Special, //0 鐗规畩锛堝皢璧拌繘鍏蜂綋鐨勬妧鑳絀D杩涜澶勭悊锛屾牴鎹晥鏋淚D
+    Single,//1 鍗曚綋鐩爣鎶�鑳芥敾鍑�
+    Multiple,//2 缇や綋鐩爣鎶�鑳芥敾鍑�
+    Transmit,//3 缇や綋鐩爣鎶�鑳芥敾鍑�(閾惧紡) 鏁堟灉1濉激瀹筹紝鏁堟灉2濉�掑锛屾晥鏋�3濉烦鍑犳
+    ClearHatred,//4 娓呬粐鎭� 娓呴櫎鐩爣鍦ㄩ噴鏀捐�呬粐鎭ㄥ垪琛ㄥ唴鐨勪粐鎭ㄧ櫨鍒嗘瘮 NPC浣跨敤
+    SingleHatred,//5 鍗曚綋浠囨仺鎶�鑳�
+    MultipleBuff,//6 缇や綋BUFF
+    Summon,//7 鍙敜锛堝彫鍞ゅ吔鐨勬敾鍑诲姏鍙朜PC琛ㄧ殑鏁板�硷級
+    SingleRecoverAtkPer,//8 鍗曚綋鎭㈠鑷韩鏀诲嚮鐧惧垎姣旇閲忥紙浠呴拡瀵圭灛鍙戞妧鑳�
+    FastMove,//9 鎷︽埅銆佹殫褰辨銆佹潃鎴洓瀹存ā鏉� 闈炵帺瀹朵笉鍙敤 鎶�鑳戒細閫犳垚浼ゅ骞朵笖姝ゆRUSH鏆村嚮鐜囦細鎻愰珮鐨勶紝闇�瑕佸~鏁堟灉AB鍊硷紝鍏朵腑锛氭晥鏋�1 A鍊间激瀹崇櫨鍒嗘瘮锛孊鍊间激瀹冲浐瀹氬�� 鏁堟灉2 A鍊兼毚鍑伙紝B鍊兼毚鍑荤櫨鍒嗘瘮
+    FlashMove,//10 娉曞笀闂幇
+    //11 NPC缁欏彫鍞ゅ吔鍔燘UFF
+    //12 鏈夎搴︾殑缇ゆ敾:鍗婂緞瀛楁涓虹被鍨嬶細1 鐩寸嚎锛�2 5鏍兼暎灏勬敾鍑� 3 6鏍兼暎灏�
+    //13 娓呯┖NPC鑷繁鐨勬渶澶т粐鎭ㄨ��
+    //15 NPC涓撶敤锛屾壘鍒板綋鍓嶄粐鎭ㄥ垪琛ㄤ腑鏈�澶т粐鎭ㄨ�咃紝濡傛灉鍦ㄨ閲庝腑鍒欑灛绉昏繃鍘�
+    //16 鍙敜鍏戒笓鐢紝鍙敜NPC锛堝彫鍞ゅ吔鐨勬敾鍑诲姏鍙栨敾鍑诲彇鐜╁鐨勬敾鍑诲姏锛�
+    //17 鎸夎閲忔坊鍔犱粐鎭紙鑲夊疇锛�
+    //18 鍗曚綋鎭㈠鑷韩姘旇涓婇檺鐧惧垎姣旇閲忥紙閽堝鐬彂鎶�鑳斤級鏁堟灉1a鍊煎~鐧惧垎姣旓紝b鍊煎~鍥哄畾鍊�
+    //19 缇や綋鏀诲嚮鎶�鑳斤紝浼ゅ涓鸿寖鍥村唴鎵�鏈変汉鍒嗘媴
+    //20 瀵圭洰鏍囬�犳垚鐩爣琛�閲忎笂闄愮櫨鍒嗘瘮鐨勪激瀹�
+    //25  
+    //NPC涓撶敤 鍙敜鍏芥妧鑳芥ā鏉� 
+    //鏁堟灉1 A鍊� 鍙敜鍏絅PCID
+    //      B鍊� 鍗曟鍙敜鏁伴噺
+    //      C鍊�  鎬诲彫鍞ゆ暟閲�
+    //21 缇や綋鐧惧垎姣旀墸琛�妯℃澘
+    //28 鍙栨秷鐨勯�変腑鐩爣妯℃澘
+    //30 寮撶鎵嬪Э鎬佹ā鏉�
+    //32 澧炲姞鍚歌鏁堟灉(闈炲惛琛�鎶�鑳�,浣滅敤浜庡惛琛�鏁堟灉涓囧垎姣�),A鍊煎~涓囧垎鐜囩郴鏁�
+    //33 鎵撳嚭鏈�鍚庝竴鍑讳激瀹崇殑X%闄勫姞Y鍊�
+    default11,
+    default12,
+    default13,
+    default14,
+    default15,
+    default16,
+    default17,
+    default18,
+    default19,
+    default20,
+    default21,
+    default22,
+    default23,
+    default24,
+    default25,
+    default26,
+    default27,
+    default28,
+    default29,
+    default30,
+    default31,
+    default32,
+    RushAttack = 34,//34 鍐查攱+浼ゅ锛岀劧鍚庢晥鏋滃崐寰勯厤0鏃�=鍗曟敾浼ゅ锛岄厤>0鏃�=缇ゆ敾鏍煎瓙鏁帮紝閰�5灏辩瓑浜庤缇ゆ敾5*5
+    //35 钃勫姏妯℃澘锛屾惌閰嶆晥鏋滃�� 鏁堟灉ID 1206  A鍊间负鑳介噺娆℃暟 
+    default35,
+    
+}
+
+
+public enum GameObjType
+{
+    /** 鏈畾涔� */
+    gotNone = 0,
+    /** 鐜╁ */
+    gotPlayer,
+    /** NPC */
+    gotNPC,
+    /** 鐗╁搧 */
+    gotItem,
+    /** 椋炶鐗╀欢 */
+    gotFlyObj,
+
+    /** 姝ゆ灇涓剧殑鍊肩被鍨嬬殑鍊间笂闄� */
+    gotMax
+}
+
+
+/** 浼ゅ绫诲瀷 */
+public enum HurtAttackType
+{
+    /** 鏅�氫激瀹� */
+    Normal = 1,
+    /** 鎭㈠ */
+    Recovery = 2,
+    /** 鍙嶅脊浼ゅ */
+    BounceHurt = 3,
+    /** 鐣欒 */
+    Bleed = 4,
+    /** 鎶靛尽 */
+    Parry = 5,
+    /** 杩炲嚮 */
+    DoubleHit = 6,
+    /** 鏆村嚮 */
+    SuperHit = 7,
+    /** 浼氬績涓�鍑� */
+    LuckyHit = 8,
+    /** 闂伩 */
+    Miss = 9,
+    /** 鍏嶇柅 */
+    Immune = 10,
+    /** 鍘嬪埗 */
+    Suppress = 11,
+    /**鏂╂潃**/
+    ZhanSha = 12,
+    /** 璇涗粰涓�鍑� */
+    ZhuXianAtk = 13,
+    /** 缁堟瀬鏂╂潃 */
+    FinalKill = 14,
+    /*鑷村懡涓�鍑�*/
+    DeadlyHit = 15,
+    ThumpHit = 16,// 閲嶅嚮
+    Yinji = 17,// 鍗拌
+    Burning = 18,// 鐏肩儳
+
+
+}
+
+
+public enum DungeonTargetType
+{
+    NPC = 1,
+    Exp = 2,
+    Score = 3,
+    Money = 4,
+    Wave = 5,
+    NpcTotal = 6,
+    Stage = 7,
+    NPCDialogue = 8,    //npc瀵硅瘽
+    VictorySumCnt = 9, //锛堜粰榄旇儨鍒╂�诲満鏁帮級
+    StageVictoryCnt = 10, //锛堥樁娈佃儨鍒╁満鏁帮級
+    Collect = 11,
+    AttackCount = 12,
+
+
+}
+
+
+public enum AchievementType
+{
+    Level = 1,
+    FightPower = 2,
+    MainLine = 3,
+    KillMonster = 4,
+    DailyQuest = 5,
+    FairyQuest = 6,
+    JobRank = 7,
+    MagicWeaponLevel = 8,
+    MountCount = 9,
+    MountLevel = 10,
+    PetCount = 11,
+    PetLevel = 12,
+    CollectGold = 13,
+    CollectBindDiamond = 14,
+    CollectDiamond = 15,
+    AccumulativeSignIn = 16,
+    ContinuousSignIn = 17,
+    PackbackGrid = 18,
+    FriendCount = 19,
+    WorldChat = 20,
+    SaleItem = 21,
+    BuyItem = 22,
+    Dead = 23,
+    ClearRedName = 24,
+    KillPlayer = 25,
+    StrengthenCount = 26,
+    EquipStrengthenLevel = 27,
+    WorldBoss = 28,
+    CircleQuest = 29,
+    TreasureDungeon = 30,
+    JoinGuild = 31,
+    JoinTeam = 32,
+    CollectTreasure = 33,
+    BeKilledCount = 34,
+    PrayCount = 35,
+    KillNPC = 36,
+    FindWorldMap = 37,
+    PutonEquipPlace = 38,
+    PutonEquipQuality = 39,
+    MissionTranfer = 40,
+    PropertyAdd = 41,
+    RuneTower = 42,
+    Mount = 43,
+    GetRune = 44,
+    RuneLevel = 45,
+    FairyArea = 46,
+    ComposeItem = 47,
+    InlayGem = 48,
+    Kylin = 49,
+    Realm = 50,
+    RefiningDan = 51,
+    ActivevalueAward = 52,
+    TreasureLevel = 53,
+    AncientBattleGroundKillCnt = 55,
+    AncientBattleGroundMultiKill = 56,
+    UnLockPet = 57,
+    PetRank = 58,
+    PetRanks = 59,
+    LifeGemInlay = 60,
+    AttackGemInlay = 61,
+    FairylandExp = 62,
+    NuwaGradeS = 63,
+    AnyMountLevel = 64,
+    DvsFWinningStreak = 65,
+
+}
+
+
+/// <summary>
+/// 鐗╁搧浣跨敤鑰愪箙搴﹂檺鍒剁被鍨�
+/// </summary>
+public enum ItemTimeType
+{
+    EquipedTime = 3,              //鏃堕棿锛堣澶囩殑鏃跺��-1锛屾鍚庢瘡鍒嗛挓-1锛�
+    RealityTime = 9,                //鐜板疄鏃堕棿鎵h�愪箙
+
+
+
+}
+
+
+public enum TitleBtnState
+{
+    Normal,
+    Click,
+    Locked,
+}
+
+
+public enum LegendAttrType
+{
+    Normal = 0, //涓�鑸�
+    Pursuit = 1, //杩芥眰
+    Fixed = 2, //鍥哄畾
+}
+
+
+public enum ServerState
+{
+    Maintain = 0,
+    Normal = 1,
+    Busy = 2,
+    Hot = 3,
+    Predicted = 4,
+}
+
+
+public enum ItemUseDataKey
+{
+    mapLoaction = 15,  // 鐗╁搧璁板綍鍦板浘鍧愭爣[mapid, posx, posy]
+    legendAttrID = 17,  //鐗╁搧浼犲灞炴�D鍒楄〃
+    itemCount = 18,  // 鐗╁搧涓暟锛屾敮鎸�20浜匡紝鐩墠浠呯壒娈婅浆鍖栫墿鍝佷細鐢ㄥ埌
+    legendAttrValue = 19,  //鐗╁搧浼犲灞炴�у�煎垪琛�
+    outOfPrintAttrID = 21,  //鐗╁搧缁濈増灞炴�D鍒楄〃
+    outOfPrintAttrValue = 23,  //鐗╁搧缁濈増灞炴�у�煎垪琛�
+
+    itemColor = 16,  //鐗╁搧棰滆壊锛屽鏋滆鍊兼病鏈夊氨鍙栫墿鍝�
+    cancelUseLimit = 20,  //鐗╁搧鍙栨秷浣跨敤闄愬埗
+    source = 24,  // 鐗╁搧鏉ユ簮 1-瀵诲疂锛�2-鍟嗗簵璐拱锛�3-鍟嗗簵鍏戞崲锛�4-鍑绘潃铏氭嫙鎺夎惤
+    wingMaterialItemID = 27,  //缈呰唨绮剧偧鏉愭枡ID鍒楄〃
+    wingMaterialItemCount = 29,  //缈呰唨绮剧偧鏉愭枡涓暟鍒楄〃
+
+    suiteLV = 30,  //濂楄绛夌骇
+    dogzEquipPlus = 31,  // 绁炲吔瑁呭寮哄寲淇℃伅鍒楄〃 [寮哄寲绛夌骇, 寮哄寲鐔熺粌搴
+    hasOpenCnt = 32,  // 鐗╁搧绱Н寮�鍚鏁�
+    itemDecompound = 33,  //鍚堟垚鐗╁搧鎷嗚В杩旇繕鐗╁搧鍒楄〃 [瑁呭ID,鏉愭枡1ID,涓暟,鏄惁缁戝畾,鏉愭枡2ID,涓暟,鏄惁缁戝畾,...]
+    createItemLoginDay = 34,  //鍒涘缓鐗╁搧鏃剁殑鐧诲綍澶╂暟
+    lastOpenItemLoginDay = 36,  //涓婁竴娆″紑鍚墿鍝佹椂鐨勭櫥褰曞ぉ鏁�
+    equipSkills = 37, //瑁呭鎶�鑳斤紝娌℃湁璁板綍鍒欒鍙栬〃
+    runeLV = 38,  // 绗﹀嵃绛夌骇
+    birthChartLV = 40,  // 鍛芥牸绛夌骇
+    wingProgressValue = 42, //缇界考绮剧偧鍊�
+    createTime = 44, // 鏃舵晥鐗╁搧鐨勫垱寤烘椂闂�
+    totalTime = 48, // 鏃舵晥鐗╁搧鐨勫墿浣欐椂闂�
+    auctionItemCreateTime = 50,//鎷嶅搧鍒涘缓鏃堕棿
+
+    // 绁炶灞炴��
+    shenAttrID = 51,  //鐗╁搧绁炲搧灞炴�D鍒楄〃
+    xianAttrID = 53,  //鐗╁搧浠欏搧灞炴�D鍒楄〃
+    jiAttrID = 55,  //鐗╁搧鏋佸搧灞炴�D鍒楄〃
+
+    shenAttrValue = 61,  //鐗╁搧绁炲搧灞炴�у�煎垪琛�
+    xianAttrValue = 63,  //鐗╁搧浠欏搧灞炴�у�煎垪琛�
+    jiAttrValue = 65,  //鐗╁搧鏋佸搧灞炴�у�煎垪琛�
+
+    //鍚庣画IL寮�鍙戞坊鍔犻璁�
+    default1,
+    default2,
+    default3,
+    default4,
+    default5,
+    default6,
+    default7,
+    default8,
+    default9,
+    default10,
+
+
+    #region 200~300 瀹犵墿鏁版嵁鐢�
+    pet_NPCID = 200,  //npcID
+    pet_Skill = 201,  //鎶�鑳藉垪琛�
+    pet_ClassLV = 202,  // 闃剁骇
+    pet_State = 204,  // 褰撳墠鐘舵��, 瀵瑰簲 Def_PetStateList
+    pet_QualityLV = 206,  // 鍝佽川
+
+    default81,
+    default82,
+    default83,
+    default84,
+    default85,
+    default86,
+    default87,
+    default88,
+    default89,
+    default90,
+    default91,
+    default92,
+    default93,
+    default94,
+    default95,
+    default96,
+    default97,
+    default98,
+    default99,
+    default100,
+    #endregion
+}
+
+
+public enum ItemOperateType
+{
+    makeUse, //浣跨敤
+    putOn, //绌夸笂
+    dismantle, //鎷嗚В鍚堟垚瑁呭
+    split, //鎷嗗垎
+    putAway,//涓婃灦
+    compose,//鍚堟垚
+    sell, //鍑哄敭
+    putOff, //鑴变笅
+    putIn, //鏀惧叆
+    putOut, //鍙栧嚭
+    exchange,//鍏戞崲
+    buy,//璐拱
+    putItemout,//鐗╁搧涓嬫灦
+    renewal,//缁垂
+    refine, //绮剧偧
+    LevelUp,//鍗囩骇
+    Resolve,//鍒嗚В
+    Wear,//浣╂埓
+    Replace,//鏇挎崲
+
+    gotoPuton,//鍓嶅線绌夸笂
+    strength, //寮哄寲
+    inlay, //闀跺祵
+    train,//娲楃偧
+    star,//鍗囨槦
+    lsExchange, //鐏电煶鍏戞崲
+
+    //鍚庣画IL寮�鍙戞坊鍔犻璁�
+    default1, //鍗囬樁
+    default2,
+    default3,
+    
+}
+
+
+public enum ItemWinType
+{
+    itemWin, //鏅�氱墿鍝佸脊妗�
+    boxWin, //瀹濈寮规
+    equipWin,  //瑁呭寮规
+    wingsWin,  //缈呰唨寮规
+    guardWin,//瀹堟姢寮规
+    buyItemWin, //璐拱鐗╁搧寮规
+    buyBoxWin,  //璐拱瀹濈寮规
+    petMatWin,  //瑙i攣瀹犵墿鍜屽潗楠戦亾鍏峰脊妗�
+    buyPetMatWin,  //璐拱瑙i攣瀹犵墿鍜屽潗楠戦亾鍏峰脊妗�
+    gatherSoul,//鑱氶瓊
+    kingTreasure, //鐜嬭�呮硶瀹�
+
+}
+
+
+public enum ItemTipChildType
+{
+    Normal, //鏅�氱殑瑁呭寮规
+    Buy, //璐拱寮规
+    UnionWarehouseDonation, //鎹愮尞瑁呭
+    UnionWarehouseExchange, //鍏戞崲瑁呭
+    GetEquipPath,  //瑁呭鑾峰彇閫斿緞
+    GetWingsPath,//缈呰唨鑾峰彇閫斿緞
+
+
+}
+
+
+public enum InstalledAsset
+{
+    NullAsset = 0,
+    HalfAsset = 1,
+    FullAsset = 2,
+    IngoreDownLoad = 3,
+}
+
+
+public enum VersionAuthority
+{
+    InterTest = 0,
+    Release = 1,
+}
+
+
+public enum FootAudioType
+{
+    Walk = 1,
+    Ride = 2,
+    Fly = 3,
+
+
+}
+
+
+public enum AttackFailType
+{
+    SkillFail_Other,      // 鍏朵粬
+    SkillFail_CD,      // 鎶�鑳紺D
+    SkillFail_AtkInterval, // 鏀诲嚮闂撮殧
+
+
+}
+
+
+public enum DungeonFightStage
+{
+    None,
+    Prepare,
+    Normal,
+    PickUp,
+    ExitPrepare,
+    ElderGodAreaNearDead,
+
+
+}
+
+
+public enum RankType
+{
+    FightPower = 0,
+    Job1FightPower = 1,
+    Job2FightPower = 2,
+    Job3FightPower = 3,
+    Level = 4,
+    Mount = 5,
+    Pet = 6,
+    RuneTower = 7,
+    OfflineExp = 8,
+    Realm = 9,
+    OpenServerStrengthen = 11,
+    OpenServerMount = 12,
+    OpenServerGem = 13,
+    OpenServerLv = 14,
+    OpenServerRealm = 15,
+    OpenServerFightPower = 16,
+    Def_BT_FCCostGold = 17,  //娑堣垂鎺掕姒�(浠欑晫鐩涘吀)
+    OpenServerRune = 18,
+    Assist = 19,//鍔╂垬姒�
+    OpenServerGodWeapon = 20,
+    OpenServerRecharge = 21,
+    OpenServerPet = 22,
+    Def_BT_NewFCCostGold = 23, //娑堣垂鎺掕姒�(鏂颁粰鐣岀洓鍏�)  23
+    OpenServerReikiPoint = 24,//鐏垫牴鐐�
+    OpenServerStartLevel = 25,
+    OpenServereEquipTrain = 26, //瑁呭娲楃粌
+
+    default1,
+    default2,
+    default3,
+    default4,
+}
+
+
+public enum PetOrMount
+{
+    None,
+    Pet,
+    Mount,
+}
+
+//OpenServerActivityCenter.ActivityType.AT_Activity2鐨勬椿鍔�  鍘嗗彶鍘熷洜涓嶈鐢�100
+public enum NewDayActivityID
+{
+    BossTrial = 200,    //boss鍑瘉
+    LoginAct = 201, //鐧诲綍娲诲姩
+    MissionAct = 202,   //浠诲姟娲诲姩
+    RechargeGiftAct = 203,  //鍏呭�肩ぜ鍖咃紙鍏呭�兼鏁板鍔憋級
+    CrossBossTrial = 204,   //璺ㄦ湇boss鍑瘉 蹇呴』鍜孊ossTrial 涓�璧�
+    FamilyRechargeConnAct = 205, //浠欑洘鍗忓姪
+    CustomizedGiftWin = 206, //鑷�夌ぜ鍖�
+    SecretPlaceXB = 207, //绉樺瀵诲疂
+    SecretPlaceXBCross = 208, //绉樺瀵诲疂 璺ㄦ湇
+    RechargeGiftAct31 = 209,  //鑷�夊厖鍊� + 鍟嗗簵绀煎寘
+    PetHorseAct = 210,  //瀹犵墿鍧愰獞娲诲姩
+    PetHorseActCross = 211,  //瀹犵墿鍧愰獞娲诲姩 璺ㄦ湇
+    TreasurePavilionAct = 212,  //鍙ゅ疂娲诲姩
+    TreasurePavilionActCross = 213,  //鍙ゅ疂娲诲姩 璺ㄦ湇
+    FairyAffinityLoginAct = 214,  //浠欑紭鐧婚檰娲诲姩
+    FairyAffinityMissionAct = 215,  //浠欑紭浠诲姟娲诲姩
+    FairyAffinityRechargeGiftAct = 216,  //浠欑紭绀煎寘娲诲姩
+    CycleHallAct = 217,  //杞洖娈挎椿鍔�
+    YunShiXBAct = 218,  //杩愬娍瀵诲疂娲诲姩
+    YunShiMissionAct = 219,  //杩愬娍浠诲姟娲诲姩
+    YunShiRechargeGiftAct = 220,  //杩愬娍绀煎寘娲诲姩
+    LianQiActCross = 221,    //浠欏尃澶т細娲诲姩 璺ㄦ湇
+    LianQiRechargeGiftActCross = 222, //浠欏尃澶т細绀煎寘娲诲姩 璺ㄦ湇
+}
+
+//浠欑帀璐拱鐨勪簩娆$‘璁ゆ绫诲瀷
+public enum BuyStoreItemCheckType
+{
+    All = 0,    //榛樿鍏ㄥ眬, 闈炵壒娈婂彲浠ョ粺涓�鐢ㄨ繖涓�
+    ActGift = 1, //娲诲姩绀煎寘
+    MJXB = 2,   //绉樺瀵诲疂
+    GatherSoulXB = 3,   //鑱氶瓊瀵诲疂
+    TreasurePavilion = 4,   //鍙ゅ疂瀵诲疂
+    BestXB = 5,   //鏋佸搧瀵诲疂
+    RuneXB = 6,   //绗︽枃瀵诲疂
+}
+
+//鏌ヨ鍏朵粬鐜╁鏁版嵁 鐢ㄩ�旂被鍨�
+public enum ViewPlayerType
+{
+    viewPlayerEquip = 0,    //鏌ョ湅鐜╁鍩烘湰淇℃伅锛堣澶囩敱璇锋眰澶у鐣岄樁鍐冲畾锛夛紝骞舵墦寮�鐣岄潰
+    viewPlayerFightPower = 1,  //鏌ョ湅鐜╁鎴樺姏璇︽儏锛屽苟鎵撳紑鐣岄潰
+    viewPlayerData = 2,  //鏌ョ湅鐜╁鍩烘湰淇℃伅锛屽叕鐢�
+    viewPlayerDataZZ = 3,  //鍔╂垬鍦烘櫙浣跨敤
+    viewPlayerDataArena = 4,  //鏈湇绔炴妧鍦哄満鏅娇鐢�
+    viewPlayerDataFairyKing = 5,  //浠欑洘鑱旇禌鐜嬭�匲I浣跨敤
+
+    //鏌ヨ璺ㄦ湇鏁版嵁浠�100寮�濮�
+    viewCrossPlayerEquip = 100,    //鏌ョ湅鐜╁鍩烘湰淇℃伅锛堣澶囩敱璇锋眰澶у鐣岄樁鍐冲畾锛夛紝骞舵墦寮�鐣岄潰
+    viewCrossPlayerFightPower = 101,  //鏌ョ湅鐜╁鎴樺姏璇︽儏锛屽苟鎵撳紑鐣岄潰
+    viewCrossPlayerData = 102,  //鏌ョ湅鐜╁鍩烘湰淇℃伅锛屽叕鐢�
+    viewCrossPlayerDataBlessedLand = 103,  //绂忓湴椹辫刀
+}
\ No newline at end of file
diff --git a/Utility/EnumHelper.cs.meta b/Utility/EnumHelper.cs.meta
new file mode 100644
index 0000000..4cc5351
--- /dev/null
+++ b/Utility/EnumHelper.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 6c3c795526505f341b99055538370899
+timeCreated: 1504186082
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/EnumLabelAttribute.cs b/Utility/EnumLabelAttribute.cs
new file mode 100644
index 0000000..f2adab0
--- /dev/null
+++ b/Utility/EnumLabelAttribute.cs
@@ -0,0 +1,47 @@
+锘縰sing System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+#if UNITY_EDITOR
+using UnityEditor;
+using System.Reflection;
+#endif
+
+[AttributeUsage(AttributeTargets.Field)]
+public class EnumLabelAttribute : PropertyAttribute
+{
+    public readonly Type enumType;
+    public EnumLabelAttribute(Type type)
+    {
+        this.enumType = type;
+    }
+}
+
+#if UNITY_EDITOR
+[CustomPropertyDrawer(typeof(EnumLabelAttribute))]
+public class EnumLabelPropertyDrawer : PropertyDrawer
+{
+    List<string> m_EnumLabels = new List<string>();
+    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+    {
+        var customAttribute = (EnumLabelAttribute)attribute;
+        if (m_EnumLabels.Count != property.enumNames.Length)
+        {
+            m_EnumLabels.Clear();
+            var enumtype = customAttribute.enumType;
+            foreach (var enumName in property.enumNames)
+            {
+                var enumfield = enumtype.GetField(enumName);
+                var customAttributes = enumfield.GetCustomAttributes(typeof(HeaderAttribute), false);
+                m_EnumLabels.Add(customAttributes.Length <= 0 ? enumName : ((HeaderAttribute)customAttributes[0]).header);
+            }
+        }
+        EditorGUI.BeginChangeCheck();
+        var value = EditorGUI.Popup(position, fieldInfo.Name, property.enumValueIndex, m_EnumLabels.ToArray());
+        if (EditorGUI.EndChangeCheck())
+        {
+            property.enumValueIndex = value;
+        }
+    }
+}
+#endif
diff --git a/Utility/EnumLabelAttribute.cs.meta b/Utility/EnumLabelAttribute.cs.meta
new file mode 100644
index 0000000..1054599
--- /dev/null
+++ b/Utility/EnumLabelAttribute.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: ce694ab87ddaeeb4eaf384d8cc6b284b
+timeCreated: 1537268726
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/Extension.cs b/Utility/Extension.cs
new file mode 100644
index 0000000..5a2e4e8
--- /dev/null
+++ b/Utility/Extension.cs
@@ -0,0 +1,4 @@
+class Extension
+{
+
+}
\ No newline at end of file
diff --git a/Utility/Extension.cs.meta b/Utility/Extension.cs.meta
new file mode 100644
index 0000000..aa23c97
--- /dev/null
+++ b/Utility/Extension.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0116021b3804afd4d9a2f9c7d6a93f72
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/FPS.cs b/Utility/FPS.cs
new file mode 100644
index 0000000..f55e802
--- /dev/null
+++ b/Utility/FPS.cs
@@ -0,0 +1,39 @@
+锘縰sing UnityEngine;
+using System.Collections;
+using UnityEngine.UI;
+
+public class FPS : MonoBehaviour
+{
+    [SerializeField]
+    Text m_Text;
+
+    public float updateInterval = 0.5F;
+    private float lastInterval;
+    private int frames = 0;
+    private float fps;
+
+    void Start()
+    {
+        lastInterval = Time.realtimeSinceStartup;
+        frames = 0;
+    }
+
+    void LateUpdate()
+    {
+        ++frames;
+        float timeNow = Time.realtimeSinceStartup;
+
+        if (timeNow > lastInterval + updateInterval)
+        {
+            fps = frames / (timeNow - lastInterval);
+            frames = 0;
+            lastInterval = timeNow;
+
+            if (m_Text != null)
+            {
+                m_Text.text = fps.ToString("F1");
+            }
+        }
+
+    }
+}
diff --git a/Utility/FPS.cs.meta b/Utility/FPS.cs.meta
new file mode 100644
index 0000000..f119416
--- /dev/null
+++ b/Utility/FPS.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 8c6240c61d5ed494d8ea09d70536b142
+timeCreated: 1469609150
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/FieldPrint.cs b/Utility/FieldPrint.cs
new file mode 100644
index 0000000..1c7b1ee
--- /dev/null
+++ b/Utility/FieldPrint.cs
@@ -0,0 +1,100 @@
+锘縰sing System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System;
+
+public class FieldPrint
+{
+
+    public static string PrintFields(object _object)
+    {
+        if (_object == null)
+        {
+            return string.Empty;
+        }
+
+        var fields = _object.GetType().GetFields();
+        var contents = new string[fields.Length];
+        for (int i = 0; i < fields.Length; i++)
+        {
+            var field = fields[i];
+            var fieldContent = field.GetValue(_object);
+            contents[i] = string.Format("\"{0}\":{1}", field.Name, fieldContent);
+        }
+
+        return string.Join(";  ", contents);
+    }
+
+    public static List<string> PrintFieldsExpand(object _object, bool _includeArray)
+    {
+        if (_object == null)
+        {
+            return null;
+        }
+
+        var fields = _object.GetType().GetFields();
+        var contents = new List<string>();
+        for (int i = 0; i < fields.Length; i++)
+        {
+            var field = fields[i];
+            var fieldContent = field.GetValue(_object);
+            if (fieldContent is Array)
+            {
+                contents.AddRange(PrintArray(field.Name, fieldContent));
+            }
+            else
+            {
+                contents.Add(string.Format("\"{0}\":{1}", field.Name, fieldContent));
+            }
+        }
+
+        return contents;
+    }
+
+    private static string[] PrintArray(string _name, object _object)
+    {
+        var objects = _object as Array;
+        var contents = new string[objects.Length];
+        for (int i = 0; i < objects.Length; i++)
+        {
+            var o = objects.GetValue(i);
+            var type = o.GetType();
+
+            if (type.Name == "String")
+            {
+                contents[i] = string.Format("\"{0}\"[{1}]-->({2}){3}", _name, i, type.Name, (String)o);
+            }
+            else if (type.Name == "UInt32")
+            {
+                contents[i] = string.Format("\"{0}\"[{1}]-->({2}){3}", _name, i, type.Name, (UInt32)o);
+            }
+            else if (type.Name == "Byte")
+            {
+                contents[i] = string.Format("\"{0}\"[{1}]-->({2}){3}", _name, i, type.Name, (Byte)o);
+            }
+            else if (type.Name == "UInt16")
+            {
+                contents[i] = string.Format("\"{0}\"[{1}]-->({2}){3}", _name, i, type.Name, (UInt16)o);
+            }
+            else if (type.Name == "Single")
+            {
+                contents[i] = string.Format("\"{0}\"[{1}]-->({2}){3}", _name, i, type.Name, (float)o);
+            }
+            else if (type.Name == "Boolean")
+            {
+                contents[i] = string.Format("\"{0}\"[{1}]-->({2}){3}", _name, i, type.Name, (bool)o);
+            }
+            else if (type.Name == "Int32")
+            {
+                contents[i] = string.Format("\"{0}\"[{1}]-->({2}){3}", _name, i, type.Name, (int)o);
+            }
+            else
+            {
+                contents[i] = string.Format("\"{0}\"[{1}]-->{2}", _name, i, PrintFields(o));
+            }
+        }
+
+        return contents;
+    }
+
+}
diff --git a/Utility/FieldPrint.cs.meta b/Utility/FieldPrint.cs.meta
new file mode 100644
index 0000000..b7a69af
--- /dev/null
+++ b/Utility/FieldPrint.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 8d1b6198d47e2d14fa6a835644d7f418
+timeCreated: 1509501536
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/FileExtersion.cs b/Utility/FileExtersion.cs
new file mode 100644
index 0000000..3d0be1d
--- /dev/null
+++ b/Utility/FileExtersion.cs
@@ -0,0 +1,207 @@
+锘縰sing System.Collections;
+using System.Collections.Generic;
+using System;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
+
+
+public class FileExtersion
+{
+    public readonly static string lineSplit = "\r\n"; //琛岄棿闅斾綋
+
+    //鍒涘缓瀵瑰簲鐨勬枃浠舵枃浠跺す璺緞
+    public static void MakeSureDirectory(string filePath)
+    {
+        string dir = Path.GetDirectoryName(filePath);
+        if (!Directory.Exists(dir))
+        {
+            Directory.CreateDirectory(dir);
+        }
+    }
+
+    public static List<FileInfo> GetFileInfos(string _path, string[] _searchPatterns)
+    {
+        if (_searchPatterns == null)
+        {
+            return null;
+        }
+
+        if (!Directory.Exists(_path))
+        {
+            return null;
+        }
+
+        var fileInfoes = new List<FileInfo>();
+        var directoryInfo = new DirectoryInfo(_path);
+
+        for (int i = 0; i < _searchPatterns.Length; i++)
+        {
+            fileInfoes.AddRange(directoryInfo.GetFiles(_searchPatterns[i], SearchOption.AllDirectories));
+        }
+
+        return fileInfoes;
+    }
+
+    public static void GetAllDirectoryFileInfos(string _path, List<FileInfo> _fileInfos)
+    {
+        var directoryInfo = new DirectoryInfo(_path);
+        var allFileSystemInfos = directoryInfo.GetFileSystemInfos();
+
+        for (int i = 0; i < allFileSystemInfos.Length; i++)
+        {
+            var fileSystemInfo = allFileSystemInfos[i];
+            if (fileSystemInfo is DirectoryInfo)
+            {
+                GetAllDirectoryFileInfos(fileSystemInfo.FullName, _fileInfos);
+            }
+
+            if (fileSystemInfo is FileInfo)
+            {
+                _fileInfos.Add(fileSystemInfo as FileInfo);
+            }
+        }
+    }
+
+    public static string GetFileRelativePath(string _root, string _fileFullName)
+    {
+        _root = _root.Replace("\\", "/");
+        _fileFullName = _fileFullName.Replace("\\", "/");
+        var relativePath = _fileFullName.Replace(_root, "");
+        if (relativePath.StartsWith("/"))
+        {
+            relativePath = relativePath.Substring(1, relativePath.Length - 1);
+        }
+
+        return relativePath;
+    }
+
+    public static int GetVersionFromFileName(string _fileName)
+    {
+        var index = _fileName.IndexOf("_version_");
+
+        if (index == -1)
+        {
+            return 0;
+        }
+        else
+        {
+            var version = 0;
+            int.TryParse(_fileName.Substring(0, index), out version);
+            return version;
+        }
+    }
+
+    public static string RemoveVersionFromFileFullName(string _fullName)
+    {
+        var fileName = Path.GetFileName(_fullName);
+        var index = fileName.IndexOf("_version_");
+
+        if (index != -1)
+        {
+            var startIndex = index + 9;
+            fileName = fileName.Substring(startIndex, fileName.Length - startIndex);
+            return StringUtility.Contact(Path.GetDirectoryName(_fullName), Path.DirectorySeparatorChar, fileName);
+        }
+        else
+        {
+            return _fullName;
+        }
+    }
+
+    public static string AddVersionToFileFullName(string _fullName, int _version)
+    {
+        var fileName = Path.GetFileName(_fullName);
+        var index = fileName.IndexOf("_version_");
+
+        if (index != -1)
+        {
+            fileName = fileName.Substring(0, index);
+        }
+
+        return StringUtility.Contact(Path.GetDirectoryName(_fullName), Path.DirectorySeparatorChar, _version, "_version_", fileName);
+    }
+
+    public static void DirectoryCopy(string _from, string _to)
+    {
+        if (!Directory.Exists(_from))
+        {
+            return;
+        }
+
+        if (!Directory.Exists(_to))
+        {
+            Directory.CreateDirectory(_to);
+        }
+
+        var files = Directory.GetFiles(_from);
+        foreach (var formFileName in files)
+        {
+            string fileName = Path.GetFileName(formFileName);
+            string toFileName = Path.Combine(_to, fileName);
+            File.Copy(formFileName, toFileName, true);
+        }
+
+        var fromDirs = Directory.GetDirectories(_from);
+        foreach (var fromDirName in fromDirs)
+        {
+            var dirName = Path.GetFileName(fromDirName);
+            var toDirName = Path.Combine(_to, dirName);
+            DirectoryCopy(fromDirName, toDirName);
+        }
+    }
+
+    public static string GetMD5HashFromFile(string fileName)
+    {
+        try
+        {
+            var file = new FileStream(fileName, System.IO.FileMode.Open);
+            var md5 = new MD5CryptoServiceProvider();
+            var retVal = md5.ComputeHash(file);
+            file.Close();
+            var sb = new StringBuilder();
+            for (int i = 0; i < retVal.Length; i++)
+            {
+                sb.Append(retVal[i].ToString("x2"));
+            }
+            return sb.ToString();
+        }
+        catch (Exception ex)
+        {
+            throw new Exception("GetMD5HashFromFile() fail,error:" + ex.Message);
+        }
+    }
+
+    public static string GetStringMD5Hash(string str)
+    {
+        try
+        {
+            var bytes = Encoding.UTF8.GetBytes(str);
+            var md5 = new MD5CryptoServiceProvider();
+            var retVal = md5.ComputeHash(bytes);
+            var sb = new StringBuilder();
+            for (int i = 0; i < retVal.Length; i++)
+            {
+                sb.Append(retVal[i].ToString("x2"));
+            }
+            return sb.ToString();
+        }
+        catch (Exception ex)
+        {
+            throw new Exception("GetMD5HashFromFile() fail,error:" + ex.Message);
+        }
+    }
+
+    public static LuaConfigData ReadFileAllLines(string path)
+    {
+        var lines = File.ReadAllLines(path);
+        return new LuaConfigData() { length = lines.Length, lines = lines };
+    }
+
+    public struct LuaConfigData
+    {
+        public int length;
+        public string[] lines;
+    }
+
+}
diff --git a/Utility/FileExtersion.cs.meta b/Utility/FileExtersion.cs.meta
new file mode 100644
index 0000000..417ab70
--- /dev/null
+++ b/Utility/FileExtersion.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 52b005e9ca76ba5428438ecd6655e7a5
+timeCreated: 1514029556
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/GameObjectPool.cs b/Utility/GameObjectPool.cs
new file mode 100644
index 0000000..f79a1be
--- /dev/null
+++ b/Utility/GameObjectPool.cs
@@ -0,0 +1,99 @@
+锘縰sing System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+
+public class GameObjectPool
+{
+
+    private List<GameObject> m_FreeList;
+    private List<GameObject> m_ActiveList;
+    private GameObject m_Prefab;
+
+    public int nameHashCode;
+    public string name;
+
+    public GameObjectPool(GameObject prefab)
+    {
+        name = prefab.name;
+        nameHashCode = name.GetHashCode();
+
+        m_Prefab = prefab;
+        m_FreeList = new List<GameObject>();
+        m_ActiveList = new List<GameObject>();
+    }
+
+    public GameObject Request()
+    {
+        GameObject _gameObject = null;
+        if (m_FreeList.Count == 0)
+        {
+            _gameObject = Object.Instantiate(m_Prefab);
+            _gameObject.name = name;
+        }
+        else
+        {
+            _gameObject = m_FreeList[0];
+            m_FreeList.RemoveAt(0);
+        }
+        m_ActiveList.Add(_gameObject);
+        return _gameObject;
+    }
+
+    public void Release(GameObject gameObject)
+    {
+        if (m_ActiveList.Contains(gameObject))
+        {
+            m_ActiveList.Remove(gameObject);
+        }
+        else
+        {
+            Debug.LogWarningFormat("鎵�鍥炴敹鐨刧o瀵硅薄 {0} 骞朵笉鏄粠姹犻噷鍙栧緱鐨�...", gameObject.name);
+        }
+        m_FreeList.Add(gameObject);
+       
+    }
+
+    public void Clear()
+    {
+        foreach (var _item in m_FreeList)
+        {
+            Object.Destroy(_item);
+        }
+        foreach (var _item in m_ActiveList)
+        {
+            Object.Destroy(_item);
+        }
+        m_FreeList.Clear();
+        m_ActiveList.Clear();
+    }
+
+    public void Destroy()
+    {
+
+        Clear();
+
+        m_Prefab = null;
+
+        m_FreeList = null;
+        m_ActiveList = null;
+    }
+
+#if UNITY_EDITOR
+    public void ForeachActive(System.Action<GameObject> method)
+    {
+        for (int i = m_ActiveList.Count - 1; i >= 0; --i)
+        {
+            method(m_ActiveList[i]);
+        }
+    }
+
+    public void ForeachFree(System.Action<GameObject> method)
+    {
+        for (int i = m_FreeList.Count - 1; i >= 0; --i)
+        {
+            method(m_FreeList[i]);
+        }
+    }
+#endif
+}
diff --git a/Utility/GameObjectPool.cs.meta b/Utility/GameObjectPool.cs.meta
new file mode 100644
index 0000000..7153f8c
--- /dev/null
+++ b/Utility/GameObjectPool.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 99e41fbb2b3832c41b1575b72c946cca
+timeCreated: 1504310243
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/GenerateUICode.cs b/Utility/GenerateUICode.cs
new file mode 100644
index 0000000..6f8fb5d
--- /dev/null
+++ b/Utility/GenerateUICode.cs
@@ -0,0 +1,294 @@
+锘縰sing UnityEngine;
+using UnityEngine.UI;
+using System.Collections.Generic;
+using System;
+using System.Text;
+
+#if UNITY_EDITOR
+using UnityEditor;
+#endif
+
+public class GenerateUICode : MonoBehaviour {
+}
+
+#if UNITY_EDITOR
+[CustomEditor(typeof(GenerateUICode))]
+public class GenerateUICodeEditor : Editor {
+
+    private Dictionary<int, bool> m_IdToCopy = new Dictionary<int, bool>();
+    private Dictionary<int, string> m_IdToPath = new Dictionary<int, string>();
+
+    private void OnEnable() {
+
+        m_IdToCopy.Clear();
+        m_IdToPath.Clear();
+
+        GenerateUICode _target = target as GenerateUICode;
+        Transform _child;
+        for (int i = 0; i < _target.transform.childCount; ++i) {
+            _child = _target.transform.GetChild(i);
+            m_IdToCopy.Add(_child.GetInstanceID(), false);
+            m_IdToPath.Add(_child.GetInstanceID(), GetPath(_child));
+            if (_child.childCount > 0) {
+                GenerateToggle(_child);
+            }
+        }
+
+    }
+
+    private string GetPath(Transform tr) {
+        GenerateUICode _target = target as GenerateUICode;
+        string path = tr.name;
+        while (tr.parent != null
+            && tr.parent.GetInstanceID() != _target.transform.GetInstanceID()) {
+            path = tr.parent.name + "/" + path;
+            tr = tr.parent;
+        }
+        return path;
+    }
+
+
+    public override void OnInspectorGUI() {
+
+        EditorGUILayout.BeginHorizontal();
+        if (GUILayout.Button("澶嶅埗瀹氫箟")) {
+            CopyDefine();
+        }
+        if (GUILayout.Button("澶嶅埗鑾峰彇")) {
+            CopyGet();
+        }
+        EditorGUILayout.EndHorizontal();
+
+        GenerateUICode _target = target as GenerateUICode;
+
+        if (_target.transform.childCount > 0) {
+
+            Transform _child;
+
+            for (int i = 0; i < _target.transform.childCount; ++i) {
+                _child = _target.transform.GetChild(i);
+                EditorGUILayout.BeginHorizontal();
+                m_IdToCopy[_child.GetInstanceID()] = EditorGUILayout.ToggleLeft(_child.name, m_IdToCopy[_child.GetInstanceID()]);
+                EditorGUILayout.EndHorizontal();
+                if (_child.childCount > 0) {
+                    DrawChildren(_child, 1);
+                }
+            }
+        }
+
+    }
+
+    private void GenerateToggle(Transform parent) {
+        Transform _child;
+        for (int i = 0; i < parent.transform.childCount; ++i) {
+            _child = parent.transform.GetChild(i);
+            m_IdToCopy.Add(_child.GetInstanceID(), false);
+            m_IdToPath.Add(_child.GetInstanceID(), GetPath(_child));
+            if (_child.childCount > 0) {
+                GenerateToggle(_child);
+            }
+        }
+    }
+
+    private void DrawChildren(Transform parent, int lineSpace) {
+        Transform _child;
+        EditorGUI.indentLevel += lineSpace;
+        for (int i = 0; i < parent.transform.childCount; ++i) {
+            _child = parent.transform.GetChild(i);
+            EditorGUILayout.BeginHorizontal();
+            m_IdToCopy[_child.GetInstanceID()] = EditorGUILayout.ToggleLeft(_child.name, m_IdToCopy[_child.GetInstanceID()]);
+            EditorGUILayout.EndHorizontal();
+            if (_child.childCount > 0) {
+                DrawChildren(_child, lineSpace);
+            }
+        }
+        EditorGUI.indentLevel -= lineSpace;
+    }
+
+    private void CopyDefine() {
+        StringBuilder _content = new StringBuilder();
+        GenerateUICode _target = target as GenerateUICode;
+        Transform _child;
+        for (int i = 0; i < _target.transform.childCount; ++i) {
+            _child = _target.transform.GetChild(i);
+            if (m_IdToCopy[_child.GetInstanceID()]) {
+                Component[] _components = _child.GetComponents<Image>();
+                foreach (var _component in _components) {
+                    _content.Append("private ");
+                    _content.Append(typeof(Image).Name);
+                    _content.Append(" m_Img");
+                    _content.Append(_child.name);
+                    _content.Append(";\r\n");
+                }
+
+                _components = _child.GetComponents<Text>();
+                foreach (var _component in _components) {
+                    _content.Append("private ");
+                    _content.Append(typeof(Text).Name);
+                    _content.Append(" m_Txt");
+                    _content.Append(_child.name);
+                    _content.Append(";\r\n");
+                }
+
+                _components = _child.GetComponents<Button>();
+                foreach (var _component in _components) {
+                    _content.Append("private ");
+                    _content.Append(typeof(Button).Name);
+                    _content.Append(" m_Btn");
+                    _content.Append(_child.name);
+                    _content.Append(";\r\n");
+                }
+            }
+
+            if (_child.childCount > 0) {
+                CopyDefineChildren(_child, _content);
+            }
+        }
+
+        TextEditor t = new TextEditor();
+        t.text = _content.ToString();
+        t.OnFocus();
+        t.Copy();
+        _content = null;
+    }
+
+    private void CopyGet() {
+        // UGUITool.GetChildControl<Button>(gameObject, "Img_Background/Btn_Cancel");
+        StringBuilder _content = new StringBuilder();
+        GenerateUICode _target = target as GenerateUICode;
+        Transform _child;
+        for (int i = 0; i < _target.transform.childCount; ++i) {
+            _child = _target.transform.GetChild(i);
+            if (m_IdToCopy[_child.GetInstanceID()]) {
+                Component[] _components = _child.GetComponents<Image>();
+                foreach (var _component in _components) {
+                    _content.Append("m_Img");
+                    _content.Append(_child.name);
+                    _content.Append(" = UGUITool.GetChildControl<");
+                    _content.Append(typeof(Image).Name);
+                    _content.Append(">(gameObject, \"");
+                    _content.Append(m_IdToPath[_child.GetInstanceID()]);
+                    _content.Append("\");\r\n");
+                }
+
+                _components = _child.GetComponents<Text>();
+                foreach (var _component in _components) {
+                    _content.Append("m_Img");
+                    _content.Append(_child.name);
+                    _content.Append(" = UGUITool.GetChildControl<");
+                    _content.Append(typeof(Text).Name);
+                    _content.Append(">(gameObject, \"");
+                    _content.Append(m_IdToPath[_child.GetInstanceID()]);
+                    _content.Append("\");\r\n");
+                }
+
+                _components = _child.GetComponents<Button>();
+                foreach (var _component in _components) {
+                    _content.Append("m_Img");
+                    _content.Append(_child.name);
+                    _content.Append(" = UGUITool.GetChildControl<");
+                    _content.Append(typeof(Button).Name);
+                    _content.Append(">(gameObject, \"");
+                    _content.Append(m_IdToPath[_child.GetInstanceID()]);
+                    _content.Append("\");\r\n");
+                }
+            }
+
+            if (_child.childCount > 0) {
+                CopyGetChildren(_child, _content);
+            }
+        }
+
+        TextEditor t = new TextEditor();
+        t.text = _content.ToString();
+        t.OnFocus();
+        t.Copy();
+        _content = null;
+    }
+
+    private void CopyDefineChildren(Transform parent, StringBuilder content) {
+        Transform _child;
+        for (int i = 0; i < parent.transform.childCount; ++i) {
+            _child = parent.transform.GetChild(i);
+            if (m_IdToCopy[_child.GetInstanceID()]) {
+                Component[] _components = _child.GetComponents<Image>();
+                foreach (var _component in _components) {
+                    content.Append("private ");
+                    content.Append(typeof(Image).Name);
+                    content.Append(" m_Img");
+                    content.Append(_child.name);
+                    content.Append(";\r\n");
+                }
+
+                _components = _child.GetComponents<Text>();
+                foreach (var _component in _components) {
+                    content.Append("private ");
+                    content.Append(typeof(Text).Name);
+                    content.Append(" m_Txt");
+                    content.Append(_child.name);
+                    content.Append(";\r\n");
+                }
+
+                _components = _child.GetComponents<Button>();
+                foreach (var _component in _components) {
+                    content.Append("private ");
+                    content.Append(typeof(Button).Name);
+                    content.Append(" m_Btn");
+                    content.Append(_child.name);
+                    content.Append(";\r\n");
+                }
+            }
+
+            if (_child.childCount > 0) {
+                CopyDefineChildren(_child, content);
+            }
+        }
+    }
+
+    private void CopyGetChildren(Transform parent, StringBuilder content) {
+        Transform _child;
+        for (int i = 0; i < parent.transform.childCount; ++i) {
+            _child = parent.transform.GetChild(i);
+            if (m_IdToCopy[_child.GetInstanceID()]) {
+                Component[] _components = _child.GetComponents<Image>();
+                foreach (var _component in _components) {
+                    content.Append("m_Img");
+                    content.Append(_child.name);
+                    content.Append(" = UGUITool.GetChildControl<");
+                    content.Append(typeof(Image).Name);
+                    content.Append(">(gameObject, \"");
+                    content.Append(m_IdToPath[_child.GetInstanceID()]);
+                    content.Append("\");\r\n");
+                }
+
+                _components = _child.GetComponents<Text>();
+                foreach (var _component in _components) {
+                    content.Append("m_Img");
+                    content.Append(_child.name);
+                    content.Append(" = UGUITool.GetChildControl<");
+                    content.Append(typeof(Text).Name);
+                    content.Append(">(gameObject, \"");
+                    content.Append(m_IdToPath[_child.GetInstanceID()]);
+                    content.Append("\");\r\n");
+                }
+
+                _components = _child.GetComponents<Button>();
+                foreach (var _component in _components) {
+                    content.Append("m_Img");
+                    content.Append(_child.name);
+                    content.Append(" = UGUITool.GetChildControl<");
+                    content.Append(typeof(Button).Name);
+                    content.Append(">(gameObject, \"");
+                    content.Append(m_IdToPath[_child.GetInstanceID()]);
+                    content.Append("\");\r\n");
+                }
+            }
+
+            if (_child.childCount > 0) {
+                CopyGetChildren(_child, content);
+            }
+        }
+    }
+}
+#endif
+
diff --git a/Utility/GenerateUICode.cs.meta b/Utility/GenerateUICode.cs.meta
new file mode 100644
index 0000000..7690b0a
--- /dev/null
+++ b/Utility/GenerateUICode.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 6b62136fc2edb494990f573f8635d3a6
+timeCreated: 1497428070
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/GlobalTimeEvent.cs b/Utility/GlobalTimeEvent.cs
new file mode 100644
index 0000000..501c125
--- /dev/null
+++ b/Utility/GlobalTimeEvent.cs
@@ -0,0 +1,190 @@
+锘縰sing System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System;
+
+
+public class GlobalTimeEvent : SingletonMonobehaviour<GlobalTimeEvent>
+
+{
+    public event Action secondEvent;
+    public event Action fiveSecondEvent;
+    public event Action minuteEvent;
+    public event Action fiveMinuteEvent;
+    public event Action tenMinuteEvent;
+    public event Action halfHourEvent;
+    public event Action hourEvent;
+    public event Action halfMinuteEvent;
+
+    int secondBuf = -1;
+    int fiveSecondBuf = -1;
+    int minuteBuf = -1;
+    int fiveMinuteBuf = -1;
+    int tenMinuteBuf = -1;
+    int halfHourBuf = -1;
+    int hourBuf = -1;
+    int halfMinuteBuf = -1;
+
+    public void Begin()
+    {
+
+    }
+
+    private void Update()
+    {
+        var second = DateTime.Now.Second;
+        if (second != secondBuf)
+        {
+            if (secondEvent != null)
+            {
+                secondEvent();
+            }
+
+            secondBuf = second;
+        }
+
+
+        var fiveSecond = second / 5;
+        if (fiveSecondBuf != fiveSecond)
+        {
+            try
+            {
+                if (fiveSecondEvent != null)
+                {
+                    fiveSecondEvent();
+                }
+            }
+            catch (Exception ex)
+            {
+                Debug.LogException(ex);
+            }
+            finally
+            {
+                fiveSecondBuf = fiveSecond;
+            }
+        }
+
+        var minute = DateTime.Now.Minute;
+        if (minuteBuf != minute)
+        {
+            try
+            {
+                if (minuteEvent != null)
+                {
+                    minuteEvent();
+                }
+            }
+            catch (Exception ex)
+            {
+                Debug.LogException(ex);
+            }
+            finally
+            {
+                minuteBuf = minute;
+            }
+        }
+
+        var thirtySeconds = second / 30;
+        if (halfMinuteBuf != thirtySeconds)
+        {
+            try
+            {
+                if (halfMinuteEvent != null)
+                {
+                    halfMinuteEvent();
+                }
+            }
+            catch (Exception ex)
+            {
+                Debug.LogException(ex);
+            }
+            finally
+            {
+                halfMinuteBuf = thirtySeconds;
+            }
+        }
+
+        var fiveMinute = minute / 5;
+        if (fiveMinuteBuf != fiveMinute)
+        {
+            try
+            {
+                if (fiveMinuteEvent != null)
+                {
+                    fiveMinuteEvent();
+                }
+            }
+            catch (Exception ex)
+            {
+                Debug.LogException(ex);
+            }
+            finally
+            {
+                fiveMinuteBuf = fiveMinute;
+            }
+        }
+
+        var tenMinute = minute / 10;
+        if (tenMinuteBuf != tenMinute)
+        {
+            try
+            {
+                if (tenMinuteEvent != null)
+                {
+                    tenMinuteEvent();
+                }
+            }
+            catch (Exception ex)
+            {
+                Debug.LogException(ex);
+            }
+            finally
+            {
+                tenMinuteBuf = tenMinute;
+            }
+        }
+
+        var thirtyMinute = minute / 30;
+        if (halfHourBuf != thirtyMinute)
+        {
+            try
+            {
+                if (halfHourEvent != null)
+                {
+                    halfHourEvent();
+                }
+            }
+            catch (Exception ex)
+            {
+                Debug.LogException(ex);
+            }
+            finally
+            {
+                halfHourBuf = thirtyMinute;
+            }
+        }
+
+        var hour = DateTime.Now.Hour;
+        if (hourBuf != hour)
+        {
+            try
+            {
+                if (hourEvent != null)
+                {
+                    hourEvent();
+                }
+            }
+            catch (Exception ex)
+            {
+                Debug.LogException(ex);
+            }
+            finally
+            {
+                hourBuf = hour;
+            }
+        }
+
+    }
+
+
+}
diff --git a/Utility/GlobalTimeEvent.cs.meta b/Utility/GlobalTimeEvent.cs.meta
new file mode 100644
index 0000000..4c7db9a
--- /dev/null
+++ b/Utility/GlobalTimeEvent.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 2a14e14162e91574eaaf8f2fb678755d
+timeCreated: 1526874206
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/LayerUtility.cs b/Utility/LayerUtility.cs
new file mode 100644
index 0000000..b38929a
--- /dev/null
+++ b/Utility/LayerUtility.cs
@@ -0,0 +1,85 @@
+锘縰sing UnityEngine;
+using System.Collections;
+using System;
+
+
+public static class LayerUtility
+{
+    public static readonly int DefaultLayer = LayerMask.NameToLayer("Default");
+    public static readonly int DefaultMask = 1 << DefaultLayer;
+
+    public static readonly int GroundLayer = LayerMask.NameToLayer("Ground");
+    public static readonly int GroundMask = 1 << GroundLayer;
+
+    public static readonly int Wall = LayerMask.NameToLayer("Wall");
+    public static readonly int WallMask = 1 << Wall;
+
+    public static readonly int UILayer = LayerMask.NameToLayer("UI");
+    public static readonly int UIMask = 1 << UILayer;
+
+    public static readonly int DevisableUI = LayerMask.NameToLayer("DevisableUI");
+    public static readonly int DevisableUIMask = 1 << DevisableUI;
+
+    public static readonly int UIEffectLayer = LayerMask.NameToLayer("UIEffect");
+    public static readonly int UIEffectMask = 1 << UILayer;
+
+    public static readonly int HUDLayer = LayerMask.NameToLayer("HUD");
+    public static readonly int HUDMask = 1 << HUDLayer;
+
+    public static readonly int Player = LayerMask.NameToLayer("Player");
+    public static readonly int PlayerMask = 1 << Player;
+
+    public static readonly int Monster = LayerMask.NameToLayer("Monster");
+    public static readonly int MonsterMask = 1 << Monster;
+
+    public static readonly int TransparentFX = LayerMask.NameToLayer("TransparentFX");
+    public static readonly int TransparentFXMask = 1 << TransparentFX;
+
+    public static readonly int Hero = LayerMask.NameToLayer("Hero");
+    public static readonly int HeroMask = 1 << Hero;
+
+    public static readonly int MapTrigger = LayerMask.NameToLayer("MapTrigger");
+    public static readonly int MapTriggerMask = 1 << MapTrigger;
+
+    public static readonly int Walkble = LayerMask.NameToLayer("WalkbleLayer");
+    public static readonly int WalkbleMask = 1 << Walkble;
+
+    public static readonly int BossShow = LayerMask.NameToLayer("BossShow");
+    public static readonly int BossShowMask = 1 << BossShow;
+
+    public static readonly int BattleEffectLow = LayerMask.NameToLayer("BattleEffectLow");
+    public static readonly int BattleEffectLowMask = 1 << BattleEffectLow;
+    public static readonly int BattleEffectMid = LayerMask.NameToLayer("BattleEffectMid");
+    public static readonly int BattleEffectMidMask = 1 << BattleEffectMid;
+    public static readonly int BattleEffectHigh = LayerMask.NameToLayer("BattleEffectHigh");
+    public static readonly int BattleEffectHighMask = 1 << BattleEffectHigh;
+
+    public static readonly int Hide = LayerMask.NameToLayer("Hide");
+    public static readonly int HideMask = 1 << Hide;
+
+    public static readonly int MaskShow = LayerMask.NameToLayer("MaskShow");
+    public static readonly int MaskShowMask = 1 << MaskShow;
+
+
+    public static void SetLayer(this GameObject _gameObject, int _layer, bool _recursive)
+    {
+        if (_gameObject == null)
+        {
+            return;
+        }
+
+        _gameObject.layer = _layer;
+
+        if (_recursive && _gameObject.transform.childCount > 0)
+        {
+            var childCount = _gameObject.transform.childCount;
+            for (var i = 0; i < childCount; i++)
+            {
+                var child = _gameObject.transform.GetChild(i);
+                SetLayer(child.gameObject, _layer, true);
+            }
+        }
+
+    }
+
+}
diff --git a/Utility/LayerUtility.cs.meta b/Utility/LayerUtility.cs.meta
new file mode 100644
index 0000000..cc3e33c
--- /dev/null
+++ b/Utility/LayerUtility.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: cba8c84b026445d4ba9d1d0de95419e3
+timeCreated: 1500865329
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/LocalSave.cs b/Utility/LocalSave.cs
new file mode 100644
index 0000000..dc0e396
--- /dev/null
+++ b/Utility/LocalSave.cs
@@ -0,0 +1,225 @@
+锘�//--------------------------------------------------------
+//    [Author]:                   Wu Xijin
+//    [Date]   :           Sunday, May 08, 2016
+//--------------------------------------------------------
+using UnityEngine;
+using System.Text;
+using System;
+
+
+public static class LocalSave
+{
+
+    public static void DeleteAll()
+    {
+        PlayerPrefs.DeleteAll();
+    }
+
+    public static void DeleteKey(string _key)
+    {
+        PlayerPrefs.DeleteKey(_key);
+    }
+
+    public static bool HasKey(string _key)
+    {
+        return PlayerPrefs.HasKey(_key);
+    }
+
+    public static void SetInt(string key, int value)
+    {
+        PlayerPrefs.SetInt(key, value);
+    }
+
+    public static int GetInt(string key, int _default = 0)
+    {
+        if (!PlayerPrefs.HasKey(key))
+        {
+            return _default;
+        }
+        else
+        {
+            return PlayerPrefs.GetInt(key);
+        }
+    }
+
+    public static void SetFloat(string key, float value)
+    {
+
+        PlayerPrefs.SetFloat(key, value);
+    }
+
+    public static float GetFloat(string key, float _default = 0f)
+    {
+        if (!PlayerPrefs.HasKey(key))
+        {
+            return _default;
+        }
+        else
+        {
+            return PlayerPrefs.GetFloat(key);
+        }
+    }
+
+    public static void SetBool(string key, bool value)
+    {
+
+        PlayerPrefs.SetInt(key, value ? 1 : 0);
+    }
+
+    public static bool GetBool(string key, bool _default = false)
+    {
+        if (!PlayerPrefs.HasKey(key))
+        {
+            return _default;
+        }
+        else
+        {
+            return PlayerPrefs.GetInt(key) == 1;
+        }
+    }
+
+    public static void SetString(string key, string value)
+    {
+
+        PlayerPrefs.SetString(key, value);
+    }
+
+    public static string GetString(string key)
+    {
+        if (!PlayerPrefs.HasKey(key))
+        {
+            return string.Empty;
+        }
+        else
+        {
+            return PlayerPrefs.GetString(key);
+        }
+    }
+
+    public static void SetVector3(string key, Vector3 value)
+    {
+        var sb = new StringBuilder();
+        sb.Append(value.x);
+        sb.Append(";");
+        sb.Append(value.y);
+        sb.Append(";");
+        sb.Append(value.z);
+
+        PlayerPrefs.SetString(key, sb.ToString());
+    }
+
+    public static Vector3 GetVector3(string key)
+    {
+        if (!PlayerPrefs.HasKey(key))
+        {
+            return Vector3.zero;
+        }
+        else
+        {
+            var v = new Vector3();
+            var strArray = PlayerPrefs.GetString(key).Split(';');
+            v.x = float.Parse(strArray[0]);
+            v.y = float.Parse(strArray[2]);
+            v.z = float.Parse(strArray[4]);
+
+            return v;
+        }
+    }
+
+    public static void SetIntArray(string key, int[] value)
+    {
+        if (value != null && value.Length > 0)
+        {
+            var sb = new StringBuilder();
+            for (var i = 0; i < value.Length; i++)
+            {
+                sb.Append(value[i]);
+                sb.Append(';');
+            }
+
+            sb.Remove(sb.Length - 1, 1);
+            PlayerPrefs.SetString(key, sb.ToString());
+        }
+        else
+        {
+            PlayerPrefs.DeleteKey(key);
+        }
+    }
+
+    public static int[] GetIntArray(string key)
+    {
+        if (!PlayerPrefs.HasKey(key))
+        {
+            return null;
+        }
+        else
+        {
+            var value = PlayerPrefs.GetString(key);
+
+            var strArray = value.Split(';');
+            var intArray = new int[strArray.Length];
+            for (var i = 0; i < strArray.Length; i++)
+            {
+                int.TryParse(strArray[i], out intArray[i]);
+            }
+
+            return intArray;
+        }
+    }
+
+    public static void SetFloatArray(string key, float[] value)
+    {
+        var sb = new StringBuilder();
+        for (var i = 0; i < value.Length; i++)
+        {
+            sb.Append(value[i]);
+            sb.Append(";");
+        }
+
+        sb.Remove(sb.Length - 1, 1);
+        PlayerPrefs.SetString(key, sb.ToString());
+    }
+
+    public static float[] GetFloatArray(string key)
+    {
+        if (!PlayerPrefs.HasKey(key))
+        {
+            return null;
+        }
+        else
+        {
+            var value = PlayerPrefs.GetString(key);
+            var strArray = value.Split(';');
+            var array = new float[strArray.Length];
+            for (var i = 0; i < strArray.Length; i++)
+            {
+                float.TryParse(strArray[i], out array[i]);
+            }
+
+            return array;
+        }
+
+    }
+
+    public static void SetStringArray(string key, string[] value)
+    {
+        var valueGroup = string.Join(";", value);
+        PlayerPrefs.SetString(key, valueGroup);
+    }
+
+    public static string[] GeStringArray(string key)
+    {
+        if (!PlayerPrefs.HasKey(key))
+        {
+            return null;
+        }
+        else
+        {
+            var value = PlayerPrefs.GetString(key);
+            return value.Split(';');
+        }
+    }
+}
+
+
+
diff --git a/Utility/LocalSave.cs.meta b/Utility/LocalSave.cs.meta
new file mode 100644
index 0000000..4cac676
--- /dev/null
+++ b/Utility/LocalSave.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: bec7a4c05d7689a41ac542acb6406b34
+timeCreated: 1500865329
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/MathUtility.cs b/Utility/MathUtility.cs
new file mode 100644
index 0000000..3982945
--- /dev/null
+++ b/Utility/MathUtility.cs
@@ -0,0 +1,222 @@
+锘縰sing UnityEngine;
+using System;
+
+
+public class MathUtility
+{
+
+    public static Vector3 Rotate90_XZ_CW(Vector3 vector)
+    {
+        Vector3 _vec = new Vector3(vector.z, vector.y, -vector.x);
+        return _vec;
+    }
+
+    public static Vector3 Rotate90_XZ_CCW(Vector3 vector)
+    {
+        Vector3 _vec = new Vector3(-vector.z, vector.y, vector.x);
+        return _vec;
+    }
+
+    public static Vector3 Rotate180_XZ(Vector3 vector)
+    {
+        Vector3 _vec = new Vector3(-vector.x, vector.y, -vector.z);
+        return _vec;
+    }
+
+    /// <summary>
+    /// 杩斿洖鎵嬪娍鏂瑰悜
+    /// </summary>
+    /// <param name="_start"></param>
+    /// <param name="_end"></param>
+    /// <returns></returns>
+    static public GestureType GetGestureDirection(Vector2 _start, Vector2 _end)
+    {
+        GestureType gesture;
+
+        var direction = _end - _start;
+        var x = direction.x;
+        var y = direction.y;
+
+        if (y < x && y > -x)
+        {
+            gesture = GestureType.Right;
+        }
+        else if (y > x && y < -x)
+        {
+            gesture = GestureType.Left;
+        }
+        else if (y > x && y > -x)
+        {
+            gesture = GestureType.Up;
+        }
+        else
+        {
+            gesture = GestureType.Down;
+        }
+
+        return gesture;
+    }
+
+    // public static float FreeFall(float _startY, float _time)
+    // {
+
+    //     float deltaY = 0.5f * Constants.GRAVITY_RATE * Mathf.Pow(_time, 2f);
+
+    //     return _startY - deltaY;
+    // }
+
+    public static float CalculateRefrenceScale(Vector2 _designWH)
+    {
+        var width = _designWH.x;
+        var height = _designWH.y;
+        var refrenceHeight = 0f;
+
+        if (Screen.height / (float)Screen.width > height / (float)width)
+        {
+            refrenceHeight = (float)width / Screen.width * Screen.height;
+        }
+        else
+        {
+            refrenceHeight = height;
+        }
+
+        var scale = refrenceHeight / height;
+
+        return scale;
+    }
+
+    public static float CalDistance(Vector3 srcPos, Vector3 desPos)
+    {
+        return (srcPos.x - desPos.x) * (srcPos.x - desPos.x) + (srcPos.z - desPos.z) * (srcPos.z - desPos.z);
+    }
+
+    /// <summary>
+    /// 杩斿洖Int鏁版嵁涓煇涓�浣嶆槸鍚︿负1
+    /// </summary>
+    /// <param name="value"></param>
+    /// <param name="index">32浣嶆暟鎹殑浠庡彸鍚戝乏鐨勫亸绉讳綅绱㈠紩(0~31)</param>
+    /// <returns>true琛ㄧず璇ヤ綅涓�1锛宖alse琛ㄧず璇ヤ綅涓�0</returns>
+    public static bool GetBitValue(uint value, ushort index)
+    {
+        if (index > 31)
+        {
+            throw new ArgumentOutOfRangeException("index"); //绱㈠紩鍑洪敊
+        }
+
+        var val = 1 << index;
+        return (value & val) == val;
+    }
+
+    /// <summary>
+    /// 璁惧畾Int鏁版嵁涓煇涓�浣嶇殑鍊�
+    /// </summary>
+    /// <param name="value">浣嶈瀹氬墠鐨勫��</param>
+    /// <param name="index">32浣嶆暟鎹殑浠庡彸鍚戝乏鐨勫亸绉讳綅绱㈠紩(0~31)</param>
+    /// <param name="bitValue">true璁捐浣嶄负1,false璁句负0</param>
+    /// <returns>杩斿洖浣嶈瀹氬悗鐨勫��</returns>
+    public static int SetBitValue(int value, ushort index, bool bitValue)
+    {
+        if (index > 31)
+        {
+            throw new ArgumentOutOfRangeException("index"); //绱㈠紩鍑洪敊
+        }
+
+        var val = 1 << index;
+        return bitValue ? (value | val) : (value & ~val);
+    }
+
+    public static bool IsPointInsideRectangel(Vector3 point, Vector3 rectStart, Vector3 rectEnd)
+    {
+        return point.x > rectStart.x && point.x < rectEnd.x && point.z > rectStart.z && point.z < rectEnd.z;
+    }
+
+    /// <summary>
+    /// 杩斿洖瑙掑害浠h〃鐨勫洓鍏冪礌
+    /// </summary>
+    /// <param name="angle"></param>
+    /// <returns></returns>
+    public static Quaternion GetClientRotationFromAngle(int angle)
+    {
+        float _angle = Mathf.Clamp(1.40625f * angle, 0f, 359f);
+        return Quaternion.Euler(0, _angle, 0);
+    }
+
+    public static float DistanceSqrtXZ(Vector3 p1, Vector3 p2)
+    {
+        p1.y = 0;
+        p2.y = 0;
+        return Vector3.SqrMagnitude(p2 - p1);
+    }
+
+    public static Vector3 ForwardXZ(Vector3 target, Vector3 self)
+    {
+        target.y = 0;
+        self.y = 0;
+        return (target - self).normalized;
+    }
+
+    public static bool IsSameDir(Vector3 vec1, Vector3 vec2)
+    {
+        vec1.y = 0;
+        vec2.y = 0;
+
+        return Vector3.Dot(vec1, vec2) > 0;
+    }
+
+    public static bool OppositeDir(Vector3 vec1, Vector3 vec2)
+    {
+        vec1.y = 0;
+        vec2.y = 0;
+
+        return Vector3.Dot(vec1, vec2) < 0;
+    }
+    public static int Power(int a, int e)
+    {
+        int value = 1;
+        for (int i = 0; i < e; i++)
+        {
+            value *= a;
+        }
+
+        return value;
+    }
+
+    public static bool CheckAdult(string _IDNumber)
+    {
+        if (string.IsNullOrEmpty(_IDNumber))
+        {
+            return false;
+        }
+
+        if (_IDNumber.Length == 15)
+        {
+            return true;
+        }
+        else if (_IDNumber.Length == 18)
+        {
+            var year = int.Parse(_IDNumber.Substring(6, 4));
+            var month = int.Parse(_IDNumber.Substring(10, 2));
+            var day = int.Parse(_IDNumber.Substring(12, 2));
+            var borth = new DateTime(year, month, day);
+
+            return (DateTime.Now - borth).TotalDays >= (365 * 18 + 4);
+        }
+        else
+        {
+            return true;
+        }
+    }
+
+    public static float GetFloatFromLitJson(LitJson.JsonData j)
+    {
+        if (j.IsDouble)
+        {
+            return (float)(double)j;
+        }
+        else if (j.IsInt)
+        {
+            return (float)(int)j;
+        }
+        return 0f;
+    }
+}
diff --git a/Utility/MathUtility.cs.meta b/Utility/MathUtility.cs.meta
new file mode 100644
index 0000000..739b727
--- /dev/null
+++ b/Utility/MathUtility.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: c23b2120f2710ef49aae24aa032b7b02
+timeCreated: 1467038210
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/MathUtils.cs b/Utility/MathUtils.cs
new file mode 100644
index 0000000..e08855c
--- /dev/null
+++ b/Utility/MathUtils.cs
@@ -0,0 +1,222 @@
+锘縰sing UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+
+public class MathUtils
+{
+	public static float GetQuatLength(Quaternion q)
+	{
+		return Mathf.Sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w);
+	}
+
+	public static Quaternion GetQuatConjugate(Quaternion q)
+	{
+		return new Quaternion(-q.x, -q.y, -q.z, q.w);
+	}
+
+	/// <summary>
+	/// Logarithm of a unit quaternion. The result is not necessary a unit quaternion.
+	/// </summary>
+	public static Quaternion GetQuatLog(Quaternion q)
+	{
+		Quaternion res = q;
+		res.w = 0;
+
+		if (Mathf.Abs(q.w) < 1.0f)
+		{
+			float theta = Mathf.Acos(q.w);
+			float sin_theta = Mathf.Sin(theta);
+
+			if (Mathf.Abs(sin_theta) > 0.0001)
+			{
+				float coef = theta / sin_theta;
+				res.x = q.x * coef;
+				res.y = q.y * coef;
+				res.z = q.z * coef;
+			}
+		}
+
+		return res;
+	}
+
+	public static Quaternion GetQuatExp(Quaternion q)
+	{
+		Quaternion res = q;
+
+		float fAngle = Mathf.Sqrt(q.x * q.x + q.y * q.y + q.z * q.z);
+		float fSin = Mathf.Sin(fAngle);
+
+		res.w = Mathf.Cos(fAngle);
+
+		if (Mathf.Abs(fSin) > 0.0001)
+		{
+			float coef = fSin / fAngle;
+			res.x = coef * q.x;
+			res.y = coef * q.y;
+			res.z = coef * q.z;
+		}
+
+		return res;
+	}
+
+	/// <summary>
+	/// SQUAD Spherical Quadrangle interpolation [Shoe87]
+	/// </summary>
+	public static Quaternion GetQuatSquad(float t, Quaternion q0, Quaternion q1, Quaternion a0, Quaternion a1)
+	{
+		float slerpT = 2.0f * t * (1.0f - t);
+
+		Quaternion slerpP = Slerp(q0, q1, t);
+		Quaternion slerpQ = Slerp(a0, a1, t);
+
+		return Slerp(slerpP, slerpQ, slerpT);
+	}
+
+	public static Quaternion GetSquadIntermediate(Quaternion q0, Quaternion q1, Quaternion q2)
+	{
+		Quaternion q1Inv = GetQuatConjugate(q1);
+		Quaternion p0 = GetQuatLog(q1Inv * q0);
+		Quaternion p2 = GetQuatLog(q1Inv * q2);
+		Quaternion sum = new Quaternion(-0.25f * (p0.x + p2.x), -0.25f * (p0.y + p2.y), -0.25f * (p0.z + p2.z), -0.25f * (p0.w + p2.w));
+
+		return q1 * GetQuatExp(sum);
+	}
+
+	/// <summary>
+	/// Smooths the input parameter t.
+	/// If less than k1 ir greater than k2, it uses a sin.
+	/// Between k1 and k2 it uses linear interp.
+	/// </summary>
+	public static float Ease(float t, float k1, float k2)
+	{
+		float f; float s;
+
+		f = k1 * 2 / Mathf.PI + k2 - k1 + (1.0f - k2) * 2 / Mathf.PI;
+
+		if (t < k1)
+		{
+			s = k1 * (2 / Mathf.PI) * (Mathf.Sin((t / k1) * Mathf.PI / 2 - Mathf.PI / 2) + 1);
+		}
+		else
+			if (t < k2)
+			{
+				s = (2 * k1 / Mathf.PI + t - k1);
+			}
+			else
+			{
+				s = 2 * k1 / Mathf.PI + k2 - k1 + ((1 - k2) * (2 / Mathf.PI)) * Mathf.Sin(((t - k2) / (1.0f - k2)) * Mathf.PI / 2);
+			}
+
+		return (s / f);
+	}
+
+	/// <summary>
+	/// We need this because Quaternion.Slerp always uses the shortest arc.
+	/// </summary>
+	public static Quaternion Slerp(Quaternion p, Quaternion q, float t)
+	{
+		Quaternion ret;
+
+		float fCos = Quaternion.Dot(p, q);
+
+		if ((1.0f + fCos) > 0.00001)
+		{
+			float fCoeff0, fCoeff1;
+
+			if ((1.0f - fCos) > 0.00001)
+			{
+				float omega = Mathf.Acos(fCos);
+				float invSin = 1.0f / Mathf.Sin(omega);
+				fCoeff0 = Mathf.Sin((1.0f - t) * omega) * invSin;
+				fCoeff1 = Mathf.Sin(t * omega) * invSin;
+			}
+			else
+			{
+				fCoeff0 = 1.0f - t;
+				fCoeff1 = t;
+			}
+
+			ret.x = fCoeff0 * p.x + fCoeff1 * q.x;
+			ret.y = fCoeff0 * p.y + fCoeff1 * q.y;
+			ret.z = fCoeff0 * p.z + fCoeff1 * q.z;
+			ret.w = fCoeff0 * p.w + fCoeff1 * q.w;
+		}
+		else
+		{
+			float fCoeff0 = Mathf.Sin((1.0f - t) * Mathf.PI * 0.5f);
+			float fCoeff1 = Mathf.Sin(t * Mathf.PI * 0.5f);
+
+			ret.x = fCoeff0 * p.x - fCoeff1 * p.y;
+			ret.y = fCoeff0 * p.y + fCoeff1 * p.x;
+			ret.z = fCoeff0 * p.z - fCoeff1 * p.w;
+			ret.w = p.z;
+		}
+
+		return ret;
+	}
+    #region 杩涘埗杞崲
+    private static char[] symbolsArray = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '+', '/' };
+    static string symbolStr = new string(symbolsArray, 0, 64);
+    /// <summary>
+    /// 璁插瓧绗︿覆鐢�64杩涘埗杞负10杩涘埗锛屽墠缂�娌$敤鐨勫彲鐢ㄥ瓧绗�-浠f浛
+    /// </summary>
+    /// <param name="val"></param>
+    /// <returns></returns>
+    public static int Convert64To10(string val)
+    {
+        val=val.Trim('-');
+        int result = 0;
+        long longResult = 0;
+        val = val.Trim();
+        if (string.IsNullOrEmpty(val)) {
+            return result;
+        }
+        if (val.Equals("0")) return 0;
+        for (int i = 0; i < val.Length; i++) {
+            if(!symbolStr.Contains(val[i].ToString())) {
+                //DesignDebug.LogError(string.Format("64杩涘埗鏍煎紡閿欒{0}", val));
+                return 0;
+            }
+            else {
+                try {
+                    int index = 0;
+                    for (int j = 0; j < symbolsArray.Length; j++) {
+                        if (symbolsArray[j] == val[val.Length - i - 1]) {
+                            index = j;
+                        }
+                    }
+                    longResult += (long)System.Math.Pow(64, i) * index;
+                    if(longResult>int.MaxValue) {
+                        Debug.LogError("瓒呭嚭Int鏈�澶у�硷紝灏濊瘯杞崲涓簂ong绫诲瀷");
+                        return 0;
+                    }
+                    result = (int)longResult;
+                }
+                catch {
+                    Debug.LogError("杩愮畻婧㈠嚭");
+                    return 0;
+                }
+            }
+        }
+        return result;
+    }
+    static char[] outSymbol = new char[65];
+    /// <summary>
+    /// 灏�10杩涘埗杞负64杩涘埗鐨勫瓧绗︿覆
+    /// </summary>
+    /// <param name="val"></param>
+    /// <returns></returns>
+    public static string Convert10To64(int val)
+    {
+        if (0 == val) return "0";
+        int index = 0;
+        long longPositive = Mathf.Abs(val);
+        for (index = 0; index <= 64; index++) {
+            if (longPositive == 0) break;
+            outSymbol[outSymbol.Length - index - 1] = symbolsArray[longPositive % 64];
+            longPositive /= 64;
+        }
+        return new string(outSymbol,outSymbol.Length-index,index);
+    }
+    #endregion
+}
\ No newline at end of file
diff --git a/Utility/MathUtils.cs.meta b/Utility/MathUtils.cs.meta
new file mode 100644
index 0000000..c98b648
--- /dev/null
+++ b/Utility/MathUtils.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 7798971efdbbaa649974f94338b197aa
+timeCreated: 1504508766
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/PathUtility.cs b/Utility/PathUtility.cs
new file mode 100644
index 0000000..26aeaa9
--- /dev/null
+++ b/Utility/PathUtility.cs
@@ -0,0 +1,21 @@
+锘縰sing UnityEngine;
+
+public class PathUtility {
+    public static string GetRelationPath(Transform tranform) {
+        System.Text.StringBuilder _stringBuilder = new System.Text.StringBuilder();
+
+        if(tranform.parent != null && tranform.parent.parent == null) {
+            return tranform.name;
+        }
+
+        while(tranform.parent != null) {
+            _stringBuilder.Insert(0,string.Format("/{0}",tranform.name));
+            tranform = tranform.parent;
+        }
+
+        string _result = _stringBuilder.ToString().Substring(1);
+        _stringBuilder = null;
+        return _result;
+    }
+
+}
diff --git a/Utility/PathUtility.cs.meta b/Utility/PathUtility.cs.meta
new file mode 100644
index 0000000..a31dc7b
--- /dev/null
+++ b/Utility/PathUtility.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 5ed15324d246b474aa4dad08c60d51df
+timeCreated: 1477499365
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/ProfilerPanel.cs b/Utility/ProfilerPanel.cs
new file mode 100644
index 0000000..d43522c
--- /dev/null
+++ b/Utility/ProfilerPanel.cs
@@ -0,0 +1,75 @@
+锘�// Copyright (c) 2015 hugula
+// direct https://github.com/tenvick/hugula
+//
+using UnityEngine;
+using System.Collections;
+
+public class ProfilerPanel : MonoBehaviour {
+    const float m_KBSize = 1024.0f * 1024.0f;
+    private string memory, framerate;
+
+    private float updateInterval = 0.2F;
+    private float accum = 0; // FPS accumulated over the interval
+    private int frames = 0; // Frames drawn over the interval
+    private float timeleft; // Left time for current interval
+
+    void Start() {
+        timeleft = updateInterval;
+        //memory = Util.Get<UILabel>(gameObject, "MemoryInfo");
+        //framerate = Util.Get<UILabel>(gameObject, "FrameRate");
+    }
+
+    void Update() {
+        UpdateGameInfo();
+    }
+
+    void OnGUI() {
+        GUILayout.Label("fps:" + framerate);
+        GUILayout.Label("" + memory);
+
+    }
+    /// <summary>
+    /// 鏇存柊娓告垙淇℃伅
+    /// </summary>
+    void UpdateGameInfo() {
+        float totalMemory = (float)(UnityEngine.Profiling.Profiler.GetTotalAllocatedMemoryLong() / m_KBSize);
+        float totalReservedMemory = (float)(UnityEngine.Profiling.Profiler.GetTotalReservedMemoryLong() / m_KBSize);
+        float totalUnusedReservedMemory = (float)(UnityEngine.Profiling.Profiler.GetTotalUnusedReservedMemoryLong() / m_KBSize);
+        float monoHeapSize = (float)(UnityEngine.Profiling.Profiler.GetMonoHeapSizeLong() / m_KBSize);
+        float monoUsedSize = (float)(UnityEngine.Profiling.Profiler.GetMonoUsedSizeLong() / m_KBSize);
+
+        timeleft -= Time.deltaTime;
+        accum += Time.timeScale / Time.deltaTime;
+        ++frames;
+
+        // Interval ended - update GUI text and start new interval
+        if (timeleft <= 0.0) {
+            // display two fractional digits (f2 format)
+            float fps = accum / frames;
+            framerate = fps.ToString();// ioo.f("fps:{0:F2}", fps);
+
+            //if (fps < 30) {
+            //    framerate.color = Color.yellow;
+            //} else {
+            //    if (fps < 10) {
+            //        framerate.color = Color.red;
+            //    } else {
+            //        framerate.color = Color.green;
+            //    }
+            //}
+            timeleft = updateInterval;
+            accum = 0.0F;
+            frames = 0;
+        }
+
+        memory = string.Format("TotalAllocatedMemory:{0}MB\n" + //TotalAllocatedMemory
+                               "TotalReservedMemory:{1}MB\n" +
+                               "TotalUnusedReservedMemory:{2}MB\n" +
+                               "MonoHeapSize:{3}MB\nMonoUsedSize:{4}MB",
+                               totalMemory,
+                               totalReservedMemory,
+                               totalUnusedReservedMemory,
+                               monoHeapSize,
+                               monoUsedSize);
+    }
+}
diff --git a/Utility/ProfilerPanel.cs.meta b/Utility/ProfilerPanel.cs.meta
new file mode 100644
index 0000000..6379ef1
--- /dev/null
+++ b/Utility/ProfilerPanel.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 3793f8e230f43a143b1acbf26d102561
+timeCreated: 1469636127
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/RenderOrder.cs b/Utility/RenderOrder.cs
new file mode 100644
index 0000000..cdf9041
--- /dev/null
+++ b/Utility/RenderOrder.cs
@@ -0,0 +1,23 @@
+锘縰sing System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+[ExecuteAlways]
+public class RenderOrder : MonoBehaviour
+{
+    public int order = 10000;
+
+    [ExecuteAlways]
+    private void OnEnable()
+    {
+        LayerUtility.SetLayer(this.gameObject, LayerUtility.UILayer, true);
+        Renderer[] renders = this.GetComponentsInChildren<Renderer>(true);
+        for (int i = 0; i < renders.Length; i++)
+        {
+            var render = renders[i];
+            render.sortingLayerName = "UI";
+            render.sortingOrder = order;
+        }
+    }
+
+}
diff --git a/Utility/RenderOrder.cs.meta b/Utility/RenderOrder.cs.meta
new file mode 100644
index 0000000..1a814ca
--- /dev/null
+++ b/Utility/RenderOrder.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 4196ae3a492cb814fb93e017c99cd02a
+timeCreated: 1506320986
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/RenderTextureCreator.cs b/Utility/RenderTextureCreator.cs
new file mode 100644
index 0000000..4c64184
--- /dev/null
+++ b/Utility/RenderTextureCreator.cs
@@ -0,0 +1,56 @@
+锘縰sing System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class RenderTextureCreator : MonoBehaviour
+{
+    [SerializeField] Vector2 m_Size;
+    [SerializeField] Camera m_TargetCamera;
+    [SerializeField] bool m_Reuse = false;
+
+    static Dictionary<Vector2, RenderTexture> m_RenderTexDict = new Dictionary<Vector2, RenderTexture>();
+
+    private void Awake()
+    {
+        if (m_TargetCamera != null && m_TargetCamera.targetTexture == null)
+        {
+            RenderTexture rt;
+            if (m_Reuse && GetRenderTexture(m_Size, out rt))
+            {
+                m_TargetCamera.targetTexture = rt;
+                return;
+            }
+
+            rt = new RenderTexture(Mathf.RoundToInt(m_Size.x), Mathf.RoundToInt(m_Size.y), 16);
+            switch (Application.platform)
+            {
+                case RuntimePlatform.OSXEditor:
+                case RuntimePlatform.WindowsEditor:
+                case RuntimePlatform.WindowsPlayer:
+                    rt.format = RenderTextureFormat.ARGB32;
+                    break;
+                default:
+                    rt.format = RenderTextureFormat.ARGB4444;
+                    break;
+            }
+
+            rt.useMipMap = false;
+            rt.wrapMode = TextureWrapMode.Clamp;
+            rt.filterMode = FilterMode.Bilinear;
+
+            m_TargetCamera.targetTexture = rt;
+
+            if (!m_RenderTexDict.ContainsKey(m_Size))
+            {
+                m_RenderTexDict.Add(m_Size, rt);
+            }
+        }
+
+    }
+
+    public static bool GetRenderTexture(Vector2 _Size, out RenderTexture _tex)
+    {
+        return m_RenderTexDict.TryGetValue(_Size, out _tex);
+    }
+
+}
diff --git a/Utility/RenderTextureCreator.cs.meta b/Utility/RenderTextureCreator.cs.meta
new file mode 100644
index 0000000..7c1485a
--- /dev/null
+++ b/Utility/RenderTextureCreator.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: a6ab8bffaed37d846ae2d0d53bc3579c
+timeCreated: 1524621710
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/ResolutionUtility.cs b/Utility/ResolutionUtility.cs
new file mode 100644
index 0000000..d76eac2
--- /dev/null
+++ b/Utility/ResolutionUtility.cs
@@ -0,0 +1,64 @@
+锘縰sing System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System.Diagnostics;
+
+public class ResolutionUtility
+{
+    public static readonly Vector2 originalResolution = new Vector2(Screen.width, Screen.height);
+    public static Vector2 currentResolution = new Vector2(Screen.width, Screen.height);
+
+    [Conditional("UNITY_ANDROID")]
+    public static void AdjustResolution()
+    {
+        Screen.SetResolution(Mathf.RoundToInt(currentResolution.x), Mathf.RoundToInt(currentResolution.y), true);
+    }
+
+    // public static void AdjustResolution(GameQuality _quality)
+    // {
+    //     switch (_quality)
+    //     {
+    //         case GameQuality.Low:
+    //             currentResolution = ConvertResolution(new Vector2(1280, 720));
+    //             break;
+    //         case GameQuality.Medium:
+    //             currentResolution = ConvertResolution(new Vector2(1920, 1080));
+    //             break;
+    //         case GameQuality.High:
+    //             currentResolution = ConvertResolution(new Vector2(1920, 1080));
+    //             break;
+    //     }
+
+    //     Screen.SetResolution(Mathf.RoundToInt(currentResolution.x), Mathf.RoundToInt(currentResolution.y), true);
+    // }
+
+    static Vector2 ConvertResolution(Vector2 _inputResolution)
+    {
+        var resolution = Screen.currentResolution;
+        var ratio = (resolution.width / (float)resolution.height) / ((float)16 / 9);
+
+        var height = 0f;
+        var width = 0f;
+        if (ratio > 1)
+        {
+            height = _inputResolution[1];
+            width = Mathf.RoundToInt(resolution.width / (float)resolution.height * height);
+        }
+        else
+        {
+            width = _inputResolution[0];
+            height = Mathf.RoundToInt((float)resolution.height / resolution.width * width);
+        }
+
+        if (height * width - originalResolution.x * originalResolution.y > 10)
+        {
+            return originalResolution;
+        }
+        else
+        {
+            return new Vector2(width, height);
+        }
+
+    }
+
+}
\ No newline at end of file
diff --git a/Utility/ResolutionUtility.cs.meta b/Utility/ResolutionUtility.cs.meta
new file mode 100644
index 0000000..0662487
--- /dev/null
+++ b/Utility/ResolutionUtility.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 235aa1e7e3889cf48ad941751c9a43cb
+timeCreated: 1524315248
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/SnxxzUtility.cs b/Utility/SnxxzUtility.cs
new file mode 100644
index 0000000..e0c9f1e
--- /dev/null
+++ b/Utility/SnxxzUtility.cs
@@ -0,0 +1,24 @@
+锘縰sing System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public static class SnxxzUtility
+{
+
+    public static UnityPlatform flatForm {
+        get {
+#if UNITY_EDITOR
+            return UnityPlatform.Editor;
+#elif UNITY_IOS || UNITY_IPHONE
+             return UnityPlatform.Iphone;
+#elif UNITY_STANDALONE
+             return UnityPlatform.Standalone;
+#elif UNITY_ANDROID
+             return UnityPlatform.Android;
+#else
+             return UnityPlatform.Editor;
+#endif
+        }
+    }
+
+}
diff --git a/Utility/SnxxzUtility.cs.meta b/Utility/SnxxzUtility.cs.meta
new file mode 100644
index 0000000..c0b47fb
--- /dev/null
+++ b/Utility/SnxxzUtility.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 0b18221669f13aa4d8fd93fca35e350a
+timeCreated: 1497862531
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/StringUtility.cs b/Utility/StringUtility.cs
new file mode 100644
index 0000000..f5b3e51
--- /dev/null
+++ b/Utility/StringUtility.cs
@@ -0,0 +1,46 @@
+锘縰sing UnityEngine;
+using System.Collections;
+using System.Text;
+
+public class StringUtility
+{
+    public static string[] splitSeparator = new string[] { "|" };
+
+    private static StringBuilder s_CacheStringBuilder = new StringBuilder();
+
+    static object lockObject = new object();
+
+    public static string Contact(params object[] _objects)
+    {
+        lock (lockObject)
+        {
+            s_CacheStringBuilder.Remove(0, s_CacheStringBuilder.Length);
+            for (int i = 0; i < _objects.Length; ++i)
+            {
+                if (_objects[i] != null)
+                {
+                    s_CacheStringBuilder.Append(_objects[i]);
+                }
+            }
+            return s_CacheStringBuilder.ToString();
+        }
+    }
+
+
+    public static string FormatSpeed(float speed)
+    {
+        if (speed > 1048576f)
+        {
+            return StringUtility.Contact((speed / 1048576f).ToString("f1"), " M/S");
+        }
+        else if (speed > 1024f)
+        {
+            return StringUtility.Contact((speed / 1024f).ToString("f1"), " KB/S");
+        }
+        else
+        {
+            return StringUtility.Contact(speed.ToString("f1"), " B/S");
+        };
+    }
+
+}
diff --git a/Utility/StringUtility.cs.meta b/Utility/StringUtility.cs.meta
new file mode 100644
index 0000000..b903ac9
--- /dev/null
+++ b/Utility/StringUtility.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: c0960ed66238bdd49b70860dfee23488
+timeCreated: 1475005527
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/SystemCMD.cs b/Utility/SystemCMD.cs
new file mode 100644
index 0000000..33eb7d4
--- /dev/null
+++ b/Utility/SystemCMD.cs
@@ -0,0 +1,36 @@
+锘縰sing System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class SystemCMD
+{
+    /// <summary>
+    /// 璋冪敤缁堢鎵ц鍛戒护
+    /// </summary>
+    /// <param name="command"></param>
+    /// <returns></returns>
+    public static string RunCmd(string command)
+    {
+        System.Diagnostics.Process p = new System.Diagnostics.Process();
+        p.StartInfo.FileName = "cmd.exe";           //纭畾绋嬪簭鍚�
+        p.StartInfo.Arguments = "/c " + command;    //纭畾绋嬪紡鍛戒护琛�
+        p.StartInfo.UseShellExecute = false;        //Shell鐨勪娇鐢�
+        p.StartInfo.RedirectStandardInput = true;   //閲嶅畾鍚戣緭鍏�
+        p.StartInfo.RedirectStandardOutput = true; //閲嶅畾鍚戣緭鍑�
+        p.StartInfo.RedirectStandardError = true;   //閲嶅畾鍚戣緭鍑洪敊璇�
+        p.StartInfo.CreateNoWindow = true;          //璁剧疆缃笉鏄剧ず绀虹獥鍙�
+        p.Start();
+        p.WaitForExit();
+        string err = p.StandardError.ReadToEnd();
+        string standoutput = p.StandardOutput.ReadToEnd();
+        if (string.IsNullOrEmpty(err))
+        {
+            return standoutput;
+        }
+        else
+        {
+            return err;        //杈撳嚭鍑烘祦鍙栧緱鍛戒护琛岀粨鏋滄灉
+        }
+    }
+
+}
diff --git a/Utility/SystemCMD.cs.meta b/Utility/SystemCMD.cs.meta
new file mode 100644
index 0000000..2936b62
--- /dev/null
+++ b/Utility/SystemCMD.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 6de2d4b13bfadaf419c682196b36e001
+timeCreated: 1541043601
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/TAny.cs b/Utility/TAny.cs
new file mode 100644
index 0000000..63481a1
--- /dev/null
+++ b/Utility/TAny.cs
@@ -0,0 +1,13 @@
+锘縰sing UnityEngine;
+using System.Collections;
+
+namespace Dmyx.Fight
+{
+    public class TAny
+    {
+        public T As<T>() where T : TAny
+        {
+            return (T)this;
+        }
+    }
+}
diff --git a/Utility/TAny.cs.meta b/Utility/TAny.cs.meta
new file mode 100644
index 0000000..1bae18e
--- /dev/null
+++ b/Utility/TAny.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: fd4098dfea0479a4d88da5adb0765f78
+timeCreated: 1472490736
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/TBlackBoard.cs b/Utility/TBlackBoard.cs
new file mode 100644
index 0000000..cf7c18c
--- /dev/null
+++ b/Utility/TBlackBoard.cs
@@ -0,0 +1,47 @@
+锘縰sing System.Collections.Generic;
+
+public class TBlackBoard {
+
+    class TBlackboardItem {
+
+        private object m_Value;
+
+        public void SetValue(object v) {
+            m_Value = v;
+        }
+
+        public T GetValue<T>() {
+            return (T)m_Value;
+        }
+    }
+
+    private Dictionary<string, TBlackboardItem> m_ItemDict;
+
+    public TBlackBoard() {
+        m_ItemDict = new Dictionary<string, TBlackboardItem>();
+    }
+
+    ~TBlackBoard() {
+        m_ItemDict.Clear();
+        m_ItemDict = null;
+    }
+
+    public void SetValue(string key, object v) {
+        TBlackboardItem item;
+        if (m_ItemDict.ContainsKey(key) == false) {
+            item = new TBlackboardItem();
+            m_ItemDict.Add(key, item);
+        }
+        else {
+            item = m_ItemDict[key];
+        }
+        item.SetValue(v);
+    }
+
+    public T GetValue<T>(string key, T defaultValue) {
+        if (m_ItemDict.ContainsKey(key) == false) {
+            return defaultValue;
+        }
+        return m_ItemDict[key].GetValue<T>();
+    }
+}
diff --git a/Utility/TBlackBoard.cs.meta b/Utility/TBlackBoard.cs.meta
new file mode 100644
index 0000000..0944475
--- /dev/null
+++ b/Utility/TBlackBoard.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 94b510a87ef3f534db28c3c7fa3bb291
+timeCreated: 1499999089
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/TransformExtension.cs b/Utility/TransformExtension.cs
new file mode 100644
index 0000000..c17d0ad
--- /dev/null
+++ b/Utility/TransformExtension.cs
@@ -0,0 +1,197 @@
+锘縰sing UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+
+
+public static class TransformExtension
+{
+
+    
+    public static void Destroy(this Transform transform)
+    {
+        if (Application.isPlaying)
+            GameObject.Destroy(transform);//寤惰繜閿�姣�,涓嬩竴甯ф墽琛�,鍦ㄦ父鎴忚繍琛屾椂浣跨敤
+        else
+            GameObject.DestroyImmediate(transform);//绔嬪嵆閿�姣�,鍦ㄧ紪杈戞椂浣跨敤
+    }
+
+    //娓呯┖瀛愮墿浣�
+    
+    public static void ClearAllChilds(this Transform transform)
+    {
+        var count = transform.childCount;
+        for (var i = 0; i < count; i++)
+        {
+            if (Application.isPlaying)
+                GameObject.Destroy(transform.GetChild(i).gameObject);//寤惰繜閿�姣�,涓嬩竴甯ф墽琛�,鍦ㄦ父鎴忚繍琛屾椂浣跨敤
+            else
+                GameObject.DestroyImmediate(transform.GetChild(0).gameObject);//绔嬪嵆閿�姣�,鍦ㄧ紪杈戞椂浣跨敤
+
+        }
+    }
+
+    
+    public static void SetParentEx(this Transform transform, Transform parent, Vector3 localPosition, Quaternion rotation, Vector3 scale)
+    {
+
+        if (transform != null && parent != null)
+        {
+            transform.SetParent(parent);
+            transform.localPosition = localPosition;
+            transform.localRotation = rotation;
+            transform.localScale = scale;
+        }
+    }
+
+    
+    public static void SetParentEx(this Transform transform, Transform parent, Vector3 localPosition, Vector3 eulerAngles, Vector3 scale)
+    {
+        if (transform != null && parent != null)
+        {
+            transform.SetParent(parent);
+            transform.localPosition = localPosition;
+            transform.localEulerAngles = eulerAngles;
+            transform.localScale = scale;
+        }
+    }
+
+    public static T[] GetComponentsInChildren<T>(this Transform transform, bool includeInactive, bool includeSelf) where T : Component
+    {
+
+        if (includeSelf)
+        {
+            return transform.GetComponentsInChildren<T>(includeInactive);
+        }
+        else
+        {
+            int childCount = transform.childCount;
+            List<T> list = new List<T>();
+            T t = null;
+            for (int i = 0; i < childCount; i++)
+            {
+                t = transform.GetComponent<T>();
+                if (t != null)
+                {
+                    list.Add(t);
+                }
+            }
+            return list.ToArray();
+        }
+
+    }
+
+    
+    public static Transform GetChildTransformDeeply(this Transform transform, string childName, bool includeSelf = false)
+    {
+
+        if (includeSelf)
+        {
+            if (transform.name.Equals(childName))
+            {
+                return transform;
+            }
+        }
+
+        int _count = transform.childCount;
+
+        Transform _tempChild = null;
+
+        for (int i = 0; i < _count; ++i)
+        {
+
+            _tempChild = transform.GetChild(i);
+
+            if (_tempChild.name.Equals(childName))
+            {
+                return _tempChild;
+            }
+
+            _tempChild = transform.GetChild(i).GetChildTransformDeeply(childName, false);
+            if (_tempChild)
+            {
+                return _tempChild;
+            }
+        }
+
+        return null;
+    }
+
+    /// <summary>
+    /// 浠ラ敋鍥涗釜瑙掔殑鏂瑰紡杩涜鍖归厤
+    /// 骞朵笖灏嗗璞¤缃负鐖跺璞�
+    /// </summary>
+    /// <param name="_child"></param>
+    /// <param name="_parent"></param>
+    
+    public static void MatchWhith(this RectTransform _child, RectTransform _parent)
+    {
+
+        if (_child.parent != _parent)
+        {
+            _child.SetParent(_parent);
+        }
+        _child.anchoredPosition3D = Vector3.zero;
+        _child.sizeDelta = Vector2.zero;
+        _child.anchorMin = Vector2.zero;
+        _child.anchorMax = Vector2.one;
+        _child.pivot = Vector2.one * 0.5f;
+        _child.localRotation = Quaternion.identity;
+        _child.localScale = Vector3.one;
+    }
+
+    
+    public static bool ContainWorldPosition(this RectTransform _rectTransform, Vector3 _worldPosition)
+    {
+        var worldCorners = new Vector3[4];
+        _rectTransform.GetWorldCorners(worldCorners);
+        if (_worldPosition.x >= worldCorners[0].x && _worldPosition.x <= worldCorners[2].x
+            && _worldPosition.y >= worldCorners[0].y && _worldPosition.y <= worldCorners[2].y)
+        {
+            return true;
+        }
+
+        return false;
+    }
+
+    
+    public static bool RectTransformContain(this RectTransform _rectTransform, RectTransform _target)
+    {
+        var targetWorldCorners = new Vector3[4];
+        _target.GetWorldCorners(targetWorldCorners);
+
+        for (int i = 0; i < targetWorldCorners.Length; i++)
+        {
+            var position = targetWorldCorners[i];
+            if (_rectTransform.ContainWorldPosition(position))
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    
+    public static void SetPosition(this Transform transform, float x, float y, float z, bool isLocal = false)
+    {
+        if (transform == null)
+        {
+            return;
+        }
+
+        if (isLocal)
+        {
+            transform.localPosition = new Vector3(x, y, z);
+        }
+        else
+        {
+            transform.position = new Vector3(x, y, z);
+        }
+    }
+
+    public static Transform GetRoot(this Transform transform)
+    {
+        return transform && transform.parent ? GetRoot(transform.parent) : transform;
+    }
+
+}
diff --git a/Utility/TransformExtension.cs.meta b/Utility/TransformExtension.cs.meta
new file mode 100644
index 0000000..38e8a6c
--- /dev/null
+++ b/Utility/TransformExtension.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: c460f6f6ed413344cb56e19c83e6d7c9
+timeCreated: 1458662341
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/UGUIEventListenerContainDrag.cs b/Utility/UGUIEventListenerContainDrag.cs
new file mode 100644
index 0000000..56e7dfd
--- /dev/null
+++ b/Utility/UGUIEventListenerContainDrag.cs
@@ -0,0 +1,72 @@
+锘縰sing UnityEngine;
+using UnityEngine.UI;
+using UnityEngine.EventSystems;
+
+public class UGUIEventListenerContainDrag : MonoBehaviour,
+                            IPointerClickHandler,
+                            IPointerDownHandler,
+                            IPointerEnterHandler,
+                            IPointerExitHandler,
+                            IPointerUpHandler,
+                            IBeginDragHandler,
+                            IDragHandler,
+                            IEndDragHandler
+{
+    public delegate void VoidDelegate(GameObject go);
+    public delegate void VoidDelegateDrag(GameObject go, PointerEventData eventData);
+    public VoidDelegate OnClick { get; set; }
+    public VoidDelegate OnDown { get; set; }
+    public VoidDelegate OnEnter { get; set; }
+    public VoidDelegate OnLongPress { get; set; }
+    public VoidDelegate OnExit { get; set; }
+    public VoidDelegate OnUp { get; set; }
+    public VoidDelegateDrag OnDragStart { get; set; }
+    public VoidDelegateDrag OnDraging { get; set; }
+    public VoidDelegateDrag OnDragEnd { get; set; }
+
+    private string mAudioType;
+    //鏄惁澶勪簬鎸変笅鐘舵�� 涓庨暱鎸夐厤鍚堜娇鐢�
+    bool isDown = false;
+    float time = 0;
+
+    public void OnPointerClick(PointerEventData eventData)
+    {
+        if (OnClick != null)
+        {
+            if (!GetComponent<Button>() || GetComponent<Button>().interactable)
+            {
+                OnClick(gameObject);
+            }
+        }
+    }
+    public void OnPointerDown(PointerEventData eventData)
+    {
+        OnDown?.Invoke(gameObject);
+        time = Time.realtimeSinceStartup;
+        isDown = true;
+    }
+    public void OnPointerEnter(PointerEventData eventData) { OnEnter?.Invoke(gameObject); }
+    public void OnPointerExit(PointerEventData eventData) { OnExit?.Invoke(gameObject); isDown = false; }
+    public void OnPointerUp(PointerEventData eventData) { OnUp?.Invoke(gameObject); isDown = false; time = Time.realtimeSinceStartup; }
+    public void OnBeginDrag(PointerEventData eventData) { OnDragStart?.Invoke(gameObject, eventData); }
+    public void OnDrag(PointerEventData eventData) { OnDraging?.Invoke(gameObject, eventData); }
+    public void OnEndDrag(PointerEventData eventData) { OnDragEnd?.Invoke(gameObject, eventData); }
+
+    public static UGUIEventListenerContainDrag Get(GameObject go, string clickAudio = null)
+    {
+        UGUIEventListenerContainDrag listener = go.GetComponent<UGUIEventListenerContainDrag>();
+        if (listener == null) listener = go.AddComponent<UGUIEventListenerContainDrag>();
+        listener.mAudioType = clickAudio;
+        return listener;
+    }
+
+    void Update()
+    {
+        //闀挎寜
+        if (OnLongPress != null && isDown && Time.realtimeSinceStartup - time > 0.8f)
+        {
+            OnLongPress(gameObject);
+            isDown = false;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Utility/UGUIEventListenerContainDrag.cs.meta b/Utility/UGUIEventListenerContainDrag.cs.meta
new file mode 100644
index 0000000..214be3f
--- /dev/null
+++ b/Utility/UGUIEventListenerContainDrag.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 20949383143a1104abfbc87b0db734e3
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/UIParamCopyTool.cs b/Utility/UIParamCopyTool.cs
new file mode 100644
index 0000000..ec04a10
--- /dev/null
+++ b/Utility/UIParamCopyTool.cs
@@ -0,0 +1,258 @@
+锘縰sing System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+#if UNITY_EDITOR
+using UnityEditor;
+#endif
+public class UIParamCopyTool : MonoBehaviour
+{
+    private List<UIObject> copyObjects = new List<UIObject>();
+    public List<UITarget> copyTargets = new List<UITarget>();
+    public void Add()
+    {
+        var _obejct = new UIObject();
+        _obejct.type = UIType.None;
+        copyObjects.Add(_obejct);
+    }
+
+    public UIObject this[int _index]
+    {
+        get
+        {
+            if (_index < copyObjects.Count && _index >= 0)
+            {
+                return copyObjects[_index];
+            }
+            return null;
+        }
+    }
+
+    public void Remove(int _index)
+    {
+        var _object = copyObjects[_index];
+        copyObjects.RemoveAt(_index);
+        _object = null;
+    }
+
+    public int Count
+    {
+        get
+        {
+            return copyObjects.Count;
+        }
+    }
+
+    public void FindTarget(string _parentName)
+    {
+        copyTargets.Clear();
+        FindTarget(transform, _parentName);
+    }
+
+    public void Paste()
+    {
+        foreach (var _object in copyObjects)
+        {
+            foreach (var _target in copyTargets)
+            {
+                _target.Paste(_object);
+            }
+        }
+    }
+
+    public void FindTarget(Transform _parent, string _parentName)
+    {
+        if(_parent == null|| _parent.childCount == 0)
+        {
+            return;
+        }
+        foreach (Transform _tran in _parent)
+        {
+            if (_tran.name == _parentName)
+            {
+                var _target = new UITarget()
+                {
+                    Object = _tran.gameObject,
+                    ok = true,
+                };
+                _target.Init();
+                copyTargets.Add(_target);
+                continue;
+            }
+            FindTarget(_tran, _parentName);
+        }
+    }
+
+    public class UIObject
+    {
+        public Graphic Object;
+        public UIType type;
+        public string name = string.Empty;
+    }
+
+    public class UITarget
+    {
+        public GameObject Object;
+        public bool ok = true;
+
+        public List<Image> images = new List<Image>();
+        public List<Text> texts = new List<Text>();
+
+        public void Init()
+        {
+            Object.GetComponentsInChildren<Image>(true, images);
+            Object.GetComponentsInChildren<Text>(true, texts);
+        }
+
+        public void Paste(UIObject _object)
+        {
+            switch (_object.type)
+            {
+                case UIType.None:
+                    break;
+                case UIType.Image:
+                    PasteImage(_object);
+                    break;
+                case UIType.Text:
+                    PasteText(_object);
+                    break;
+            }
+        }
+
+        public void PasteRectTransform(RectTransform _target, RectTransform _paste)
+        {
+            _target.pivot = _paste.pivot;
+            _target.anchorMax = _paste.anchorMax;
+            _target.anchorMin = _paste.anchorMin;
+            _target.sizeDelta = _paste.sizeDelta;
+            _target.localPosition = _paste.localPosition;
+        }
+
+        public void PasteImage(UIObject _object)
+        {
+            var _imageArray = images.FindAll((x) =>
+            {
+                return x.name == _object.name;
+            });
+            if (_imageArray == null)
+            {
+                return;
+            }
+            for (int i = 0; i < _imageArray.Count; i++)
+            {
+                var _image = _imageArray[i];
+                var _paste = _object.Object as Image;
+                _image.sprite = _paste.sprite;
+                _image.color = _paste.color;
+                _image.raycastTarget = _paste.raycastTarget;
+                PasteRectTransform(_image.rectTransform, _paste.rectTransform);
+            }
+        }
+
+        public void PasteText(UIObject _object)
+        {
+            var _textArray = texts.FindAll((x) =>
+            {
+                return x.name == _object.name;
+            });
+            if (_textArray == null)
+            {
+                return;
+            }
+            for (int i = 0; i < _textArray.Count; i++)
+            {
+                var _text = _textArray[i];
+                var _paste = _object.Object as Text;
+                _text.color = _paste.color;
+                _text.fontSize = _paste.fontSize;
+                _text.font = _paste.font;
+                _text.raycastTarget = _paste.raycastTarget;
+                _text.alignment = _paste.alignment;
+                _text.horizontalOverflow = _paste.horizontalOverflow;
+                _text.verticalOverflow = _paste.verticalOverflow;
+                PasteRectTransform(_text.rectTransform, _paste.rectTransform);
+            }
+            
+        }
+    }
+
+    public enum UIType
+    {
+        None,
+        Image,
+        Text,
+    }
+}
+
+#if UNITY_EDITOR
+[CustomEditor(typeof(UIParamCopyTool))]
+public class UIParamCopyToolEditor : Editor
+{
+    private Vector2 scrollposition;
+    private Vector2 scrollposition1;
+    private string targetName = string.Empty;
+
+    public override void OnInspectorGUI()
+    {
+        var _target = target as UIParamCopyTool;
+        if (GUILayout.Button("+"))
+        {
+            _target.Add();
+        }
+        scrollposition = GUILayout.BeginScrollView(scrollposition);
+        for (int i = 0; i < _target.Count; i++)
+        {
+            GUILayout.BeginHorizontal();
+            EditorGUILayout.EnumPopup(_target[i].type);
+            if (_target[i].Object == null)
+            {
+                _target[i].Object = (Graphic)EditorGUILayout.ObjectField("Component:", _target[i].Object, typeof(Graphic), true);
+            }
+            else if (_target[i].Object is Image)
+            {
+                _target[i].name = _target[i].Object.name;
+                _target[i].type = UIParamCopyTool.UIType.Image;
+                _target[i].Object = (Image)EditorGUILayout.ObjectField(_target[i].name, _target[i].Object, typeof(Image), true);
+            }
+            else if (_target[i].Object is Text)
+            {
+                _target[i].name = _target[i].Object.name;
+                _target[i].type = UIParamCopyTool.UIType.Text;
+                _target[i].Object = (Text)EditorGUILayout.ObjectField(_target[i].name, _target[i].Object, typeof(Text), true);
+            }
+            if (GUILayout.Button("-"))
+            {
+                _target.Remove(i);
+                i--;
+            }
+            GUILayout.EndHorizontal();
+        }
+        GUILayout.EndScrollView();
+        GUILayout.BeginHorizontal();
+        targetName = EditorGUILayout.TextField("鐩爣鍚嶏細", targetName);
+        if (GUILayout.Button("Find"))
+        {
+            if (targetName != string.Empty)
+            {
+                _target.FindTarget(targetName);
+            }
+        }
+        GUILayout.EndHorizontal();
+        scrollposition1 = GUILayout.BeginScrollView(scrollposition1);
+        for (int i = 0; i < _target.copyTargets.Count; i++)
+        {
+            GUILayout.BeginHorizontal();
+            var _copyTarget = _target.copyTargets[i];
+            _copyTarget.ok = EditorGUILayout.Toggle("鏄惁鏇挎崲", _copyTarget.ok, GUILayout.Width(40));
+            EditorGUILayout.LabelField(StringUtility.Contact("Image", _copyTarget.images.Count));
+            EditorGUILayout.LabelField(StringUtility.Contact("Text", _copyTarget.texts.Count));
+            GUILayout.EndHorizontal();
+        }
+        GUILayout.EndScrollView();
+        if (GUILayout.Button("Paste"))
+        {
+            _target.Paste();
+        }
+    }
+}
+#endif
diff --git a/Utility/UIParamCopyTool.cs.meta b/Utility/UIParamCopyTool.cs.meta
new file mode 100644
index 0000000..a32c455
--- /dev/null
+++ b/Utility/UIParamCopyTool.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 83c3216266f2309419f0711814581fd8
+timeCreated: 1518159911
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/VectorUtility.cs b/Utility/VectorUtility.cs
new file mode 100644
index 0000000..cc2af3f
--- /dev/null
+++ b/Utility/VectorUtility.cs
@@ -0,0 +1,74 @@
+锘縰sing UnityEngine;
+
+public static class VectorUtility
+{
+
+    public static Vector3 SetX(this Vector3 vector3, float x)
+    {
+        vector3.x = x;
+        return vector3;
+    }
+
+    public static Vector3 SetY(this Vector3 vector3, float y)
+    {
+        vector3.y = y;
+        return vector3;
+    }
+
+    public static Vector3 SetZ(this Vector3 vector3, float z)
+    {
+        vector3.z = z;
+        return vector3;
+    }
+
+    public static Vector2 SetX(this Vector2 vector2, float x)
+    {
+        vector2.x = x;
+        return vector2;
+    }
+
+    public static Vector2 SetY(this Vector2 vector2, float y)
+    {
+        vector2.y = y;
+        return vector2;
+    }
+
+    public static float VectorAngle(Vector2 to, Vector2 from)
+    {
+        Vector3 cross = Vector3.Cross(to - from, Vector2.up);
+        float angle = Vector2.Angle(to - from, Vector2.up);
+        return cross.z > 0 ? -angle : angle;
+    }
+
+    public static Vector3 Vector3Parse(this string _input)
+    {
+        if (string.IsNullOrEmpty(_input))
+        {
+            return Vector3.zero;
+        }
+
+        _input = _input.Replace("(", "").Replace(")", "");
+        var stringArray = _input.Split(',');
+
+        float x = 0f;
+        float y = 0f;
+        float z = 0f;
+        if (stringArray.Length > 0)
+        {
+            float.TryParse(stringArray[0], out x);
+        }
+
+        if (stringArray.Length > 1)
+        {
+            float.TryParse(stringArray[1], out y);
+        }
+
+        if (stringArray.Length > 2)
+        {
+            float.TryParse(stringArray[2], out z);
+        }
+
+        return new Vector3(x, y, z);
+    }
+
+}
diff --git a/Utility/VectorUtility.cs.meta b/Utility/VectorUtility.cs.meta
new file mode 100644
index 0000000..3c358cd
--- /dev/null
+++ b/Utility/VectorUtility.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: d3930b2a9f9e67848948af19b2ec2be8
+timeCreated: 1500642389
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Utility/VesselExtension.cs b/Utility/VesselExtension.cs
new file mode 100644
index 0000000..a98b3f9
--- /dev/null
+++ b/Utility/VesselExtension.cs
@@ -0,0 +1,105 @@
+锘縰sing System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System;
+
+public static class VesselExtension
+{
+
+    public static bool IsNullOrEmpty<T>(this List<T> vessel)
+    {
+        return vessel == null || vessel.Count == 0;
+    }
+
+    public static bool IsNullOrEmpty<T>(this T[] vessel)
+    {
+        return vessel == null || vessel.Length == 0;
+    }
+
+    public static bool IsNullOrEmpty<T0, T1>(this Dictionary<T0, T1> dictionary)
+    {
+        return dictionary == null || dictionary.Count == 0;
+    }
+
+    public static T GetFirst<T>(this List<T> list)
+    {
+        if (list == null)
+        {
+            throw new ArgumentNullException("List is null.");
+        }
+
+        if (list.Count == 0)
+        {
+            Debug.Log("List count can't be zero.");
+            return default(T);
+        }
+
+        return list[0];
+    }
+
+    public static T GetLast<T>(this List<T> list)
+    {
+        if (list == null)
+        {
+            throw new ArgumentNullException("List is null.");
+        }
+
+        if (list.Count == 0)
+        {
+            Debug.Log("List count can't be zero.");
+            return default(T);
+        }
+
+        return list[list.Count - 1];
+    }
+
+    public static T GetFirst<T>(this T[] list)
+    {
+        if (list == null)
+        {
+            throw new ArgumentNullException("Array is null.");
+        }
+
+        if (list.Length == 0)
+        {
+            Debug.Log("Array count can't be zero.");
+            return default(T);
+        }
+
+        return list[0];
+    }
+
+    public static T GetLast<T>(this T[] list)
+    {
+        if (list == null)
+        {
+            throw new ArgumentNullException("Array is null.");
+        }
+
+        if (list.Length == 0)
+        {
+            Debug.Log("Array count can't be zero.");
+            return default(T);
+        }
+
+        return list[list.Length - 1];
+    }
+
+    public static T GetRandom<T>(this List<T> list)
+    {
+        if (list == null)
+        {
+            throw new ArgumentNullException("List is null.");
+        }
+
+        if (list.Count == 0)
+        {
+            Debug.Log("List count can't be zero.");
+            return default(T);
+        }
+
+        var randomIndex = UnityEngine.Random.Range(0, list.Count);
+        return list[randomIndex];
+    }
+
+}
diff --git a/Utility/VesselExtension.cs.meta b/Utility/VesselExtension.cs.meta
new file mode 100644
index 0000000..aae8406
--- /dev/null
+++ b/Utility/VesselExtension.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 010f49a2fd5e80549a0a31cc591d480b
+timeCreated: 1551410370
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

--
Gitblit v1.8.0