From f43e38880a7255d07cccfc313146c3f397fcf505 Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期三, 07 五月 2025 09:34:27 +0800
Subject: [PATCH] UI配置等
---
Main/Config/ConfigBase.cs.meta | 11
Main/Manager/ManagerBase.cs | 13
Main/Character/Motion.meta | 8
Main/UI/Login.meta | 8
Main/Place/PlaceUnit.cs | 516 ++++++++
Main/UI/UIBase.cs | 175 +-
Main/Config/ConfigParse.cs.meta | 11
Main/UI/Login/LoginWin.cs | 62 +
Main/Manager/IManager.cs | 7
Main/Manager/LoginManager.cs.meta | 11
Main/Character/Motion/MotionBase.cs | 58 +
Main/Character/Motion/MotionBase.cs.meta | 11
Main/UI/Main.meta | 8
Main/Manager/IManager.cs.meta | 11
Main/Character/CharacterBase.cs | 9
Main/Config/ConfigBase.cs | 141 ++
Main/Manager/GameSystemManager.meta | 8
Main/UI/Place/PlaceWin.cs.meta | 11
Main/Manager/GameSystemManager/PlaceManager.cs.meta | 11
Main/UI/Place.meta | 8
Main/Manager/ConfigManager.cs | 84 +
Main/UI/Place/PlaceWin.cs | 62 +
Main/Place/PlaceDrop.cs | 143 ++
Main/Manager/ManagerBase.cs.meta | 11
Main/Place/PlaceDataStructs.cs.meta | 11
Main/Character.meta | 8
Main/Manager.meta | 8
Main/Battle.meta | 8
Main/UI/Login/LoginWin.cs.meta | 11
Main/Place/PlaceUnit.cs.meta | 11
Main/UI/LoadingWin.cs | 73 +
Main/UI/Main/MainWin.cs | 206 +++
Main/UI/UIManager.cs | 80
Main/UI/LoadingWin.cs.meta | 11
Main/Place/PlaceField.cs.meta | 11
Main/Manager/GameSystemManager/BattleManager.cs | 14
Main/Place/PlaceDrop.cs.meta | 11
Main/Main.cs | 103 +
Main/UI/Main/MainWin.cs.meta | 11
Main/Character/CharacterBase.cs.meta | 11
Main/Place/PlaceField.cs | 406 +++++++
Main/Config/ConfigParse.cs | 305 +++++
Main/Manager/LoginManager.cs | 16
Main/Config/Configs.meta | 8
Main/Manager/StageManager.cs | 119 ++
Main/Main.asmdef | 7
Main/Manager/ConfigManager.cs.meta | 11
Main/Manager/GameSystemManager/BattleManager.cs.meta | 11
Utility/DontDestroyOnLoad.cs.meta | 11
Utility/DontDestroyOnLoad.cs | 11
Main/Manager/GameSystemManager.cs.meta | 11
Main/Manager/GameSystemManager/PlaceManager.cs | 21
Main/Manager/GameSystemManager/TeamManager.cs.meta | 11
Main/Manager/GameSystemManager.cs | 33
Main/Manager/StageManager.cs.meta | 11
Main/Place.meta | 8
Main/Manager/GameSystemManager/TeamManager.cs | 400 ++++++
Main/Place/PlaceDataStructs.cs | 83 +
Main/Config.meta | 8
59 files changed, 3,301 insertions(+), 176 deletions(-)
diff --git a/Main/Battle.meta b/Main/Battle.meta
new file mode 100644
index 0000000..14bf21e
--- /dev/null
+++ b/Main/Battle.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: f97380ec7fe308f4fb5bb6658c9b2604
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Character.meta b/Main/Character.meta
new file mode 100644
index 0000000..f91e1b0
--- /dev/null
+++ b/Main/Character.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 236e2b98d9a024546a3d5b0ee59c257e
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Character/CharacterBase.cs b/Main/Character/CharacterBase.cs
new file mode 100644
index 0000000..e86b197
--- /dev/null
+++ b/Main/Character/CharacterBase.cs
@@ -0,0 +1,9 @@
+
+
+public class CharacterBase
+{
+
+
+
+
+}
\ No newline at end of file
diff --git a/Main/Character/CharacterBase.cs.meta b/Main/Character/CharacterBase.cs.meta
new file mode 100644
index 0000000..21f5255
--- /dev/null
+++ b/Main/Character/CharacterBase.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 446cfdee2e270e2459fa4dbb2c33b152
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Character/Motion.meta b/Main/Character/Motion.meta
new file mode 100644
index 0000000..8ab6d6e
--- /dev/null
+++ b/Main/Character/Motion.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 613ebae9f200e9d43b75a053fd050971
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Character/Motion/MotionBase.cs b/Main/Character/Motion/MotionBase.cs
new file mode 100644
index 0000000..bdf26d3
--- /dev/null
+++ b/Main/Character/Motion/MotionBase.cs
@@ -0,0 +1,58 @@
+using Spine.Unity;
+using Spine;
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+
+// 鍔ㄤ綔鎺у埗
+public class MotionBase
+{
+ protected SkeletonAnimation skeletonAnimation;
+
+ public virtual void Init(SkeletonAnimation _skeletonAnimation)
+ {
+ skeletonAnimation = _skeletonAnimation;
+ }
+
+ public virtual void Play(string _motionName, bool _isLoop = false)
+ {
+ skeletonAnimation.AnimationState.SetAnimation(0, _motionName, _isLoop);
+ }
+
+ public virtual void Pause()
+ {
+ skeletonAnimation.AnimationState.TimeScale = 0;
+ }
+
+ public virtual void Resume()
+ {
+ skeletonAnimation.AnimationState.TimeScale = 1;
+ }
+
+ public virtual void MixBlend(string _motionName, float _duration)
+ {
+ // 鑾峰彇褰撳墠杞ㄩ亾涓婄殑鍔ㄧ敾
+ TrackEntry currentTrack = skeletonAnimation.AnimationState.GetCurrent(0);
+
+ if (currentTrack != null)
+ {
+ // 娣诲姞涓�涓柊鐨勫姩鐢诲埌杞ㄩ亾0锛屽苟璁剧疆娣峰悎鏃堕棿
+ TrackEntry newTrack = skeletonAnimation.AnimationState.SetAnimation(0, _motionName, true);
+
+ // 璁剧疆娣峰悎鎸佺画鏃堕棿
+ newTrack.MixDuration = _duration;
+
+ // 鍙�夛細璁剧疆娣峰悎绫诲瀷
+ // newTrack.MixBlend = MixBlend.Replace; // 榛樿鍊�
+
+ // 鍙�夛細濡傛灉闇�瑕佸湪娣峰悎瀹屾垚鍚庢墽琛屾煇浜涙搷浣�
+ // newTrack.Complete += OnMixComplete;
+ }
+ else
+ {
+ // 濡傛灉褰撳墠娌℃湁鍔ㄧ敾鍦ㄦ挱鏀撅紝鐩存帴鎾斁鏂板姩鐢�
+ skeletonAnimation.AnimationState.SetAnimation(0, _motionName, true);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Main/Character/Motion/MotionBase.cs.meta b/Main/Character/Motion/MotionBase.cs.meta
new file mode 100644
index 0000000..7979b1c
--- /dev/null
+++ b/Main/Character/Motion/MotionBase.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7d0ffbc3831c9564481db79412785ff9
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Config.meta b/Main/Config.meta
new file mode 100644
index 0000000..ba72ecf
--- /dev/null
+++ b/Main/Config.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: da9ffef894f7c304c8f0de2f85657112
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Config/ConfigBase.cs b/Main/Config/ConfigBase.cs
new file mode 100644
index 0000000..3e371da
--- /dev/null
+++ b/Main/Config/ConfigBase.cs
@@ -0,0 +1,141 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+
+public class ConfigBase<U, T> where T : ConfigBase<U, T>, new()
+{
+ public static Dictionary<U, T> dic = new Dictionary<U, T>();
+
+ protected static bool isInit = false;
+
+ public static T Get(U id)
+ {
+ if (!isInit)
+ {
+ Debug.LogError("ConfigBase 娌℃湁鍒濆鍖�");
+ return null; // 鎴栬�呮姏鍑哄紓甯革紝瑙嗘儏鍐佃�屽畾
+ }
+
+ if (dic.ContainsKey(id))
+ {
+ return dic[id];
+ }
+
+ return null;
+ }
+
+ public List<T> GetValues()
+ {
+ if (!isInit)
+ {
+ Debug.LogError(typeof(T).Name + " 娌℃湁鍒濆鍖� GetValues");
+ return null; // 鎴栬�呮姏鍑哄紓甯革紝瑙嗘儏鍐佃�屽畾
+ }
+ List<T> result = new List<T>();
+ result.AddRange(dic.Values);
+ return result;
+ }
+
+ public static bool HasKey(U key)
+ {
+ if (!isInit)
+ {
+ Debug.LogError(typeof(T).Name + " 娌℃湁鍒濆鍖� HasKey");
+ return false; // 鎴栬�呮姏鍑哄紓甯革紝瑙嗘儏鍐佃�屽畾
+ }
+
+ return dic.ContainsKey(key);
+ }
+
+ public static void Init(string[] lines)
+ {
+ Dictionary<string, string> rawDatas = new Dictionary<string, string>();
+
+ for (int i = 3; i < lines.Length; i++)
+ {
+ string line = lines[i];
+ var index = line.IndexOf("\t");
+ if (index == -1)
+ {
+ continue;
+ }
+
+ string strKey = line.Substring(0, index);
+ T config = new T();
+ U key = config.LoadKey(strKey);
+ config.LoadConfig(line);
+ dic.Add(key, config);
+ }
+
+ isInit = true;
+ }
+
+ public virtual U LoadKey(string line)
+ {
+ return default(U);
+ }
+
+ public virtual void LoadConfig(string line)
+ {
+
+ }
+
+ protected int ParseInt(string str)
+ {
+ int result = 0;
+ int.TryParse(str, out result);
+ return result;
+ }
+
+ protected float ParseFloat(string str)
+ {
+ float result = 0f;
+ float.TryParse(str, out result);
+ return result;
+ }
+
+ protected string[] Split(string str, char split)
+ {
+ return str.Split(split);
+ }
+
+ protected List<string> ParseStrList(string str, char split)
+ {
+ List<string> result = new List<string>();
+ string[] strs = Split(str, split);
+ for (int i = 0; i < strs.Length; i++)
+ {
+ result.Add(strs[i]);
+ }
+
+ return result;
+ }
+
+ protected List<int> ParseIntList(string str, char split)
+ {
+ List<int> result = new List<int>();
+ string[] strs = Split(str, split);
+ for (int i = 0; i < strs.Length; i++)
+ {
+ result.Add(ParseInt(strs[i]));
+ }
+ return result;
+ }
+
+ protected U GetKey(string key)
+ {
+ if (typeof(U) == typeof(string))
+ {
+ return (U)(object)key;
+ }
+ else if (typeof(U) == typeof(int))
+ {
+ return (U)(object)ParseInt(key);
+ }
+ else
+ {
+ Debug.LogError("GetKey 绫诲瀷閿欒");
+ return default(U);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Main/Config/ConfigBase.cs.meta b/Main/Config/ConfigBase.cs.meta
new file mode 100644
index 0000000..6e3b278
--- /dev/null
+++ b/Main/Config/ConfigBase.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: beeab167082007f42b3eedbb8a3c19e8
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Config/ConfigParse.cs b/Main/Config/ConfigParse.cs
new file mode 100644
index 0000000..4ad01b1
--- /dev/null
+++ b/Main/Config/ConfigParse.cs
@@ -0,0 +1,305 @@
+锘縰sing LitJson;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using UnityEngine;
+
+public class ConfigParse
+{
+ public enum SegStrType
+ {
+ Multiple,
+ KeyValue,
+ }
+
+ public static T? GetSegValue<T>(string msg, string key, SegStrType type) where T : struct
+ {
+ T? result = null;
+ switch (type)
+ {
+ case SegStrType.Multiple:
+ {
+ uint index = 0;
+ uint.TryParse(key, out index);
+ result = (T)Convert.ChangeType(GetMultipleStr(msg, index), typeof(T));
+ }
+ break;
+ case SegStrType.KeyValue:
+ {
+ result = (T)Convert.ChangeType(GetKeyValue(msg, key), typeof(T));
+ }
+ break;
+ }
+ return result;
+ }
+
+ public static string GetSegValue(string msg, string key, SegStrType type)
+ {
+ switch (type)
+ {
+ case SegStrType.Multiple:
+ {
+ uint index = 0;
+ uint.TryParse(key, out index);
+ return GetMultipleStr(msg, index);
+ }
+ case SegStrType.KeyValue:
+ {
+ return GetKeyValue(msg, key);
+ }
+ }
+ return string.Empty;
+ }
+
+ private static string GetMultipleStr(string msg, uint index)
+ {
+ string[] segs = GetMultipleStr(msg);
+ if (segs != null && index < segs.Length)
+ {
+ return segs[index];
+ }
+ return string.Empty;
+ }
+
+ public static T[] GetMultipleStr<T>(string msg) where T : struct
+ {
+ string[] segs = GetMultipleStr(msg);
+ if (segs != null && segs.Length > 0)
+ {
+ T[] array = new T[segs.Length];
+ for (int i = 0; i < segs.Length; i++)
+ {
+ array[i] = (T)Convert.ChangeType(segs[i], typeof(T));
+ }
+ return array;
+ }
+ return null;
+ }
+
+ public static string[] GetMultipleStr(string msg)
+ {
+ string[] segs = msg.Split('|');
+ if (segs.Length == 1 && segs[0].Equals(string.Empty)) return null;
+ return segs;
+ }
+
+ private static string GetKeyValue(string msg, string key)
+ {
+ string[] segs = GetMultipleStr(msg);
+ for (int i = 0; i < segs.Length; i++)
+ {
+ string[] pair = GetKeyValue(segs[i]);
+ if (pair.Length > 1)
+ {
+ if (!pair[0].Equals(key)) continue;
+ else return pair[1];
+ }
+ else continue;
+ }
+ return string.Empty;
+ }
+
+ private static string[] GetKeyValue(string msg)
+ {
+ return msg.Split('_');
+ }
+
+ public static T[] GetKeyValueKeys<T>(string msg) where T : struct
+ {
+ string[] segs = GetMultipleStr(msg);
+ if (segs != null && segs.Length > 0)
+ {
+ T[] array = new T[segs.Length];
+ for (int i = 0; i < segs.Length; i++)
+ {
+ string[] pair = GetKeyValue(segs[i]);
+ if (pair.Length > 1)
+ {
+ array[i] = (T)Convert.ChangeType(pair[0], typeof(T));
+ }
+ }
+ return array;
+ }
+ return null;
+ }
+
+ public static T[] GetKeyValueValues<T>(string msg) where T : struct
+ {
+ string[] segs = GetMultipleStr(msg);
+ if (segs != null && segs.Length > 0)
+ {
+ T[] array = new T[segs.Length];
+ for (int i = 0; i < segs.Length; i++)
+ {
+ string[] pair = GetKeyValue(segs[i]);
+ if (pair.Length > 1)
+ {
+ array[i] = (T)Convert.ChangeType(pair[1], typeof(T));
+ }
+ }
+ return array;
+ }
+ return null;
+ }
+
+ public static Dictionary<T, P> GetDic<T, P>(string msg)
+ {
+ Dictionary<T, P> dic = null;
+ string[] segs = GetMultipleStr(msg);
+ if (segs != null && segs.Length > 0)
+ {
+ dic = new Dictionary<T, P>();
+ for (int i = 0; i < segs.Length; i++)
+ {
+ string[] pair = GetKeyValue(segs[i]);
+ if (pair.Length > 1)
+ {
+ dic.Add((T)Convert.ChangeType(pair[0], typeof(T)), (P)Convert.ChangeType(pair[1], typeof(P)));
+ }
+ }
+ }
+ return dic;
+ }
+
+ public static string ServerStringTrim(string str)
+ {
+ if (!string.IsNullOrEmpty(str))
+ {
+ str = str.Replace("\0", "");
+ str = str.Replace("\x00", "");
+ return str;
+ }
+ else
+ {
+ return string.Empty;
+ }
+ }
+
+ //{'17':['63','6','27'],'65':['800'],'55':['139'],'19':['1000','2600','130']}
+ public static Regex userDataRegex = new Regex(@"'([0-9]+)':\[(.*?)\]", RegexOptions.Singleline);
+ public static Dictionary<int, List<int>> Analysis(string val)//姝e垯琛ㄨ揪寮忕殑瀛楃涓插垎鍓�
+ {
+ string s = ServerStringTrim(val);
+ if (string.IsNullOrEmpty(s))
+ {
+ return null;
+ }
+
+ s = s.Replace(" ", string.Empty);
+ if (!userDataRegex.IsMatch(s))
+ {
+ return null;
+ }
+ else
+ {
+ Dictionary<int, List<int>> dics = new Dictionary<int, List<int>>();
+ foreach (Match match in userDataRegex.Matches(s))
+ {
+ int id = int.Parse(match.Groups[1].Value);
+ string str = match.Groups[2].Value;
+ string[] vals = str.Split(',');
+ List<int> list = new List<int>();
+ for (int i = 0; i < vals.Length; i++)
+ {
+ int intval = int.Parse(vals[i].Replace('\'', ' '));
+ list.Add(intval);
+ }
+ if (!dics.ContainsKey(id))
+ {
+ dics.Add(id, list);
+ }
+ }
+ return dics;
+ }
+ }
+
+ public static Dictionary<int, List<int>> ParseJsonDict(string jsonStr)
+ {
+ if (jsonStr == "{}" || string.IsNullOrEmpty(jsonStr))
+ {
+ return new Dictionary<int, List<int>>();
+ }
+ var dict = JsonMapper.ToObject<Dictionary<string, List<int>>>(jsonStr);
+ Dictionary<int, List<int>> result = new Dictionary<int, List<int>>();
+
+ foreach (var item in dict)
+ {
+ result[int.Parse(item.Key)] = item.Value;
+ }
+
+ return result;
+ }
+
+ public static Dictionary<int, int> ParseIntDict(string jsonStr)
+ {
+ if (jsonStr == "{}" || string.IsNullOrEmpty(jsonStr))
+ {
+ return new Dictionary<int, int>();
+ }
+ var dict = JsonMapper.ToObject<Dictionary<string, int>>(jsonStr);
+ Dictionary<int, int> result = new Dictionary<int, int>();
+
+ foreach (var item in dict)
+ {
+ result[int.Parse(item.Key)] = item.Value;
+ }
+
+ return result;
+ }
+
+ public static Dictionary<int, int[]> ParseIntArrayDict(string jsonStr)
+ {
+ if (jsonStr == "{}" || string.IsNullOrEmpty(jsonStr))
+ {
+ return new Dictionary<int, int[]>();
+ }
+ var dict = JsonMapper.ToObject<Dictionary<string, int[]>>(jsonStr);
+ Dictionary<int, int[]> result = new Dictionary<int, int[]>();
+
+ foreach (var item in dict)
+ {
+ result[int.Parse(item.Key)] = item.Value;
+ }
+
+ return result;
+ }
+
+ public static Dictionary<int, int[][]> ParseIntArray2Dict(string jsonStr)
+ {
+ if (jsonStr == "{}" || string.IsNullOrEmpty(jsonStr))
+ {
+ return new Dictionary<int, int[][]>();
+ }
+ var dict = JsonMapper.ToObject<Dictionary<string, int[][]>>(jsonStr);
+ Dictionary<int, int[][]> result = new Dictionary<int, int[][]>();
+
+ foreach (var item in dict)
+ {
+ result[int.Parse(item.Key)] = item.Value;
+ }
+
+ return result;
+ }
+
+
+ //涓囧垎鐜囪浆涓烘瘡涓猧d瀵瑰簲鐨勬鐜� [[涓囧垎姒傜巼锛宨d1],[涓囧垎姒傜巼锛宨d2]]
+ public static Dictionary<int, int> GetRateDict(int[][] rateArray)
+ {
+ Dictionary<int, int> dic = new Dictionary<int, int>();
+ //姒傜巼涓� 鍑忓幓涓婁竴涓鐜囩殑鍊煎嵆涓哄綋鍓岻D姒傜巼
+ for (int i = 0;i< rateArray.Length; i++)
+ {
+ if (i > 0)
+ {
+ dic[rateArray[i][1]] = rateArray[i][0] - rateArray[i - 1][0];
+ }
+ else
+ {
+ dic[rateArray[i][1]] = rateArray[i][0];
+ }
+ }
+
+ return dic;
+ }
+}
diff --git a/Main/Config/ConfigParse.cs.meta b/Main/Config/ConfigParse.cs.meta
new file mode 100644
index 0000000..17a769b
--- /dev/null
+++ b/Main/Config/ConfigParse.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6f9144568a1b6674da727f6a1a88aed9
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Config/Configs.meta b/Main/Config/Configs.meta
new file mode 100644
index 0000000..4e5884e
--- /dev/null
+++ b/Main/Config/Configs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 776d1c99148d30f4799a606e5cd0f5de
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Main.asmdef b/Main/Main.asmdef
index bc3c97a..a5d805b 100644
--- a/Main/Main.asmdef
+++ b/Main/Main.asmdef
@@ -4,7 +4,12 @@
"references": [
"GUID:3ffa07c58a98b0445a7a34376b165fd1",
"GUID:4129704b5a1a13841ba16f230bf24a57",
- "GUID:f51ebe6a0ceec4240a699833d6309b23"
+ "GUID:f51ebe6a0ceec4240a699833d6309b23",
+ "GUID:e34a5702dd353724aa315fb8011f08c3",
+ "GUID:4d1926c9df5b052469a1c63448b7609a",
+ "GUID:68765d262e2128e4ab49c983f3411946",
+ "GUID:173464ddf4cdb6640a4dfa8a9281ad69",
+ "GUID:72d1fea872bd7a449bf3818f2b0a6708"
],
"includePlatforms": [],
"excludePlatforms": [],
diff --git a/Main/Main.cs b/Main/Main.cs
index 981ab79..15d0d7e 100644
--- a/Main/Main.cs
+++ b/Main/Main.cs
@@ -4,49 +4,81 @@
using UnityEngine;
using Cysharp.Threading;
using Cysharp.Threading.Tasks;
+using System.Threading.Tasks;
/// <summary>
/// Main绫伙紝浣滀负鐑洿鏂扮▼搴忛泦鐨勫叆鍙g偣
/// </summary>
public class Main
{
+ public static List<IGameSystemManager> managers = new List<IGameSystemManager>();
+
/// <summary>
/// 鍒濆鍖栧嚱鏁帮紝鐢盠aunch绫昏皟鐢�
/// </summary>
- public static void Init()
+ public static async UniTask Init()
{
Debug.Log("Main.Init() 琚皟鐢�");
- // 1. 鍒濆鍖栨父鎴忕郴缁�
- InitializeGameSystems();
-
- // 2. 鍔犺浇閰嶇疆
- LoadConfigurations();
-
- // 3. 鎵撳紑鐧诲綍鐣岄潰
- OpenLoginUI();
+ await InitSystems();
+
+ Debug.Log("鍏抽棴鍔犺浇鐣岄潰");
+ LaunchLoadingWin.Instance.CloseWindow();
+
+ SwitchToLoginScene();
}
-
-
+
/// <summary>
/// 鍒濆鍖栨父鎴忕郴缁�
/// </summary>
- private static void InitializeGameSystems()
+ private static async UniTask InitSystems()
{
- Debug.Log("鍒濆鍖栨父鎴忕郴缁�");
-
- // 杩欓噷鍙互鍒濆鍖栧悇绉嶆父鎴忕郴缁燂紝濡傝祫婧愮鐞嗐�乁I绠$悊銆侀煶棰戠鐞嗙瓑
-
+ // 杩欓噷鍙互鍒濆鍖栧ぇ鍨嬬郴缁� 璐┛鏁翠釜娓告垙鐨勭郴缁�
+ await ResManager.Instance.Init();
+ UIManager.Instance.Init();
+ StageManager.Instance.Init();
+ LoginManager.Instance.Init();
+
}
-
- /// <summary>
- /// 鍔犺浇閰嶇疆
- /// </summary>
- private static void LoadConfigurations()
+
+ private static void SwitchToLoginScene()
{
- Debug.Log("鍔犺浇娓告垙閰嶇疆");
-
- // 杩欓噷鍙互鍔犺浇娓告垙閰嶇疆锛屽娓告垙鍙傛暟銆佽〃鏍兼暟鎹瓑
-
+ // Debug.Log("鎵撳紑鐧诲綍鐣岄潰");
+ // UIManager.Instance.OpenWindow<LoginWin>();
+ Debug.Log("鍒囨崲鍒扮櫥褰曞満鏅�");
+ ConfigManager.Instance.Init();
+ StageManager.Instance.ToLoginScene();
+ }
+
+ public static void OnEnterGameScene()
+ {
+ // 鍒濆鍖栨父鎴忓満鏅�
+ Debug.Log("鍒濆鍖栨父鎴忓満鏅�");
+
+ // 鍒濆鍖栨父鎴忕郴缁�
+ managers.Add(PlaceManager.Instance);
+ managers.Add(BattleManager.Instance);
+ managers.Add(TeamManager.Instance);
+
+ foreach (var manager in managers)
+ {
+ manager.Init();
+ }
+
+ foreach (var manager in managers)
+ {
+ manager.RequestNessaryData();
+ }
+
+ }
+
+ public static void OnSwitchToLoginScene()
+ {
+ foreach (var manager in managers)
+ {
+ manager.Release();
+ }
+
+ managers.Clear();
}
/// <summary>
@@ -54,27 +86,8 @@
/// </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/Manager.meta b/Main/Manager.meta
new file mode 100644
index 0000000..b55776f
--- /dev/null
+++ b/Main/Manager.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: d17f7001c7a25da4b8f7c0051a479e37
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Manager/ConfigManager.cs b/Main/Manager/ConfigManager.cs
new file mode 100644
index 0000000..4af4662
--- /dev/null
+++ b/Main/Manager/ConfigManager.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using Cysharp.Threading.Tasks;
+using System.Reflection;
+
+
+public class ConfigManager : ManagerBase<ConfigManager>
+{
+ public bool isLoadFinished
+ {
+ get;
+ private set;
+ }
+
+ public virtual async UniTask InitConfigs()
+ {
+ // 鍔犺浇閰嶇疆鏂囦欢
+ await LoadConfigs();
+ }
+
+ protected async UniTask LoadConfigs()
+ {
+ isLoadFinished = false;
+
+ // 鍔犺浇閰嶇疆鏂囦欢
+
+ // 鍔犺浇瀹屾垚鍚庤缃甶sLoadFinished涓簍rue
+ isLoadFinished = true;
+ }
+
+
+
+
+
+ private async UniTask LoadConfig<T>() where T : class
+ {
+ string configName = typeof(T).Name;
+
+ TextAsset textAsset = await ResManager.Instance.LoadAsset<TextAsset>("Config", configName);
+ if (textAsset != null)
+ {
+ string[] lines = textAsset.text.Split('\n');
+ var methodInfo = typeof(T).GetMethod("Init", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
+ if (methodInfo != null)
+ {
+ methodInfo.Invoke(null, new object[] { lines });
+ // 璁剧疆鍒濆鍖栨爣蹇�
+ var isInitField = typeof(T).GetField("isInit", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
+ if (isInitField != null)
+ {
+ isInitField.SetValue(null, true);
+ }
+ Debug.Log($"鍔犺浇閰嶇疆: {typeof(T).Name} 鎴愬姛");
+ }
+ else
+ {
+ Debug.LogError($"閰嶇疆绫� {typeof(T).Name} 娌℃湁闈欐�両nit鏂规硶");
+ }
+ }
+ else
+ {
+ Debug.LogError($"鎵句笉鍒伴厤缃枃浠�: {configName}");
+ }
+ }
+
+ private void ClearConfigDictionary<T>() where T : class
+ {
+ // 閲嶇疆 T 鍒濆鍖栫姸鎬�
+ var isInitField = typeof(T).GetField("isInit", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
+ if (isInitField != null)
+ {
+ isInitField.SetValue(null, false);
+ }
+ }
+
+ public override void Release()
+ {
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/Main/Manager/ConfigManager.cs.meta b/Main/Manager/ConfigManager.cs.meta
new file mode 100644
index 0000000..38522f1
--- /dev/null
+++ b/Main/Manager/ConfigManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 899d505772a98b44ba61e2e0d0a00072
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Manager/GameSystemManager.cs b/Main/Manager/GameSystemManager.cs
new file mode 100644
index 0000000..fc2bc39
--- /dev/null
+++ b/Main/Manager/GameSystemManager.cs
@@ -0,0 +1,33 @@
+// 娓告垙绯荤粺鐨勭鐞嗗熀绫�
+
+// 娣诲姞涓�涓潪娉涘瀷鐨勫熀绫绘垨鎺ュ彛
+public interface IGameSystemManager
+{
+ public void Init();
+ public void Release();
+ public void RequestNessaryData();
+ public bool IsNessaryDataReady();
+}
+
+// 璁╂硾鍨嬬被缁ф壙鑷潪娉涘瀷鍩虹被
+public class GameSystemManager<T> : Singleton<T>, IGameSystemManager where T : GameSystemManager<T>, new()
+{
+ public virtual void Init()
+ {
+ }
+
+ public virtual void Release()
+ {
+
+ }
+
+ public virtual void RequestNessaryData()
+ {
+
+ }
+
+ public virtual bool IsNessaryDataReady()
+ {
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Main/Manager/GameSystemManager.cs.meta b/Main/Manager/GameSystemManager.cs.meta
new file mode 100644
index 0000000..0c35ad1
--- /dev/null
+++ b/Main/Manager/GameSystemManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 05ef44209a69865458086694ce7d6f67
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Manager/GameSystemManager.meta b/Main/Manager/GameSystemManager.meta
new file mode 100644
index 0000000..c3d55d3
--- /dev/null
+++ b/Main/Manager/GameSystemManager.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 7b0931f43ab92084b8a1e5faa7fbfda2
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Manager/GameSystemManager/BattleManager.cs b/Main/Manager/GameSystemManager/BattleManager.cs
new file mode 100644
index 0000000..a52f3c3
--- /dev/null
+++ b/Main/Manager/GameSystemManager/BattleManager.cs
@@ -0,0 +1,14 @@
+public class BattleManager : GameSystemManager<BattleManager>
+{
+ public override void Init()
+ {
+ base.Init();
+
+ }
+
+ public override void Release()
+ {
+ base.Release();
+ }
+
+}
\ No newline at end of file
diff --git a/Main/Manager/GameSystemManager/BattleManager.cs.meta b/Main/Manager/GameSystemManager/BattleManager.cs.meta
new file mode 100644
index 0000000..9cbbbb1
--- /dev/null
+++ b/Main/Manager/GameSystemManager/BattleManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e2eea1200b9fe6644a6907b4e042f222
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Manager/GameSystemManager/PlaceManager.cs b/Main/Manager/GameSystemManager/PlaceManager.cs
new file mode 100644
index 0000000..2573e84
--- /dev/null
+++ b/Main/Manager/GameSystemManager/PlaceManager.cs
@@ -0,0 +1,21 @@
+public class PlaceManager : GameSystemManager<PlaceManager>
+{
+ public PlaceField placeField;
+
+ public override void Init()
+ {
+ base.Init();
+
+ }
+
+ public override void Release()
+ {
+ base.Release();
+ }
+
+ // 褰撻槦浼嶈窡绔犺妭淇℃伅鏁版嵁閮芥湁涔嬪悗灏卞彲浠ュ垱寤哄満鏅簡
+ public void CreatePlaceField()
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Main/Manager/GameSystemManager/PlaceManager.cs.meta b/Main/Manager/GameSystemManager/PlaceManager.cs.meta
new file mode 100644
index 0000000..6c82cce
--- /dev/null
+++ b/Main/Manager/GameSystemManager/PlaceManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: dc73049956fa1a241a3aeac4d7fdd7af
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Manager/GameSystemManager/TeamManager.cs b/Main/Manager/GameSystemManager/TeamManager.cs
new file mode 100644
index 0000000..128ccf9
--- /dev/null
+++ b/Main/Manager/GameSystemManager/TeamManager.cs
@@ -0,0 +1,400 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+/// <summary>
+/// 闃靛瀷绫诲瀷
+/// </summary>
+public enum FormationType
+{
+ None = 0,
+ Type1 = 1,
+ Type2 = 2,
+ Type3 = 3,
+ Type4 = 4,
+ Type5 = 5
+}
+
+/// <summary>
+/// 鍗$墝淇℃伅
+/// </summary>
+[Serializable]
+public class CardInfo
+{
+ public int cardId; // 鍗$墝ID
+ public int level; // 鍗$墝绛夌骇
+ public int star; // 鍗$墝鏄熺骇
+ public int quality; // 鍗$墝鍝佽川
+
+ // 鍏朵粬鍗$墝灞炴��...
+
+ public CardInfo()
+ {
+ cardId = 0;
+ level = 1;
+ star = 1;
+ quality = 1;
+ }
+
+ public CardInfo(int _cardId, int _level = 1, int _star = 1, int _quality = 1)
+ {
+ cardId = _cardId;
+ level = _level;
+ star = _star;
+ quality = _quality;
+ }
+}
+
+/// <summary>
+/// 闃熶紞鍗$墝淇℃伅
+/// </summary>
+[Serializable]
+public class SlotInfo
+{
+ public CardInfo cardInfo; // 鍗$墝淇℃伅
+ public int teamIndex; // 鍦ㄩ槦浼嶄腑鐨勭储寮曚綅缃�
+
+ public SlotInfo()
+ {
+ cardInfo = new CardInfo();
+ teamIndex = -1;
+ }
+
+ public SlotInfo(CardInfo _card, int _teamIndex)
+ {
+ cardInfo = _card;
+ teamIndex = _teamIndex;
+ }
+
+ public bool IsEmptySlot()
+ {
+ return cardInfo == null || cardInfo.cardId == 0;
+ }
+}
+
+/// <summary>
+/// 闃熶紞淇℃伅
+/// </summary>
+[Serializable]
+public class TeamInfo
+{
+ public int teamId; // 闃熶紞ID
+ public FormationType formation; // 闃靛瀷绫诲瀷
+ public List<SlotInfo> teamCards; // 闃熶紞鍗$墝鍒楄〃
+
+ public TeamInfo()
+ {
+ teamId = 0;
+ formation = FormationType.Type1;
+ teamCards = new List<SlotInfo>();
+ }
+
+ public TeamInfo(int _teamId, string _teamName, FormationType _formation)
+ {
+ teamId = _teamId;
+ formation = _formation;
+ teamCards = new List<SlotInfo>();
+ }
+
+ /// <summary>
+ /// 娣诲姞鍗$墝鍒伴槦浼�
+ /// </summary>
+ public bool AddCard(CardInfo _card, int _teamIndex, bool _isLeader = false)
+ {
+ // 妫�鏌ヤ綅缃槸鍚﹀凡琚崰鐢�
+ foreach (var teamCard in teamCards)
+ {
+ if (teamCard.teamIndex == _teamIndex)
+ {
+ Debug.LogWarning($"闃熶紞浣嶇疆 {_teamIndex} 宸茶鍗犵敤");
+ return false;
+ }
+ }
+
+ SlotInfo newTeamCard = new SlotInfo(_card, _teamIndex);
+ teamCards.Add(newTeamCard);
+ return true;
+ }
+
+ /// <summary>
+ /// 绉婚櫎闃熶紞涓殑鍗$墝
+ /// </summary>
+ public bool RemoveCard(int _teamIndex)
+ {
+ for (int i = 0; i < teamCards.Count; i++)
+ {
+ if (teamCards[i].teamIndex == _teamIndex)
+ {
+ teamCards.RemoveAt(i);
+ return true;
+ }
+ }
+
+ Debug.LogWarning($"鏈壘鍒颁綅缃� {_teamIndex} 鐨勫崱鐗�");
+ return false;
+ }
+
+}
+
+/// <summary>
+/// 闃熶紞绠$悊鍣�
+/// </summary>
+public class TeamManager : GameSystemManager<TeamManager>
+{
+ // 鎵�鏈夐槦浼嶄俊鎭�
+ private List<TeamInfo> teamInfos = new List<TeamInfo>();
+
+ // 褰撳墠閫変腑鐨勯槦浼嶇储寮�
+ private int currentTeamIndex = 0;
+
+ // 鏈�澶ч槦浼嶆暟閲�
+ private const int MAX_TEAM_COUNT = 5;
+
+ // 姣忎釜闃熶紞鐨勬渶澶у崱鐗屾暟閲�
+ private const int MAX_CARD_PER_TEAM = 6;
+
+ public override void Init()
+ {
+ base.Init();
+ Debug.Log("TeamManager 鍒濆鍖�");
+
+ // 鍒濆鍖栭粯璁ら槦浼�
+ if (teamInfos.Count == 0)
+ {
+ CreateDefaultTeam();
+ }
+ }
+
+ public override void Release()
+ {
+ base.Release();
+ Debug.Log("TeamManager 閲婃斁");
+
+ // 娓呯悊鏁版嵁
+ teamInfos.Clear();
+ }
+
+ /// <summary>
+ /// 鍒涘缓榛樿闃熶紞
+ /// </summary>
+ private void CreateDefaultTeam()
+ {
+ TeamInfo defaultTeam = new TeamInfo(1, "闃熶紞1", FormationType.Type1);
+ teamInfos.Add(defaultTeam);
+ }
+
+ /// <summary>
+ /// 鑾峰彇鎵�鏈夐槦浼嶄俊鎭�
+ /// </summary>
+ public List<TeamInfo> GetAllTeams()
+ {
+ return teamInfos;
+ }
+
+ /// <summary>
+ /// 鑾峰彇鎸囧畾ID鐨勯槦浼�
+ /// </summary>
+ public TeamInfo GetTeam(int _teamId)
+ {
+ return teamInfos.Find(team => team.teamId == _teamId);
+ }
+
+ /// <summary>
+ /// 鑾峰彇褰撳墠閫変腑鐨勯槦浼�
+ /// </summary>
+ public TeamInfo GetCurrentTeam()
+ {
+ if (currentTeamIndex >= 0 && currentTeamIndex < teamInfos.Count)
+ {
+ return teamInfos[currentTeamIndex];
+ }
+ return null;
+ }
+
+ /// <summary>
+ /// 璁剧疆褰撳墠閫変腑鐨勯槦浼�
+ /// </summary>
+ public bool SetCurrentTeam(int _teamId)
+ {
+ for (int i = 0; i < teamInfos.Count; i++)
+ {
+ if (teamInfos[i].teamId == _teamId)
+ {
+ currentTeamIndex = i;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// 鍒涘缓鏂伴槦浼�
+ /// </summary>
+ public TeamInfo CreateTeam(string _teamName, FormationType _formation)
+ {
+ if (teamInfos.Count >= MAX_TEAM_COUNT)
+ {
+ Debug.LogWarning("宸茶揪鍒版渶澶ч槦浼嶆暟閲忛檺鍒�");
+ return null;
+ }
+
+ // 鐢熸垚鏂扮殑闃熶紞ID
+ int newTeamId = 1;
+ if (teamInfos.Count > 0)
+ {
+ newTeamId = teamInfos[teamInfos.Count - 1].teamId + 1;
+ }
+
+ TeamInfo newTeam = new TeamInfo(newTeamId, _teamName, _formation);
+ teamInfos.Add(newTeam);
+
+ return newTeam;
+ }
+
+ /// <summary>
+ /// 鍒犻櫎闃熶紞
+ /// </summary>
+ public bool DeleteTeam(int _teamId)
+ {
+ if (teamInfos.Count <= 1)
+ {
+ Debug.LogWarning("鑷冲皯淇濈暀涓�涓槦浼�");
+ return false;
+ }
+
+ for (int i = 0; i < teamInfos.Count; i++)
+ {
+ if (teamInfos[i].teamId == _teamId)
+ {
+ teamInfos.RemoveAt(i);
+
+ // 濡傛灉鍒犻櫎鐨勬槸褰撳墠閫変腑鐨勯槦浼嶏紝鍒欓噸鏂拌缃綋鍓嶉槦浼�
+ if (currentTeamIndex >= teamInfos.Count)
+ {
+ currentTeamIndex = teamInfos.Count - 1;
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// 淇敼闃熶紞闃靛瀷
+ /// </summary>
+ public bool ChangeFormation(int _teamId, FormationType _newFormation)
+ {
+ TeamInfo team = GetTeam(_teamId);
+ if (team != null)
+ {
+ team.formation = _newFormation;
+ return true;
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// 鍚戦槦浼嶆坊鍔犲崱鐗�
+ /// </summary>
+ public bool AddCardToTeam(int _teamId, CardInfo _card, int _teamIndex, bool _isLeader = false)
+ {
+ TeamInfo team = GetTeam(_teamId);
+ if (team == null)
+ {
+ Debug.LogWarning($"鏈壘鍒癐D涓� {_teamId} 鐨勯槦浼�");
+ return false;
+ }
+
+ if (team.teamCards.Count >= MAX_CARD_PER_TEAM)
+ {
+ Debug.LogWarning("闃熶紞鍗$墝宸茶揪鍒版渶澶ф暟閲�");
+ return false;
+ }
+
+ return team.AddCard(_card, _teamIndex, _isLeader);
+ }
+
+ /// <summary>
+ /// 浠庨槦浼嶇Щ闄ゅ崱鐗�
+ /// </summary>
+ public bool RemoveCardFromTeam(int _teamId, int _teamIndex)
+ {
+ TeamInfo team = GetTeam(_teamId);
+ if (team == null)
+ {
+ Debug.LogWarning($"鏈壘鍒癐D涓� {_teamId} 鐨勯槦浼�");
+ return false;
+ }
+
+ return team.RemoveCard(_teamIndex);
+ }
+
+ /// <summary>
+ /// 浜ゆ崲闃熶紞涓袱寮犲崱鐗岀殑浣嶇疆
+ /// </summary>
+ public bool SwapTeamCards(int _teamId, int _fromIndex, int _toIndex)
+ {
+ TeamInfo team = GetTeam(_teamId);
+ if (team == null)
+ {
+ Debug.LogWarning($"鏈壘鍒癐D涓� {_teamId} 鐨勯槦浼�");
+ return false;
+ }
+
+ SlotInfo fromCard = null;
+ SlotInfo toCard = null;
+
+ foreach (var card in team.teamCards)
+ {
+ if (card.teamIndex == _fromIndex)
+ {
+ fromCard = card;
+ }
+ else if (card.teamIndex == _toIndex)
+ {
+ toCard = card;
+ }
+ }
+
+ if (fromCard == null)
+ {
+ Debug.LogWarning($"鏈壘鍒颁綅缃� {_fromIndex} 鐨勫崱鐗�");
+ return false;
+ }
+
+ if (toCard == null)
+ {
+ // 濡傛灉鐩爣浣嶇疆娌℃湁鍗$墝锛岀洿鎺ョЩ鍔�
+ fromCard.teamIndex = _toIndex;
+ }
+ else
+ {
+ // 浜ゆ崲涓ゅ紶鍗$墝鐨勪綅缃�
+ fromCard.teamIndex = _toIndex;
+ toCard.teamIndex = _fromIndex;
+ }
+
+ return true;
+ }
+
+ /// <summary>
+ /// 淇濆瓨闃熶紞鏁版嵁
+ /// </summary>
+ public void SaveTeamData()
+ {
+ // 瀹炵幇闃熶紞鏁版嵁鐨勪繚瀛橀�昏緫
+ // 鍙互浣跨敤 PlayerPrefs銆丣SON 搴忓垪鍖栨垨鍏朵粬鏂瑰紡
+ Debug.Log("淇濆瓨闃熶紞鏁版嵁");
+ }
+
+ /// <summary>
+ /// 鍔犺浇闃熶紞鏁版嵁
+ /// </summary>
+ public void LoadTeamData()
+ {
+ // 瀹炵幇闃熶紞鏁版嵁鐨勫姞杞介�昏緫
+ Debug.Log("鍔犺浇闃熶紞鏁版嵁");
+ }
+}
\ No newline at end of file
diff --git a/Main/Manager/GameSystemManager/TeamManager.cs.meta b/Main/Manager/GameSystemManager/TeamManager.cs.meta
new file mode 100644
index 0000000..739b68c
--- /dev/null
+++ b/Main/Manager/GameSystemManager/TeamManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8ac01de78a793cf4fb759dddc21c0bbe
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Manager/IManager.cs b/Main/Manager/IManager.cs
new file mode 100644
index 0000000..b7fef68
--- /dev/null
+++ b/Main/Manager/IManager.cs
@@ -0,0 +1,7 @@
+
+
+public interface IManager
+{
+ void Init();
+ void Release();
+}
diff --git a/Main/Manager/IManager.cs.meta b/Main/Manager/IManager.cs.meta
new file mode 100644
index 0000000..c921773
--- /dev/null
+++ b/Main/Manager/IManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 15be84dd6a98de14cb553ac421b17fb9
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Manager/LoginManager.cs b/Main/Manager/LoginManager.cs
new file mode 100644
index 0000000..176e289
--- /dev/null
+++ b/Main/Manager/LoginManager.cs
@@ -0,0 +1,16 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class LoginManager : ManagerBase<LoginManager>
+{
+ public override void Init()
+ {
+
+ }
+
+ public override void Release()
+ {
+
+ }
+}
diff --git a/Main/Manager/LoginManager.cs.meta b/Main/Manager/LoginManager.cs.meta
new file mode 100644
index 0000000..660e708
--- /dev/null
+++ b/Main/Manager/LoginManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 344e28aa3edcfbd4f863a019c2cbaaac
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Manager/ManagerBase.cs b/Main/Manager/ManagerBase.cs
new file mode 100644
index 0000000..b28427b
--- /dev/null
+++ b/Main/Manager/ManagerBase.cs
@@ -0,0 +1,13 @@
+
+public class ManagerBase<T> : Singleton<T>, IManager where T : ManagerBase<T>, new()
+{
+ public virtual void Init()
+ {
+
+ }
+
+ public virtual void Release()
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Main/Manager/ManagerBase.cs.meta b/Main/Manager/ManagerBase.cs.meta
new file mode 100644
index 0000000..9587db4
--- /dev/null
+++ b/Main/Manager/ManagerBase.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8c651c6b070b83d48b0f07117ed43058
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Manager/StageManager.cs b/Main/Manager/StageManager.cs
new file mode 100644
index 0000000..55bfdc8
--- /dev/null
+++ b/Main/Manager/StageManager.cs
@@ -0,0 +1,119 @@
+using System;
+using Cysharp.Threading.Tasks;
+using UnityEngine;
+using UnityEngine.SceneManagement;
+
+public enum StageName
+{
+ Login,
+ Game,
+}
+
+public class StageManager : Singleton<StageManager>, IManager
+{
+ public StageName currentStage;
+
+ public void Init()
+ {
+
+ }
+
+ public void Release()
+ {
+
+ }
+
+ public async UniTaskVoid ToLoginScene()
+ {
+ UIManager.Instance.DestroyAllUI();
+
+ AsyncOperation asyncOperation = SceneManager.LoadSceneAsync("Login");
+
+ await OnLoading(asyncOperation, () => 1f);
+
+ Main.OnSwitchToLoginScene();
+
+ currentStage = StageName.Login;
+
+ UIManager.Instance.OpenWindow<LoginWin>();
+ }
+
+ protected float GetManagerRequestDataProgress()
+ {
+ if (Main.managers.Count == 0)
+ {
+ return 1f;
+ }
+
+ int count = 0;
+
+ for (int i = 0; i < Main.managers.Count; i++)
+ {
+ var manager = Main.managers[i];
+
+ if (manager.IsNessaryDataReady())
+ {
+ count++;
+ }
+ }
+
+ return ((float)count) / ((float)Main.managers.Count);
+ }
+
+ public async UniTaskVoid ToGameScene()
+ {
+ UIManager.Instance.DestroyAllUI();
+
+ ResManager.Instance.PrewarmResources();
+
+ AsyncOperation asyncOperation = SceneManager.LoadSceneAsync("Game");
+
+ await OnLoading(asyncOperation, GetManagerRequestDataProgress);
+
+ // 鍔犺浇鍒濆鍖栨暟鎹畬鎴�
+ currentStage = StageName.Game;
+
+ UIManager.Instance.OpenWindow<MainWin>();
+ }
+
+ protected async UniTask OnLoading(AsyncOperation asyncOperation, Func<float> getLoadingProgress, Func<UniTask> anthorTask = null)
+ {
+ asyncOperation.allowSceneActivation = false;
+
+ LoadingWin loadingWin = UIManager.Instance.OpenWindow<LoadingWin>();
+
+ while (!asyncOperation.isDone)
+ {
+ if (asyncOperation.progress >= 0.9f)
+ {
+ asyncOperation.allowSceneActivation = true;
+ }
+
+ loadingWin.SetProgress(asyncOperation.progress * 0.5f + getLoadingProgress() * 0.5f);
+
+ await UniTask.Yield();
+ }
+
+ float managerProgress = getLoadingProgress();
+
+ while (managerProgress < 1f)
+ {
+ loadingWin.SetProgress(asyncOperation.progress * 0.5f + managerProgress * 0.5f);
+
+ await UniTask.Yield();
+
+ managerProgress = getLoadingProgress();
+ }
+
+ if (anthorTask != null)
+ {
+ await anthorTask();
+ }
+
+ loadingWin.SetProgress(1f, true);
+
+ await UniTask.Delay(TimeSpan.FromSeconds(0.5f));
+
+ loadingWin.CloseWindow();
+ }
+}
\ No newline at end of file
diff --git a/Main/Manager/StageManager.cs.meta b/Main/Manager/StageManager.cs.meta
new file mode 100644
index 0000000..cd53cbe
--- /dev/null
+++ b/Main/Manager/StageManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: aac79594075c0524080fb21a459c7264
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Place.meta b/Main/Place.meta
new file mode 100644
index 0000000..cce66df
--- /dev/null
+++ b/Main/Place.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 1244e95cb51b1cb42a8adaba3a5dff53
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Place/PlaceDataStructs.cs b/Main/Place/PlaceDataStructs.cs
new file mode 100644
index 0000000..19f5af1
--- /dev/null
+++ b/Main/Place/PlaceDataStructs.cs
@@ -0,0 +1,83 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+/// <summary>
+/// 鍗曚綅鏁版嵁
+/// </summary>
+public class UnitData
+{
+ public int ID { get; set; }
+ public string Name { get; set; }
+ public int HP { get; set; }
+ public int Attack { get; set; }
+ public float AttackSpeed { get; set; }
+ public float MoveSpeed { get; set; }
+ public string PrefabPath { get; set; }
+}
+
+/// <summary>
+/// 绔犺妭鏁版嵁
+/// </summary>
+public class ChapterData
+{
+ public int ID { get; set; }
+ public string Name { get; set; }
+ public int MapId { get; set; }
+ public List<WaveData> Waves { get; set; }
+
+ /// <summary>
+ /// 鑾峰彇鎸囧畾娉㈡鐨勬晫浜哄垪琛�
+ /// </summary>
+ public List<int> GetEnemiesForWave(int wave)
+ {
+ if (wave <= 0 || wave > Waves.Count)
+ return new List<int>();
+
+ return Waves[wave - 1].EnemyIds;
+ }
+
+ /// <summary>
+ /// 鑾峰彇鎸囧畾娉㈡鐨勬帀钀界墿鍝�
+ /// </summary>
+ public List<DropItemData> GetDropsForWave(int wave)
+ {
+ if (wave <= 0 || wave > Waves.Count)
+ return new List<DropItemData>();
+
+ return Waves[wave - 1].DropItems;
+ }
+}
+
+/// <summary>
+/// 娉㈡鏁版嵁
+/// </summary>
+public class WaveData
+{
+ public int WaveIndex { get; set; }
+ public List<int> EnemyIds { get; set; }
+ public List<DropItemData> DropItems { get; set; }
+}
+
+/// <summary>
+/// 鐗╁搧绫诲瀷
+/// </summary>
+public enum ItemType
+{
+ Gold,
+ Diamond,
+ Item
+}
+
+/// <summary>
+/// 鎺夎惤鐗╁搧鏁版嵁
+/// </summary>
+public class DropItemData
+{
+ public int ID { get; set; }
+ public ItemType ItemType { get; set; }
+ public int ItemId { get; set; }
+ public int Amount { get; set; }
+ public float DropRate { get; set; }
+ public string IconPath { get; set; }
+}
\ No newline at end of file
diff --git a/Main/Place/PlaceDataStructs.cs.meta b/Main/Place/PlaceDataStructs.cs.meta
new file mode 100644
index 0000000..2064cc8
--- /dev/null
+++ b/Main/Place/PlaceDataStructs.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4541140280fac3541b7ec64b9acd2f20
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Place/PlaceDrop.cs b/Main/Place/PlaceDrop.cs
new file mode 100644
index 0000000..3abd5e0
--- /dev/null
+++ b/Main/Place/PlaceDrop.cs
@@ -0,0 +1,143 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+/// <summary>
+/// 鏀剧疆鎴樻枟鎺夎惤鐗╁搧绫�
+/// </summary>
+public class PlaceDrop
+{
+ // 鎺夎惤鐗╁搧鏁版嵁
+ public DropItemData DropData { get; private set; }
+
+ // 浣嶇疆
+ public Vector2 Position { get; private set; }
+
+ // 鐘舵��
+ private enum DropState
+ {
+ Dropping, // 鎺夎惤涓�
+ Waiting, // 绛夊緟鏀堕泦
+ Flying // 椋炲悜UI
+ }
+
+ private DropState currentState = DropState.Dropping;
+
+ // 璁℃椂鍣�
+ private float waitTimer = 0f;
+ private float waitDuration = 1.5f; // 绛夊緟1.5绉掑悗鑷姩鏀堕泦
+
+ // 椋炶鐩稿叧
+ private Vector2 targetPosition;
+ private float flySpeed = 10f;
+
+ // 鏄惁搴旇琚敹闆�
+ public bool ShouldCollect { get; private set; } = false;
+
+ // 鎺夎惤鍔ㄧ敾璁℃椂鍣�
+ private float dropAnimTimer = 0f;
+ private float dropAnimDuration = 0.5f;
+ private Vector2 startPosition;
+ private Vector2 endPosition;
+
+ /// <summary>
+ /// 鏋勯�犲嚱鏁�
+ /// </summary>
+ public PlaceDrop(DropItemData dropData)
+ {
+ DropData = dropData;
+
+ // 闅忔満鎺夎惤浣嶇疆锛堝湪鍦烘櫙涓績闄勮繎锛�
+ startPosition = new Vector2(Random.Range(-2f, 2f), 5f);
+ endPosition = new Vector2(
+ startPosition.x + Random.Range(-1f, 1f),
+ Random.Range(-1f, 1f)
+ );
+
+ Position = startPosition;
+
+ // 璁剧疆椋炲悜鐨勭洰鏍囦綅缃紙UI涓婄殑璐у竵鏍忎綅缃級
+ targetPosition = new Vector2(8f, 4f); // 绀轰緥浣嶇疆锛屽疄闄呭簲璇ユ槸UI涓揣甯佹爮鐨勪笘鐣屽潗鏍�
+ }
+
+ /// <summary>
+ /// 鏇存柊鎺夎惤鐗╁搧鐘舵��
+ /// </summary>
+ public void Update(float deltaTime)
+ {
+ switch (currentState)
+ {
+ case DropState.Dropping:
+ UpdateDropping(deltaTime);
+ break;
+
+ case DropState.Waiting:
+ UpdateWaiting(deltaTime);
+ break;
+
+ case DropState.Flying:
+ UpdateFlying(deltaTime);
+ break;
+ }
+ }
+
+ /// <summary>
+ /// 鏇存柊鎺夎惤鍔ㄧ敾
+ /// </summary>
+ private void UpdateDropping(float deltaTime)
+ {
+ dropAnimTimer += deltaTime;
+ float t = Mathf.Clamp01(dropAnimTimer / dropAnimDuration);
+
+ // 浣跨敤浜屾璐濆灏旀洸绾挎ā鎷熸帀钀芥晥鏋�
+ Position = Vector2.Lerp(startPosition, endPosition, t);
+
+ // 鎺夎惤鍔ㄧ敾瀹屾垚鍚庡垏鎹㈠埌绛夊緟鐘舵��
+ if (t >= 1.0f)
+ {
+ currentState = DropState.Waiting;
+ waitTimer = 0f;
+ }
+ }
+
+ /// <summary>
+ /// 鏇存柊绛夊緟鐘舵��
+ /// </summary>
+ private void UpdateWaiting(float deltaTime)
+ {
+ // 绛夊緟涓�娈垫椂闂村悗鑷姩鏀堕泦
+ waitTimer += deltaTime;
+ if (waitTimer >= waitDuration)
+ {
+ currentState = DropState.Flying;
+ }
+ }
+
+ /// <summary>
+ /// 鏇存柊椋炶鐘舵��
+ /// </summary>
+ private void UpdateFlying(float deltaTime)
+ {
+ // 璁$畻椋炶鏂瑰悜
+ Vector2 direction = (targetPosition - Position).normalized;
+
+ // 鏇存柊浣嶇疆
+ Position += direction * flySpeed * deltaTime;
+
+ // 妫�鏌ユ槸鍚﹀埌杈剧洰鏍�
+ float distanceToTarget = Vector2.Distance(Position, targetPosition);
+ if (distanceToTarget < 0.1f)
+ {
+ // 鍒拌揪鐩爣锛屾爣璁颁负搴旇琚敹闆�
+ ShouldCollect = true;
+ }
+ }
+
+ /// <summary>
+ /// 鎵嬪姩鏀堕泦鐗╁搧
+ /// </summary>
+ public void Collect()
+ {
+ currentState = DropState.Flying;
+ }
+}
\ No newline at end of file
diff --git a/Main/Place/PlaceDrop.cs.meta b/Main/Place/PlaceDrop.cs.meta
new file mode 100644
index 0000000..a1ee1ad
--- /dev/null
+++ b/Main/Place/PlaceDrop.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 070f25c487448bb44ac2134e1290d5f0
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Place/PlaceField.cs b/Main/Place/PlaceField.cs
new file mode 100644
index 0000000..bf2ab03
--- /dev/null
+++ b/Main/Place/PlaceField.cs
@@ -0,0 +1,406 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System;
+
+/// <summary>
+/// 鏀剧疆鎴樻枟鍦哄湴绫伙紝绠$悊鎴樻枟鍦烘櫙涓殑鎵�鏈夊厓绱�
+/// </summary>
+public class PlaceField
+{
+
+ // 褰撳墠绔犺妭淇℃伅
+ private ChapterData currentChapter;
+
+ // 鍦烘櫙涓殑鎵�鏈夊崟浣�
+ private List<PlaceUnit> allUnits = new List<PlaceUnit>();
+
+ // 鐜╁鍗曚綅鍒楄〃
+ private List<PlaceUnit> playerUnits = new List<PlaceUnit>();
+
+ // 鏁屼汉鍗曚綅鍒楄〃
+ private List<PlaceUnit> enemyUnits = new List<PlaceUnit>();
+
+ // 鍦烘櫙涓殑鎺夎惤鐗╁搧
+ private List<PlaceDrop> dropItems = new List<PlaceDrop>();
+
+ // 鎴樻枟鐘舵��
+ public enum BattleState
+ {
+ Preparing, // 鍑嗗涓�
+ Fighting, // 鎴樻枟涓�
+ Completed, // 鎴樻枟瀹屾垚
+ Waiting // 绛夊緟涓嬩竴鍦�
+ }
+
+ public BattleState CurrentState { get; private set; } = BattleState.Preparing;
+
+ // 鎴樻枟瀹屾垚浜嬩欢
+ public event Action OnBattleCompleted;
+
+ // 鎺夎惤鐗╁搧鏀堕泦浜嬩欢
+ public event Action<DropItemData> OnItemCollected;
+
+ // 绛夊緟璁℃椂鍣�
+ private float waitTimer = 0f;
+ private const float WAIT_DURATION = 2f; // 鎴樻枟缁撴潫鍚庣瓑寰�2绉�
+
+ /// <summary>
+ /// 鍒濆鍖栨垬鏂楀満鏅�
+ /// </summary>
+ /// <param name="chapterId">绔犺妭ID</param>
+ public void InitBattleField(int chapterId)
+ {
+ Debug.Log($"鍒濆鍖栨垬鏂楀満鍦�: 绔犺妭{chapterId}");
+
+ // 娓呯┖鍦烘櫙
+ ClearField();
+
+ // 鍔犺浇绔犺妭鏁版嵁
+ LoadChapterData(chapterId);
+
+ // 鍔犺浇鍦板浘鑳屾櫙
+ LoadMapBackground();
+
+ // 鐢熸垚鐜╁闃靛
+ SpawnPlayerUnits();
+
+ // 鐢熸垚鏁屾柟鍗曚綅
+ SpawnEnemyUnits();
+
+ // 璁剧疆鎴樻枟鐘舵�佷负鍑嗗涓�
+ CurrentState = BattleState.Preparing;
+ }
+
+ /// <summary>
+ /// 寮�濮嬫垬鏂�
+ /// </summary>
+ public void StartBattle()
+ {
+ if (CurrentState != BattleState.Preparing && CurrentState != BattleState.Waiting)
+ return;
+
+ Debug.Log("寮�濮嬫垬鏂�");
+ CurrentState = BattleState.Fighting;
+
+ // 閫氱煡鎵�鏈夊崟浣嶅紑濮嬫垬鏂�
+ foreach (var unit in allUnits)
+ {
+ unit.StartBattle();
+ }
+ }
+
+ /// <summary>
+ /// 鏇存柊鎴樺満鐘舵��
+ /// </summary>
+ public void UpdateField(float deltaTime)
+ {
+ switch (CurrentState)
+ {
+ case BattleState.Fighting:
+ UpdateFighting(deltaTime);
+ break;
+
+ case BattleState.Completed:
+ UpdateCompleted(deltaTime);
+ break;
+
+ case BattleState.Waiting:
+ UpdateWaiting(deltaTime);
+ break;
+ }
+ }
+
+ /// <summary>
+ /// 鏇存柊鎴樻枟鐘舵��
+ /// </summary>
+ private void UpdateFighting(float deltaTime)
+ {
+ // 鏇存柊鎵�鏈夊崟浣�
+ for (int i = allUnits.Count - 1; i >= 0; i--)
+ {
+ if (i < allUnits.Count)
+ {
+ allUnits[i].UpdateUnit(deltaTime);
+ }
+ }
+
+ // 妫�鏌ユ垬鏂楁槸鍚︾粨鏉�
+ CheckBattleEnd();
+
+ // 鏇存柊鎺夎惤鐗╁搧
+ UpdateDropItems(deltaTime);
+ }
+
+ /// <summary>
+ /// 鏇存柊鎴樻枟瀹屾垚鐘舵��
+ /// </summary>
+ private void UpdateCompleted(float deltaTime)
+ {
+ // 鏇存柊鎺夎惤鐗╁搧
+ UpdateDropItems(deltaTime);
+
+ // 妫�鏌ユ槸鍚︽墍鏈夋帀钀界墿鍝侀兘宸叉敹闆�
+ bool allItemsCollected = true;
+ foreach (var item in dropItems)
+ {
+ if (!item.ShouldCollect)
+ {
+ allItemsCollected = false;
+ break;
+ }
+ }
+
+ // 濡傛灉鎵�鏈夌墿鍝侀兘宸叉敹闆嗭紝杩涘叆绛夊緟鐘舵��
+ if (allItemsCollected && dropItems.Count > 0)
+ {
+ CurrentState = BattleState.Waiting;
+ waitTimer = 0f;
+ }
+ // 濡傛灉娌℃湁鎺夎惤鐗╁搧锛岀洿鎺ヨ繘鍏ョ瓑寰呯姸鎬�
+ else if (dropItems.Count == 0)
+ {
+ CurrentState = BattleState.Waiting;
+ waitTimer = 0f;
+ }
+ }
+
+ /// <summary>
+ /// 鏇存柊绛夊緟鐘舵��
+ /// </summary>
+ private void UpdateWaiting(float deltaTime)
+ {
+ waitTimer += deltaTime;
+
+ // 绛夊緟鏃堕棿缁撴潫鍚庯紝寮�濮嬩笅涓�鍦烘垬鏂�
+ if (waitTimer >= WAIT_DURATION)
+ {
+ // 娓呯悊鎴樺満
+ ClearField();
+
+ // 閲嶆柊鍒濆鍖栨垬鍦�
+ InitBattleField(currentChapter.ID);
+
+ // 寮�濮嬫柊鐨勬垬鏂�
+ StartBattle();
+ }
+ }
+
+ /// <summary>
+ /// 鍔犺浇绔犺妭鏁版嵁
+ /// </summary>
+ private void LoadChapterData(int chapterId)
+ {
+ // 浠庨厤缃鐞嗗櫒鍔犺浇绔犺妭鏁版嵁
+ // currentChapter = ConfigManager.Instance.GetChapterData(chapterId);
+
+ // 涓存椂浠g爜锛屽垱寤轰竴涓祴璇曠珷鑺�
+ currentChapter = new ChapterData
+ {
+ ID = chapterId,
+ Name = $"娴嬭瘯绔犺妭 {chapterId}",
+ MapId = chapterId
+ };
+
+ Debug.Log($"鍔犺浇绔犺妭鏁版嵁: {currentChapter.Name}");
+ }
+
+ /// <summary>
+ /// 鍔犺浇鍦板浘鑳屾櫙
+ /// </summary>
+ private void LoadMapBackground()
+ {
+ // 鏍规嵁绔犺妭鏁版嵁鍔犺浇瀵瑰簲鐨勫湴鍥捐儗鏅�
+ // MapManager.Instance.LoadMap(currentChapter.MapId);
+ Debug.Log($"鍔犺浇鍦板浘鑳屾櫙: MapID={currentChapter.MapId}");
+ }
+
+ /// <summary>
+ /// 鐢熸垚鐜╁闃靛
+ /// </summary>
+ private void SpawnPlayerUnits()
+ {
+ Debug.Log("鐢熸垚鐜╁闃靛");
+
+ // 浠庣帺瀹舵暟鎹腑鑾峰彇褰撳墠闃靛
+ // var formation = PlayerManager.Instance.CurrentFormation;
+
+ // 涓存椂浠g爜锛屽垱寤烘祴璇曠帺瀹跺崟浣�
+ for (int i = 0; i < 3; i++)
+ {
+ UnitData unitData = new UnitData
+ {
+ ID = 1000 + i,
+ Name = $"鐜╁瑙掕壊 {i+1}",
+ HP = 100,
+ Attack = 10,
+ AttackSpeed = 1.0f,
+ MoveSpeed = 2.0f,
+ PrefabPath = $"Characters/Player_{i+1}"
+ };
+
+ PlaceUnit unit = new PlaceUnit(unitData, true);
+ playerUnits.Add(unit);
+ allUnits.Add(unit);
+
+ Debug.Log($"鐢熸垚鐜╁鍗曚綅: {unit.UnitData.Name}");
+ }
+ }
+
+ /// <summary>
+ /// 鐢熸垚鏁屾柟鍗曚綅
+ /// </summary>
+ private void SpawnEnemyUnits()
+ {
+ Debug.Log("鐢熸垚鏁屾柟鍗曚綅");
+
+ // 鏍规嵁绔犺妭鏁版嵁鐢熸垚鏁屾柟鍗曚綅
+ // var enemyIds = currentChapter.GetEnemiesForWave(1);
+
+ // 涓存椂浠g爜锛屽垱寤烘祴璇曟晫鏂瑰崟浣�
+ for (int i = 0; i < 5; i++)
+ {
+ UnitData unitData = new UnitData
+ {
+ ID = 2000 + i,
+ Name = $"鏁屾柟鍗曚綅 {i+1}",
+ HP = 50,
+ Attack = 5,
+ AttackSpeed = 0.8f,
+ MoveSpeed = 1.5f,
+ PrefabPath = $"Characters/Enemy_{i+1}"
+ };
+
+ PlaceUnit unit = new PlaceUnit(unitData, false);
+ enemyUnits.Add(unit);
+ allUnits.Add(unit);
+
+ Debug.Log($"鐢熸垚鏁屾柟鍗曚綅: {unit.UnitData.Name}");
+ }
+ }
+
+ /// <summary>
+ /// 妫�鏌ユ垬鏂楁槸鍚︾粨鏉�
+ /// </summary>
+ private void CheckBattleEnd()
+ {
+ // 妫�鏌ユ晫鏂瑰崟浣嶆槸鍚﹀叏閮ㄩ樀浜�
+ bool allEnemyDead = true;
+ foreach (var unit in enemyUnits)
+ {
+ if (!unit.IsDead)
+ {
+ allEnemyDead = false;
+ break;
+ }
+ }
+
+ // 濡傛灉鎵�鏈夋晫浜洪兘宸查樀浜★紝鎴樻枟缁撴潫
+ if (allEnemyDead)
+ {
+ CompleteBattle();
+ }
+ }
+
+ /// <summary>
+ /// 瀹屾垚鎴樻枟
+ /// </summary>
+ private void CompleteBattle()
+ {
+ Debug.Log("鎴樻枟瀹屾垚");
+ CurrentState = BattleState.Completed;
+
+ // 鍋滄鎵�鏈夊崟浣嶈鍔�
+ foreach (var unit in allUnits)
+ {
+ unit.StopBattle();
+ }
+
+ // 鐢熸垚鎺夎惤鐗╁搧
+ GenerateDropItems();
+
+ // 瑙﹀彂鎴樻枟瀹屾垚浜嬩欢
+ OnBattleCompleted?.Invoke();
+ }
+
+ /// <summary>
+ /// 鐢熸垚鎺夎惤鐗╁搧
+ /// </summary>
+ private void GenerateDropItems()
+ {
+ Debug.Log("鐢熸垚鎺夎惤鐗╁搧");
+
+ // 鏍规嵁绔犺妭鎺夎惤琛ㄧ敓鎴愭帀钀界墿鍝�
+ // var dropList = currentChapter.GetDropsForWave(1);
+
+ // 涓存椂浠g爜锛屽垱寤烘祴璇曟帀钀界墿鍝�
+ for (int i = 0; i < 5; i++)
+ {
+ DropItemData dropData = new DropItemData
+ {
+ ID = i,
+ ItemType = (i % 3 == 0) ? ItemType.Gold : (i % 3 == 1) ? ItemType.Diamond : ItemType.Item,
+ ItemId = i,
+ Amount = UnityEngine.Random.Range(10, 100),
+ DropRate = 1.0f,
+ IconPath = $"Icons/Item_{i}"
+ };
+
+ // 鍒涘缓鎺夎惤鐗╁搧
+ PlaceDrop drop = new PlaceDrop(dropData);
+ dropItems.Add(drop);
+
+ Debug.Log($"鐢熸垚鎺夎惤鐗╁搧: 绫诲瀷={dropData.ItemType}, 鏁伴噺={dropData.Amount}");
+ }
+ }
+
+ /// <summary>
+ /// 鏇存柊鎺夎惤鐗╁搧
+ /// </summary>
+ private void UpdateDropItems(float deltaTime)
+ {
+ for (int i = dropItems.Count - 1; i >= 0; i--)
+ {
+ dropItems[i].Update(deltaTime);
+
+ // 妫�鏌ユ槸鍚﹂渶瑕佹敹闆嗙墿鍝�
+ if (dropItems[i].ShouldCollect)
+ {
+ // 瑙﹀彂鐗╁搧鏀堕泦浜嬩欢
+ OnItemCollected?.Invoke(dropItems[i].DropData);
+
+ // 绉婚櫎鐗╁搧
+ dropItems.RemoveAt(i);
+ }
+ }
+ }
+
+ /// <summary>
+ /// 娓呯┖鎴樺満
+ /// </summary>
+ public void ClearField()
+ {
+ Debug.Log("娓呯┖鎴樺満");
+ allUnits.Clear();
+ playerUnits.Clear();
+ enemyUnits.Clear();
+ dropItems.Clear();
+ CurrentState = BattleState.Preparing;
+ }
+
+ /// <summary>
+ /// 鑾峰彇鐜╁鍗曚綅鍒楄〃
+ /// </summary>
+ public List<PlaceUnit> GetPlayerUnits()
+ {
+ return new List<PlaceUnit>(playerUnits);
+ }
+
+ /// <summary>
+ /// 鑾峰彇鏁屾柟鍗曚綅鍒楄〃
+ /// </summary>
+ public List<PlaceUnit> GetEnemyUnits()
+ {
+ return new List<PlaceUnit>(enemyUnits);
+ }
+}
diff --git a/Main/Place/PlaceField.cs.meta b/Main/Place/PlaceField.cs.meta
new file mode 100644
index 0000000..875ca33
--- /dev/null
+++ b/Main/Place/PlaceField.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b82dee68a4dcad54780acf1dad335d8c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/Place/PlaceUnit.cs b/Main/Place/PlaceUnit.cs
new file mode 100644
index 0000000..fe4eca5
--- /dev/null
+++ b/Main/Place/PlaceUnit.cs
@@ -0,0 +1,516 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+/// <summary>
+/// 鏀剧疆鎴樻枟鍗曚綅绫伙紝浠h〃鎴樺満涓婄殑涓�涓鑹�
+/// </summary>
+public class PlaceUnit
+{
+ // 鍗曚綅鏁版嵁
+ public UnitData UnitData { get; private set; }
+
+ // 鍗曚綅灞炴��
+ public int HP { get; private set; }
+ public int MaxHP { get; private set; }
+ public int Attack { get; private set; }
+ public float AttackSpeed { get; private set; }
+ public float MoveSpeed { get; private set; }
+
+ // 鍗曚綅鐘舵��
+ public bool IsPlayer { get; private set; }
+ public bool IsDead { get; private set; }
+
+ // 浣嶇疆鍜屾湞鍚�
+ public Vector2 Position { get; private set; }
+ public Vector2 Direction { get; private set; }
+
+ // 鎴樻枟鐩稿叧
+ private PlaceUnit targetUnit;
+ private float attackCooldown;
+
+ // 鍗曚綅琛屼负鐘舵��
+ public enum UnitState
+ {
+ Idle, // 寰呮満
+ Moving, // 绉诲姩涓�
+ Attacking, // 鏀诲嚮涓�
+ Dead // 姝讳骸
+ }
+
+ public UnitState CurrentState { get; private set; } = UnitState.Idle;
+
+ /// <summary>
+ /// 鏋勯�犲嚱鏁�
+ /// </summary>
+ /// <param name="data">鍗曚綅鏁版嵁</param>
+ /// <param name="isPlayer">鏄惁涓虹帺瀹跺崟浣�</param>
+ public PlaceUnit(UnitData data, bool isPlayer)
+ {
+ UnitData = data;
+ IsPlayer = isPlayer;
+
+ // 鍒濆鍖栧睘鎬�
+ MaxHP = data.HP;
+ HP = MaxHP;
+ Attack = data.Attack;
+ AttackSpeed = data.AttackSpeed;
+ MoveSpeed = data.MoveSpeed;
+
+ // 鍒濆鍖栨敾鍑诲喎鍗�
+ attackCooldown = Random.Range(0f, 1f / AttackSpeed);
+
+ // 璁剧疆鍒濆浣嶇疆
+ Position = isPlayer ? new Vector2(-5f + Random.Range(-1f, 1f), Random.Range(-2f, 2f)) :
+ new Vector2(5f + Random.Range(-1f, 1f), Random.Range(-2f, 2f));
+ Direction = isPlayer ? Vector2.right : Vector2.left;
+
+ IsDead = false;
+ CurrentState = UnitState.Idle;
+ }
+
+ /// <summary>
+ /// 寮�濮嬫垬鏂�
+ /// </summary>
+ public void StartBattle()
+ {
+ if (IsDead) return;
+
+ CurrentState = UnitState.Idle;
+ FindTarget();
+ }
+
+ /// <summary>
+ /// 鍋滄鎴樻枟
+ /// </summary>
+ public void StopBattle()
+ {
+ if (IsDead) return;
+
+ CurrentState = UnitState.Idle;
+ targetUnit = null;
+ }
+
+ /// <summary>
+ /// 鏇存柊鍗曚綅鐘舵��
+ /// </summary>
+ public void UpdateUnit(float deltaTime)
+ {
+ if (IsDead) return;
+
+ // 濡傛灉娌℃湁鐩爣锛屽皾璇曞鎵剧洰鏍�
+ if (targetUnit == null || targetUnit.IsDead)
+ {
+ FindTarget();
+ if (targetUnit == null)
+ {
+ CurrentState = UnitState.Idle;
+ return;
+ }
+ }
+
+ // 鏍规嵁涓庣洰鏍囩殑璺濈鍐冲畾琛屼负
+ float distanceToTarget = Vector2.Distance(Position, targetUnit.Position);
+ float attackRange = 1.5f; // 鏀诲嚮鑼冨洿
+
+ if (distanceToTarget <= attackRange)
+ {
+ // 鍦ㄦ敾鍑昏寖鍥村唴锛屾墽琛屾敾鍑�
+ AttackTarget(deltaTime);
+ }
+ else
+ {
+ // 涓嶅湪鏀诲嚮鑼冨洿鍐咃紝绉诲姩鎺ヨ繎鐩爣
+ MoveToTarget(deltaTime);
+ }
+ }
+
+ /// <summary>
+ /// 瀵绘壘鐩爣
+ /// </summary>
+ private void FindTarget()
+ {
+ // 浠庡満鏅腑瀵绘壘鏁屽鍗曚綅浣滀负鐩爣
+ List<PlaceUnit> potentialTargets = IsPlayer ?
+ PlaceManager.Instance.placeField.GetEnemyUnits() :
+ PlaceManager.Instance.placeField.GetPlayerUnits();
+
+ float minDistance = float.MaxValue;
+ PlaceUnit nearestTarget = null;
+
+ foreach (var unit in potentialTargets)
+ {
+ if (!unit.IsDead)
+ {
+ float distance = Vector2.Distance(Position, unit.Position);
+ if (distance < minDistance)
+ {
+ minDistance = distance;
+ nearestTarget = unit;
+ }
+ }
+ }
+
+ targetUnit = nearestTarget;
+ }
+
+ /// <summary>
+ /// 绉诲姩鍚戠洰鏍�
+ /// </summary>
+ private void MoveToTarget(float deltaTime)
+ {
+ CurrentState = UnitState.Moving;
+
+ // 璁$畻绉诲姩鏂瑰悜
+ Vector2 moveDirection = (targetUnit.Position - Position).normalized;
+
+ // 妫�鏌ユ槸鍚︽湁闅滅鐗╋紝濡傛灉鏈夊垯闇�瑕佸璺�
+ if (HasObstacle(Position, targetUnit.Position))
+ {
+ // 绠�鍗曠殑瀵昏矾閫昏緫
+ moveDirection = FindPathDirection(targetUnit.Position);
+ }
+
+ // 妫�鏌ユ槸鍚︿笌鍏朵粬鍗曚綅閲嶅彔
+ Vector2 avoidanceDirection = Vector2.zero;
+ int avoidanceCount = 0;
+
+ // 鑾峰彇鎵�鏈夊崟浣�
+ List<PlaceUnit> allUnits = new List<PlaceUnit>();
+ allUnits.AddRange(PlaceManager.Instance.placeField.GetPlayerUnits());
+ allUnits.AddRange(PlaceManager.Instance.placeField.GetEnemyUnits());
+
+ // 妫�鏌ラ檮杩戠殑鍗曚綅
+ foreach (var unit in allUnits)
+ {
+ if (unit != this && !unit.IsDead)
+ {
+ float distance = Vector2.Distance(Position, unit.Position);
+ if (distance < 1.0f) // 閬胯璺濈
+ {
+ // 璁$畻閬胯鏂瑰悜
+ Vector2 dir = (Position - unit.Position).normalized;
+ avoidanceDirection += dir;
+ avoidanceCount++;
+ }
+ }
+ }
+
+ // 濡傛灉鏈夐渶瑕侀伩璁╃殑鍗曚綅锛岃皟鏁寸Щ鍔ㄦ柟鍚�
+ if (avoidanceCount > 0)
+ {
+ avoidanceDirection /= avoidanceCount;
+ moveDirection = Vector2.Lerp(moveDirection, avoidanceDirection, 0.5f).normalized;
+ }
+
+ // 鏇存柊浣嶇疆
+ Position += moveDirection * MoveSpeed * deltaTime;
+
+ // 鏇存柊鏈濆悜
+ Direction = moveDirection;
+ }
+
+ /// <summary>
+ /// 妫�鏌ユ槸鍚︽湁闅滅鐗�
+ /// </summary>
+ private bool HasObstacle(Vector2 start, Vector2 end)
+ {
+ // 绠�鍗曠殑闅滅鐗╂娴嬶紝瀹為檯椤圭洰涓彲鑳介渶瑕佹洿澶嶆潅鐨勭鎾炴娴�
+ // 杩欓噷鍙互浣跨敤Physics2D.Raycast鏉ユ娴�
+
+ // 绀轰緥浠g爜
+ // RaycastHit2D hit = Physics2D.Raycast(start, end - start, Vector2.Distance(start, end), obstacleLayer);
+ // return hit.collider != null;
+
+ // 涓存椂浠g爜锛岄殢鏈虹敓鎴愰殰纰嶇墿
+ return Random.value < 0.1f;
+ }
+
+ /// <summary>
+ /// 瀵绘壘璺緞鏂瑰悜
+ /// </summary>
+ private Vector2 FindPathDirection(Vector2 target)
+ {
+ // 浣跨敤A*瀵昏矾绠楁硶
+ List<Node> path = AStar(Position, target);
+
+ if (path != null && path.Count > 0)
+ {
+ // 鑾峰彇涓嬩竴涓妭鐐圭殑鏂瑰悜
+ Vector2 nextNodePos = path[0].position;
+ return (nextNodePos - Position).normalized;
+ }
+
+ // 濡傛灉瀵昏矾澶辫触锛岀洿鎺ヨ繑鍥炵洰鏍囨柟鍚�
+ return (target - Position).normalized;
+ }
+
+ /// <summary>
+ /// A*瀵昏矾绠楁硶
+ /// </summary>
+ private List<Node> AStar(Vector2 start, Vector2 goal)
+ {
+ // 缃戞牸澶у皬璁剧疆
+ float gridSize = 0.5f;
+ int gridWidth = 20;
+ int gridHeight = 10;
+
+ // 鍒涘缓寮�鏀惧垪琛ㄥ拰鍏抽棴鍒楄〃
+ List<Node> openList = new List<Node>();
+ List<Node> closedList = new List<Node>();
+
+ // 鍒涘缓璧风偣鍜岀粓鐐硅妭鐐�
+ Node startNode = new Node(start, null);
+ Node goalNode = new Node(goal, null);
+
+ // 璁$畻璧风偣鐨刦銆乬銆乭鍊�
+ startNode.g = 0;
+ startNode.h = CalculateHeuristic(startNode, goalNode);
+ startNode.f = startNode.g + startNode.h;
+
+ // 灏嗚捣鐐瑰姞鍏ュ紑鏀惧垪琛�
+ openList.Add(startNode);
+
+ // 寮�濮婣*绠楁硶涓诲惊鐜�
+ while (openList.Count > 0)
+ {
+ // 鎵惧埌寮�鏀惧垪琛ㄤ腑f鍊兼渶灏忕殑鑺傜偣
+ Node currentNode = FindNodeWithLowestF(openList);
+
+ // 濡傛灉褰撳墠鑺傜偣鏄洰鏍囪妭鐐癸紝鍒欐瀯寤鸿矾寰勫苟杩斿洖
+ if (Vector2.Distance(currentNode.position, goalNode.position) < gridSize)
+ {
+ return BuildPath(currentNode);
+ }
+
+ // 灏嗗綋鍓嶈妭鐐逛粠寮�鏀惧垪琛ㄧЩ闄わ紝鍔犲叆鍏抽棴鍒楄〃
+ openList.Remove(currentNode);
+ closedList.Add(currentNode);
+
+ // 鑾峰彇褰撳墠鑺傜偣鐨勭浉閭昏妭鐐�
+ List<Node> neighbors = GetNeighbors(currentNode, gridSize, gridWidth, gridHeight);
+
+ foreach (Node neighbor in neighbors)
+ {
+ // 濡傛灉鐩搁偦鑺傜偣鍦ㄥ叧闂垪琛ㄤ腑锛屽垯璺宠繃
+ if (IsNodeInList(neighbor, closedList))
+ {
+ continue;
+ }
+
+ // 濡傛灉鐩搁偦鑺傜偣浣嶇疆鏈夐殰纰嶇墿锛屽垯璺宠繃
+ if (HasObstacle(currentNode.position, neighbor.position))
+ {
+ continue;
+ }
+
+ // 璁$畻浠庤捣鐐圭粡杩囧綋鍓嶈妭鐐瑰埌鐩搁偦鑺傜偣鐨勪唬浠�
+ float tentativeG = currentNode.g + Vector2.Distance(currentNode.position, neighbor.position);
+
+ // 濡傛灉鐩搁偦鑺傜偣涓嶅湪寮�鏀惧垪琛ㄤ腑锛屾垨鑰呮柊璺緞鏇翠紭锛屽垯鏇存柊鐩搁偦鑺傜偣
+ if (!IsNodeInList(neighbor, openList) || tentativeG < neighbor.g)
+ {
+ neighbor.parent = currentNode;
+ neighbor.g = tentativeG;
+ neighbor.h = CalculateHeuristic(neighbor, goalNode);
+ neighbor.f = neighbor.g + neighbor.h;
+
+ // 濡傛灉鐩搁偦鑺傜偣涓嶅湪寮�鏀惧垪琛ㄤ腑锛屽垯鍔犲叆寮�鏀惧垪琛�
+ if (!IsNodeInList(neighbor, openList))
+ {
+ openList.Add(neighbor);
+ }
+ }
+ }
+ }
+
+ // 濡傛灉寮�鏀惧垪琛ㄤ负绌猴紝鍒欏璺け璐ワ紝杩斿洖null
+ return null;
+ }
+
+ /// <summary>
+ /// 璁$畻鍚彂寮忓嚱鏁板�硷紙鏇煎搱椤胯窛绂伙級
+ /// </summary>
+ private float CalculateHeuristic(Node node, Node goal)
+ {
+ // 浣跨敤鏇煎搱椤胯窛绂讳綔涓哄惎鍙戝紡鍑芥暟
+ return Mathf.Abs(node.position.x - goal.position.x) + Mathf.Abs(node.position.y - goal.position.y);
+ }
+
+ /// <summary>
+ /// 鏌ユ壘寮�鏀惧垪琛ㄤ腑f鍊兼渶灏忕殑鑺傜偣
+ /// </summary>
+ private Node FindNodeWithLowestF(List<Node> list)
+ {
+ Node lowestNode = list[0];
+
+ for (int i = 1; i < list.Count; i++)
+ {
+ if (list[i].f < lowestNode.f)
+ {
+ lowestNode = list[i];
+ }
+ }
+
+ return lowestNode;
+ }
+
+ /// <summary>
+ /// 鑾峰彇鑺傜偣鐨勭浉閭昏妭鐐�
+ /// </summary>
+ private List<Node> GetNeighbors(Node node, float gridSize, int gridWidth, int gridHeight)
+ {
+ List<Node> neighbors = new List<Node>();
+
+ // 8涓柟鍚戠殑鐩搁偦鑺傜偣
+ Vector2[] directions = new Vector2[]
+ {
+ new Vector2(1, 0), // 鍙�
+ new Vector2(-1, 0), // 宸�
+ new Vector2(0, 1), // 涓�
+ new Vector2(0, -1), // 涓�
+ new Vector2(1, 1), // 鍙充笂
+ new Vector2(1, -1), // 鍙充笅
+ new Vector2(-1, 1), // 宸︿笂
+ new Vector2(-1, -1) // 宸︿笅
+ };
+
+ foreach (Vector2 dir in directions)
+ {
+ Vector2 neighborPos = node.position + dir * gridSize;
+
+ // 妫�鏌ユ槸鍚﹀湪缃戞牸鑼冨洿鍐�
+ if (neighborPos.x >= -gridWidth/2 && neighborPos.x <= gridWidth/2 &&
+ neighborPos.y >= -gridHeight/2 && neighborPos.y <= gridHeight/2)
+ {
+ Node neighbor = new Node(neighborPos, node);
+ neighbors.Add(neighbor);
+ }
+ }
+
+ return neighbors;
+ }
+
+ /// <summary>
+ /// 妫�鏌ヨ妭鐐规槸鍚﹀湪鍒楄〃涓�
+ /// </summary>
+ private bool IsNodeInList(Node node, List<Node> list)
+ {
+ foreach (Node n in list)
+ {
+ if (Vector2.Distance(n.position, node.position) < 0.1f)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// 鏋勫缓浠庤捣鐐瑰埌褰撳墠鑺傜偣鐨勮矾寰�
+ /// </summary>
+ private List<Node> BuildPath(Node node)
+ {
+ List<Node> path = new List<Node>();
+ Node currentNode = node;
+
+ // 浠庣洰鏍囪妭鐐瑰洖婧埌璧风偣
+ while (currentNode.parent != null)
+ {
+ path.Insert(0, currentNode);
+ currentNode = currentNode.parent;
+ }
+
+ return path;
+ }
+
+ /// <summary>
+ /// A*瀵昏矾鐨勮妭鐐圭被
+ /// </summary>
+ private class Node
+ {
+ public Vector2 position; // 鑺傜偣浣嶇疆
+ public Node parent; // 鐖惰妭鐐�
+ public float g; // 浠庤捣鐐瑰埌褰撳墠鑺傜偣鐨勪唬浠�
+ public float h; // 浠庡綋鍓嶈妭鐐瑰埌鐩爣鑺傜偣鐨勪及璁′唬浠�
+ public float f; // f = g + h锛屾�讳唬浠�
+
+ public Node(Vector2 pos, Node parent)
+ {
+ this.position = pos;
+ this.parent = parent;
+ }
+ }
+
+ /// <summary>
+ /// 鏀诲嚮鐩爣
+ /// </summary>
+ private void AttackTarget(float deltaTime)
+ {
+ CurrentState = UnitState.Attacking;
+
+ // 鏀诲嚮鍐峰嵈
+ attackCooldown -= deltaTime;
+ if (attackCooldown <= 0)
+ {
+ // 鎵ц鏀诲嚮
+ PerformAttack();
+
+ // 閲嶇疆鍐峰嵈
+ attackCooldown = 1f / AttackSpeed;
+ }
+ }
+
+ /// <summary>
+ /// 鎵ц鏀诲嚮
+ /// </summary>
+ private void PerformAttack()
+ {
+ if (targetUnit != null && !targetUnit.IsDead)
+ {
+ // 閫犳垚浼ゅ
+ targetUnit.TakeDamage(Attack);
+
+ // 鎾斁鏀诲嚮鍔ㄧ敾/鐗规晥
+ Debug.Log($"{UnitData.Name} 鏀诲嚮 {targetUnit.UnitData.Name}, 閫犳垚 {Attack} 鐐逛激瀹�");
+ }
+ }
+
+ /// <summary>
+ /// 鍙楀埌浼ゅ
+ /// </summary>
+ public void TakeDamage(int damage)
+ {
+ if (IsDead) return;
+
+ // 璁$畻瀹為檯浼ゅ锛堣�冭檻闃插尽绛夊洜绱狅級
+ int defense = Mathf.Max(0, MaxHP / 20); // 绠�鍗曢槻寰¤绠楋紝鍩轰簬鏈�澶х敓鍛藉��
+ int actualDamage = Mathf.Max(1, damage - defense); // 纭繚鑷冲皯閫犳垚1鐐逛激瀹�
+
+ // 鎵i櫎鐢熷懡鍊�
+ HP -= actualDamage;
+
+ // 妫�鏌ユ槸鍚︽浜�
+ if (HP <= 0)
+ {
+ HP = 0;
+ Die();
+ }
+
+ // 鏄剧ず浼ゅ鏁板瓧
+ Debug.Log($"{UnitData.Name} 鍙楀埌 {actualDamage} 鐐逛激瀹�, 鍓╀綑HP: {HP}/{MaxHP}");
+ }
+
+ /// <summary>
+ /// 姝讳骸澶勭悊
+ /// </summary>
+ private void Die()
+ {
+ IsDead = true;
+ CurrentState = UnitState.Dead;
+
+ // 鎾斁姝讳骸鍔ㄧ敾
+ Debug.Log($"{UnitData.Name} 姝讳骸");
+ }
+}
\ No newline at end of file
diff --git a/Main/Place/PlaceUnit.cs.meta b/Main/Place/PlaceUnit.cs.meta
new file mode 100644
index 0000000..34a21a2
--- /dev/null
+++ b/Main/Place/PlaceUnit.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 84bf5729662617b4582cbe05bad8d53c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/UI/LoadingWin.cs b/Main/UI/LoadingWin.cs
new file mode 100644
index 0000000..4f293e7
--- /dev/null
+++ b/Main/UI/LoadingWin.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class LoadingWin : UIBase
+{
+ protected int currentProgress = 0;
+ protected int targetProgress = 0;
+
+ protected Text titleText;
+ protected Text tipsText;
+ protected Image progressBar;
+ protected Text progressText;
+
+ protected override void InitComponent()
+ {
+ base.InitComponent();
+ titleText = transform.Find("Text_Loading").GetComponent<Text>();
+ tipsText = transform.Find("Text_Tips").GetComponent<Text>();
+ progressBar = transform.Find("Img_Progress/Img_Foreground").GetComponent<Image>();
+ progressText = transform.Find("Text_Progress").GetComponent<Text>();
+ }
+
+ public override void HandleOpen()
+ {
+ base.HandleOpen();
+ currentProgress = targetProgress = 0;
+ Refresh();
+ }
+
+ public override void HandleClose()
+ {
+ base.HandleClose();
+ }
+
+ public override void Refresh()
+ {
+ base.Refresh();
+ UpdateProgress();
+ }
+
+ public void SetProgress(float value, bool directly = false)
+ {
+ if (directly)
+ {
+ currentProgress = targetProgress = (int)(value * 100);
+ UpdateProgress();
+ }
+ else
+ {
+ currentProgress = (int)(value * 100);
+ }
+
+
+ }
+
+ protected void UpdateProgress()
+ {
+ progressText.text = currentProgress + "%";
+ progressBar.fillAmount = currentProgress / 100f;
+ }
+
+ protected void Update()
+ {
+ if (currentProgress < targetProgress)
+ {
+ currentProgress = (int)Mathf.Lerp(currentProgress, targetProgress, 0.1f);
+ UpdateProgress();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Main/UI/LoadingWin.cs.meta b/Main/UI/LoadingWin.cs.meta
new file mode 100644
index 0000000..850f121
--- /dev/null
+++ b/Main/UI/LoadingWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e85e62037b34d9944a44a4c93764c656
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/UI/Login.meta b/Main/UI/Login.meta
new file mode 100644
index 0000000..99ddaf1
--- /dev/null
+++ b/Main/UI/Login.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: bef9e971d62416147ae8006de5cbff6a
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/UI/Login/LoginWin.cs b/Main/UI/Login/LoginWin.cs
new file mode 100644
index 0000000..3df7acb
--- /dev/null
+++ b/Main/UI/Login/LoginWin.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics.Tracing;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class LoginWin : UIBase
+{
+ private InputField username;
+ private InputField password;
+ private Button loginBtn;
+ private Button registerBtn;
+
+ protected override void InitComponent()
+ {
+ base.InitComponent();
+ Debug.Log("鍒濆鍖栫櫥褰曠獥鍙�");
+ username = transform.Find("InputUserName").GetComponent<InputField>();
+ password = transform.Find("InputPassword").GetComponent<InputField>();
+ loginBtn = transform.Find("Buttons/ButtonLogin").GetComponent<Button>();
+ registerBtn = transform.Find("Buttons/ButtonRegister").GetComponent<Button>();
+
+ loginBtn.onClick.AddListener(OnLoginBtnClick);
+ registerBtn.onClick.AddListener(OnRegisterBtnClick);
+ }
+
+ public override void HandleOpen()
+ {
+ base.HandleOpen();
+ Debug.Log("鎵撳紑鐧诲綍绐楀彛");
+ ResManager.Instance.PrewarmResources();
+ Refresh();
+ }
+
+ public override void HandleClose()
+ {
+ base.HandleClose();
+ Debug.Log("鍏抽棴鐧诲綍绐楀彛");
+ }
+
+ public override void Refresh()
+ {
+ base.Refresh();
+ Debug.Log("鍒锋柊鐧诲綍绐楀彛");
+ }
+
+ private void OnRegisterBtnClick()
+ {
+ // TODO 娉ㄥ唽
+ Debug.Log("娉ㄥ唽");
+ }
+
+ private void OnLoginBtnClick()
+ {
+ // TODO 鐧诲綍
+ Debug.Log("鐧诲綍" + username.text + " / " + password.text);
+ UIManager.Instance.CloseWindow(this);
+
+ StageManager.Instance.ToGameScene();
+ }
+}
diff --git a/Main/UI/Login/LoginWin.cs.meta b/Main/UI/Login/LoginWin.cs.meta
new file mode 100644
index 0000000..b51a43c
--- /dev/null
+++ b/Main/UI/Login/LoginWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1d9e1ce1eab28d84188a1c2db2c1c472
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/UI/Main.meta b/Main/UI/Main.meta
new file mode 100644
index 0000000..0efa991
--- /dev/null
+++ b/Main/UI/Main.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 35cec4a6bce278e4b9c8efc66988e0e2
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/UI/Main/MainWin.cs b/Main/UI/Main/MainWin.cs
new file mode 100644
index 0000000..5164b2e
--- /dev/null
+++ b/Main/UI/Main/MainWin.cs
@@ -0,0 +1,206 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+/// <summary>
+/// 娓告垙涓荤晫闈�
+/// </summary>
+public class MainWin : UIBase
+{
+ private GameObject windowBackground;
+
+ // 搴曢儴鎸夐挳缁�
+ private Button[] bottomTabButtons;
+
+ // 褰撳墠閫変腑鐨勫簳閮ㄦ爣绛剧储寮�
+ private int currentTabIndex = 0;
+
+ // 褰撳墠鎵撳紑鐨勫瓙鐣岄潰
+ private UIBase currentSubUI;
+
+ /// <summary>
+ /// 鍒濆鍖栫粍浠�
+ /// </summary>
+ protected override void InitComponent()
+ {
+ base.InitComponent();
+
+ windowBackground = transform.Find("RawImgBackground").gameObject;
+
+ bottomTabButtons = new Button[5];
+
+ for (int i = 1; i <= 5; i++)
+ {
+ string buttonName = "Buttons/Button" + i;
+ bottomTabButtons[i-1] = transform.Find(buttonName).GetComponent<Button>();
+ }
+
+ // 鍒濆鍖朥I缁勪欢浜嬩欢
+ InitButtonEvents();
+ }
+
+ /// <summary>
+ /// 鍒濆鍖朥I缁勪欢浜嬩欢
+ /// </summary>
+ private void InitButtonEvents()
+ {
+ // 鍒濆鍖栧簳閮ㄦ寜閽�
+ for (int i = 0; i < bottomTabButtons.Length; i++)
+ {
+ int index = i; // 鎹曡幏绱㈠紩
+ bottomTabButtons[i].onClick.AddListener(() => {
+ OnBottomTabButtonClicked(index);
+ });
+ }
+ }
+
+ protected override void OnOpen()
+ {
+ base.OnOpen();
+
+ // 榛樿閫変腑绗竴涓爣绛�
+ SelectBottomTab(0);
+
+ // 鍒锋柊UI
+ Refresh();
+ }
+
+ public override void Refresh()
+ {
+ UpdatePlayerInfo();
+ UpdateCurrency();
+ }
+
+ /// <summary>
+ /// 鏇存柊鐜╁淇℃伅
+ /// </summary>
+ private void UpdatePlayerInfo()
+ {
+ // 浠庣帺瀹舵暟鎹腑鑾峰彇淇℃伅骞舵洿鏂癠I
+ // 渚嬪锛�
+ // playerNameText.text = PlayerData.Instance.Name;
+ // playerLevelText.text = "Lv." + PlayerData.Instance.Level;
+ // powerText.text = PlayerData.Instance.Power.ToString();
+ // expSlider.value = PlayerData.Instance.ExpRatio;
+ }
+
+ /// <summary>
+ /// 鏇存柊璐у竵淇℃伅
+ /// </summary>
+ private void UpdateCurrency()
+ {
+ // 浠庣帺瀹舵暟鎹腑鑾峰彇璐у竵淇℃伅骞舵洿鏂癠I
+ // 渚嬪锛�
+ // goldText.text = PlayerData.Instance.Gold.ToString();
+ // diamondText.text = PlayerData.Instance.Diamond.ToString();
+ // energyText.text = PlayerData.Instance.Energy + "/" + PlayerData.Instance.MaxEnergy;
+ }
+
+ /// <summary>
+ /// 搴曢儴鏍囩鎸夐挳鐐瑰嚮
+ /// </summary>
+ private void OnBottomTabButtonClicked(int index)
+ {
+ SelectBottomTab(index);
+ }
+
+ /// <summary>
+ /// 閫夋嫨搴曢儴鏍囩
+ /// </summary>
+ private void SelectBottomTab(int index)
+ {
+ // 濡傛灉鐐瑰嚮褰撳墠宸查�変腑鐨勬爣绛撅紝涓嶅仛澶勭悊
+ if (currentTabIndex == index && currentSubUI != null)
+ {
+ return;
+ }
+
+ // 鏇存柊褰撳墠閫変腑鐨勬爣绛剧储寮�
+ currentTabIndex = index;
+
+ // 鏇存柊鎸夐挳鐘舵��
+ UpdateButtonsState();
+
+ // 鍏抽棴褰撳墠鎵撳紑鐨勫瓙鐣岄潰
+ CloseCurrentSubUI();
+
+ // 鏍规嵁閫変腑鐨勬爣绛炬墦寮�瀵瑰簲鐨勭晫闈�
+ OpenSubUIByTabIndex(index);
+ }
+
+ /// <summary>
+ /// 鏇存柊鎸夐挳鐘舵��
+ /// </summary>
+ private void UpdateButtonsState()
+ {
+ // 閬嶅巻鎵�鏈夋寜閽紝璁剧疆閫変腑鐘舵��
+ for (int i = 0; i < bottomTabButtons.Length; i++)
+ {
+ // 杩欓噷鍙互鏍规嵁鏄惁閫変腑璁剧疆鎸夐挳鐨勮瑙夋晥鏋�
+ // 渚嬪锛氭敼鍙樺浘鐗囥�侀鑹茬瓑
+ // bottomTabButtons[i].GetComponent<Image>().color = (i == currentTabIndex) ? Color.blue : Color.white;
+
+ // 鎴栬�呮縺娲�/绂佺敤閫変腑鍥炬爣
+ bottomTabButtons[i].image.color = (i == currentTabIndex) ? Color.white : Color.gray;
+ }
+ }
+
+ /// <summary>
+ /// 鍏抽棴褰撳墠鎵撳紑鐨勫瓙鐣岄潰
+ /// </summary>
+ private void CloseCurrentSubUI()
+ {
+ if (currentSubUI != null)
+ {
+ // 鍏抽棴褰撳墠鐣岄潰
+ UIManager.Instance.CloseWindow(currentSubUI);
+ currentSubUI = null;
+ }
+ }
+
+ /// <summary>
+ /// 鏍规嵁鏍囩绱㈠紩鎵撳紑瀵瑰簲鐨勫瓙鐣岄潰
+ /// </summary>
+ private void OpenSubUIByTabIndex(int index)
+ {
+ Debug.Log("鎵撳紑瀛愮晫闈� : " + index);
+
+ // 涓诲煄 闃靛 鍚岀洘 绂忓埄 鍐掗櫓
+
+ //鏍规嵁绱㈠紩鎵撳紑涓嶅悓鐨勭晫闈�
+ switch (index)
+ {
+ case 0:
+ // 渚嬪锛氭墦寮�涓婚〉鐣岄潰
+ // currentSubUI = UIManager.Instance.OpenUI<HomeUI>();
+ Debug.Log("鎵撳紑涓诲煄鐣岄潰");
+ break;
+ case 1:
+ // 渚嬪锛氭墦寮�瑙掕壊鐣岄潰
+ // currentSubUI = UIManager.Instance.OpenUI<CharacterUI>();
+ Debug.Log("鎵撳紑闃靛鐣岄潰");
+ break;
+ case 2:
+ // 渚嬪锛氭墦寮�鑳屽寘鐣岄潰
+ // currentSubUI = UIManager.Instance.OpenUI<BagUI>();
+ Debug.Log("鎵撳紑鍚岀洘鐣岄潰");
+ break;
+ case 3:
+ // 渚嬪锛氭墦寮�浠诲姟鐣岄潰
+ // currentSubUI = UIManager.Instance.OpenUI<QuestUI>();
+ Debug.Log("鎵撳紑绂忓埄鐣岄潰");
+ break;
+ case 4:
+ // 渚嬪锛氭墦寮�璁剧疆鐣岄潰
+ currentSubUI = UIManager.Instance.OpenWindow<PlaceWin>();
+ Debug.Log("鎵撳紑鍐掗櫓鐣岄潰");
+
+ windowBackground.SetActive(false);
+ break;
+ default:
+ Debug.LogWarning("鏈煡鐨勬爣绛剧储寮�: " + index);
+ break;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Main/UI/Main/MainWin.cs.meta b/Main/UI/Main/MainWin.cs.meta
new file mode 100644
index 0000000..455e629
--- /dev/null
+++ b/Main/UI/Main/MainWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0b14b415a3ac64548a78d163d6cb7e33
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/UI/Place.meta b/Main/UI/Place.meta
new file mode 100644
index 0000000..29907a9
--- /dev/null
+++ b/Main/UI/Place.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 2a75dbf92ff839445b4bf6be823add40
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/UI/Place/PlaceWin.cs b/Main/UI/Place/PlaceWin.cs
new file mode 100644
index 0000000..a93134d
--- /dev/null
+++ b/Main/UI/Place/PlaceWin.cs
@@ -0,0 +1,62 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+/// <summary>
+/// 鍦烘櫙鐣岄潰
+/// </summary>
+public class PlaceWin : UIBase
+{
+ protected Button btnExplore;
+
+ // protected
+
+ /// <summary>
+ /// 鍒濆鍖栫粍浠�
+ /// </summary>
+ protected override void InitComponent()
+ {
+ base.InitComponent();
+
+ // 鍦ㄨ繖閲屽垵濮嬪寲缁勪欢
+ btnExplore = transform.Find("BtnExplore").GetComponent<Button>();
+ btnExplore.onClick.AddListener(OnExploreClick);
+ }
+
+
+ /// <summary>
+ /// 绐楀彛鎵撳紑鏃惰皟鐢�
+ /// </summary>
+ protected override void OnOpen()
+ {
+ base.OnOpen();
+
+ // 绐楀彛鎵撳紑鏃剁殑閫昏緫
+
+ }
+
+ /// <summary>
+ /// 绐楀彛鍏抽棴鏃惰皟鐢�
+ /// </summary>
+ protected override void OnClose()
+ {
+ base.OnClose();
+
+ // 绐楀彛鍏抽棴鏃剁殑閫昏緫
+
+ }
+
+ /// <summary>
+ /// 鍒锋柊鐣岄潰
+ /// </summary>
+ public override void Refresh()
+ {
+ // 鍒锋柊鐣岄潰鐨勯�昏緫
+ }
+
+ private void OnExploreClick()
+ {
+ // UIManager.Instance.OpenUI<ExploreWin>();
+ }
+}
diff --git a/Main/UI/Place/PlaceWin.cs.meta b/Main/UI/Place/PlaceWin.cs.meta
new file mode 100644
index 0000000..ad66f43
--- /dev/null
+++ b/Main/UI/Place/PlaceWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 846b941e24d55594fac435ba7031cfa9
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Main/UI/UIBase.cs b/Main/UI/UIBase.cs
index 84e3717..d2e6a02 100644
--- a/Main/UI/UIBase.cs
+++ b/Main/UI/UIBase.cs
@@ -1,7 +1,8 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
-using DG.Tweening; // DOTween 鎻掍欢寮曠敤
+using DG.Tweening;
+using UnityEngine.UI; // DOTween 鎻掍欢寮曠敤
public enum UILayer
{
@@ -23,41 +24,44 @@
SlideFromRight // 浠庡彸渚ф粦鍏�
}
+[RequireComponent(typeof(Canvas))]
+[RequireComponent(typeof(CanvasGroup))]
+[RequireComponent(typeof(CanvasScaler))]
public class UIBase : MonoBehaviour
{
#region 灞炴�у拰鍙橀噺
// UI鍩烘湰灞炴��
[SerializeField] public UILayer uiLayer = UILayer.Mid;
- [SerializeField] public string uiName;
+ [SerializeField][HideInInspector] public string uiName;
[SerializeField] public bool isMainUI = false;
-
+
// 鎸佷箙鍖栫浉鍏�
[SerializeField] public bool isPersistent = false;
- [SerializeField] public int maxIdleRounds = 20;
-
+ [SerializeField][HideInInspector] 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
-
+ [SerializeField] public UIAnimationType openAnimationType = UIAnimationType.None;
+ [SerializeField] public UIAnimationType closeAnimationType = UIAnimationType.None;
+ [SerializeField][HideInInspector] public float animationDuration = 0.3f;
+ [SerializeField][HideInInspector] 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;
@@ -71,10 +75,10 @@
{
// 纭繚 DOTween 宸插垵濮嬪寲
DOTween.SetTweensCapacity(500, 50);
-
+
// 鍦ˋwake涓繘琛屽熀鏈垵濮嬪寲
InitComponent();
-
+
// 淇濆瓨鍘熷鍊肩敤浜庡姩鐢�
if (rectTransform != null)
{
@@ -87,7 +91,7 @@
{
// 瀛愮被鍙互閲嶅啓姝ゆ柟娉曡繘琛岄澶栧垵濮嬪寲
}
-
+
protected virtual void OnDestroy()
{
// 纭繚鍔ㄧ敾琚纭竻鐞�
@@ -111,32 +115,25 @@
{
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
@@ -151,63 +148,61 @@
canvas.sortingOrder = order;
}
}
-
+
// 鎵撳紑UI
- public virtual void Open()
+ public virtual void HandleOpen()
{
// 濡傛灉姝e湪鎾斁鍔ㄧ敾锛屽厛鍋滄
StopCurrentAnimation();
-
+
gameObject.SetActive(true);
-
+ isActive = true;
+
// 鏍规嵁鍔ㄧ敾绫诲瀷鎾斁鎵撳紑鍔ㄧ敾
PlayOpenAnimation();
-
- isActive = true;
+
OnOpen();
+
}
-
+
// 鍏抽棴UI
- public virtual void Close()
+ public virtual void HandleClose()
{
// 濡傛灉姝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();
- }
- }
+ gameObject.SetActive(false);
+ isActive = false;
}
-
+
+ public void CloseWindow()
+ {
+ UIManager.Instance.CloseWindow(this);
+ }
+
// 鍒锋柊UI
public virtual void Refresh()
{
// 瀛愮被鍙互閲嶅啓姝ゆ柟娉曞疄鐜癠I鍒锋柊閫昏緫
}
-
+
// 閿�姣乁I
public virtual void Destroy()
{
// 鍋滄鎵�鏈夊姩鐢�
StopCurrentAnimation();
-
+
ClearChildrenUI();
-
+
if (parentUI != null)
{
parentUI.RemoveChildUI(this);
}
-
+
Destroy(gameObject);
}
@@ -225,7 +220,7 @@
}
isAnimating = false;
}
-
+
// 鎾斁鎵撳紑鍔ㄧ敾
protected virtual void PlayOpenAnimation()
{
@@ -240,9 +235,9 @@
}
return;
}
-
+
isAnimating = true;
-
+
// 鍒濆鍖栧姩鐢诲墠鐨勭姸鎬�
switch (openAnimationType)
{
@@ -254,7 +249,7 @@
canvasGroup.blocksRaycasts = false;
}
break;
-
+
case UIAnimationType.ScaleInOut:
if (rectTransform != null)
{
@@ -267,7 +262,7 @@
canvasGroup.blocksRaycasts = false;
}
break;
-
+
case UIAnimationType.SlideFromTop:
if (rectTransform != null)
{
@@ -282,7 +277,7 @@
canvasGroup.blocksRaycasts = false;
}
break;
-
+
case UIAnimationType.SlideFromBottom:
if (rectTransform != null)
{
@@ -297,7 +292,7 @@
canvasGroup.blocksRaycasts = false;
}
break;
-
+
case UIAnimationType.SlideFromLeft:
if (rectTransform != null)
{
@@ -312,7 +307,7 @@
canvasGroup.blocksRaycasts = false;
}
break;
-
+
case UIAnimationType.SlideFromRight:
if (rectTransform != null)
{
@@ -328,12 +323,12 @@
}
break;
}
-
+
try
{
// 鍒涘缓鍔ㄧ敾搴忓垪
currentAnimation = DOTween.Sequence();
-
+
// 娣诲姞鍔ㄧ敾
switch (openAnimationType)
{
@@ -343,7 +338,7 @@
currentAnimation.Append(canvasGroup.DOFade(1f, animationDuration).SetEase(animationEase));
}
break;
-
+
case UIAnimationType.ScaleInOut:
if (rectTransform != null)
{
@@ -354,7 +349,7 @@
currentAnimation.Join(canvasGroup.DOFade(1f, animationDuration).SetEase(animationEase));
}
break;
-
+
case UIAnimationType.SlideFromTop:
case UIAnimationType.SlideFromBottom:
case UIAnimationType.SlideFromLeft:
@@ -369,11 +364,12 @@
}
break;
}
-
+
// 鍔ㄧ敾瀹屾垚鍚庣殑鍥炶皟
- currentAnimation.OnComplete(() => {
+ currentAnimation.OnComplete(() =>
+ {
isAnimating = false;
-
+
// 鍚敤浜や簰
if (canvasGroup != null)
{
@@ -385,7 +381,7 @@
catch (System.Exception e)
{
Debug.LogError($"鎾斁鎵撳紑鍔ㄧ敾鏃跺嚭閿�: {e.Message}");
-
+
// 鍑洪敊鏃剁‘淇漊I鍙骞跺彲浜や簰
if (canvasGroup != null)
{
@@ -396,7 +392,7 @@
isAnimating = false;
}
}
-
+
// 鎾斁鍏抽棴鍔ㄧ敾
protected virtual void PlayCloseAnimation()
{
@@ -411,21 +407,21 @@
}
return;
}
-
+
isAnimating = true;
-
+
// 绂佺敤浜や簰锛屼絾淇濇寔鍙
if (canvasGroup != null)
{
canvasGroup.interactable = false;
canvasGroup.blocksRaycasts = false;
}
-
+
try
{
// 鍒涘缓鍔ㄧ敾搴忓垪
currentAnimation = DOTween.Sequence();
-
+
// 娣诲姞鍔ㄧ敾
switch (closeAnimationType)
{
@@ -435,7 +431,7 @@
currentAnimation.Append(canvasGroup.DOFade(0f, animationDuration).SetEase(animationEase));
}
break;
-
+
case UIAnimationType.ScaleInOut:
if (rectTransform != null)
{
@@ -446,7 +442,7 @@
currentAnimation.Join(canvasGroup.DOFade(0f, animationDuration).SetEase(animationEase));
}
break;
-
+
case UIAnimationType.SlideFromTop:
if (rectTransform != null)
{
@@ -459,7 +455,7 @@
currentAnimation.Join(canvasGroup.DOFade(0f, animationDuration).SetEase(animationEase));
}
break;
-
+
case UIAnimationType.SlideFromBottom:
if (rectTransform != null)
{
@@ -472,7 +468,7 @@
currentAnimation.Join(canvasGroup.DOFade(0f, animationDuration).SetEase(animationEase));
}
break;
-
+
case UIAnimationType.SlideFromLeft:
if (rectTransform != null)
{
@@ -485,7 +481,7 @@
currentAnimation.Join(canvasGroup.DOFade(0f, animationDuration).SetEase(animationEase));
}
break;
-
+
case UIAnimationType.SlideFromRight:
if (rectTransform != null)
{
@@ -499,11 +495,12 @@
}
break;
}
-
+
// 鍔ㄧ敾瀹屾垚鍚庣殑鍥炶皟
- currentAnimation.OnComplete(() => {
+ currentAnimation.OnComplete(() =>
+ {
isAnimating = false;
-
+
// 纭繚UI涓嶅彲瑙佷笖涓嶅彲浜や簰
if (canvasGroup != null)
{
@@ -511,7 +508,7 @@
canvasGroup.interactable = false;
canvasGroup.blocksRaycasts = false;
}
-
+
// 寤惰繜绂佺敤GameObject锛岄伩鍏嶉绻佺殑Enable/Disable鎿嶄綔
// 濡傛灉闇�瑕佺珛鍗抽噴鏀捐祫婧愶紝鍙互鍙栨秷娉ㄩ噴涓嬮潰鐨勪唬鐮�
// gameObject.SetActive(false);
@@ -520,7 +517,7 @@
catch (System.Exception e)
{
Debug.LogError($"鎾斁鍏抽棴鍔ㄧ敾鏃跺嚭閿�: {e.Message}");
-
+
// 鍑洪敊鏃剁‘淇漊I涓嶅彲瑙佷笖涓嶅彲浜や簰
if (canvasGroup != null)
{
@@ -531,7 +528,7 @@
isAnimating = false;
}
}
-
+
#endregion
#region 瀛怳I绠$悊
@@ -545,7 +542,7 @@
childUI.parentUI = this;
}
}
-
+
// 绉婚櫎瀛怳I
public void RemoveChildUI(UIBase childUI)
{
@@ -555,7 +552,7 @@
childUI.parentUI = null;
}
}
-
+
// 娓呯┖鎵�鏈夊瓙UI
public void ClearChildrenUI()
{
@@ -566,7 +563,7 @@
childrenUI[i].parentUI = null;
}
}
-
+
childrenUI.Clear();
}
@@ -579,7 +576,7 @@
{
// 瀛愮被鍙互閲嶅啓姝ゆ柟娉曞疄鐜版墦寮�UI鏃剁殑閫昏緫
}
-
+
// UI鍏抽棴鏃剁殑鍥炶皟
protected virtual void OnClose()
{
diff --git a/Main/UI/UIManager.cs b/Main/UI/UIManager.cs
index 56abadf..297144b 100644
--- a/Main/UI/UIManager.cs
+++ b/Main/UI/UIManager.cs
@@ -38,7 +38,7 @@
#region 鍒濆鍖栨柟娉�
// 鍒濆鍖�
- private void Init()
+ public void Init()
{
InitUIRoot();
}
@@ -46,7 +46,18 @@
// 鍒涘缓UI鏍硅妭鐐�
private void InitUIRoot()
{
- GameObject root = GameObject.Instantiate(Resources.Load<GameObject>("UIRoot"));
+ GameObject root = GameObject.Find("UIRoot");
+ if (root == null)
+ {
+ root = GameObject.Instantiate(Resources.Load<GameObject>("UI/UIRoot"));
+
+ if (root == null)
+ {
+ Debug.LogError("鏃犳硶鎵惧埌UI鏍硅妭鐐�");
+ return;
+ }
+ }
+
uiRoot = root.transform;
uiRoot.position = Vector3.zero;
@@ -118,20 +129,21 @@
}
// 鑾峰彇UI瀹炰緥锛屽鏋滀笉瀛樺湪鍒欒繑鍥瀗ull
- private UIBase GetUI(string uiName)
+ public T GetUI<T>() where T : UIBase
{
+ string uiName = typeof(T).Name;
if (string.IsNullOrEmpty(uiName))
{
Debug.LogError("UI鍚嶇О涓虹┖");
return null;
}
-
+
UIBase ui;
if (uiDict.TryGetValue(uiName, out ui))
{
- return ui;
+ return ui as T;
}
-
+
return null;
}
@@ -171,16 +183,10 @@
#region UI璧勬簮绠$悊
// 鍔犺浇UI棰勫埗浣�
- private UIBase LoadUIResource(string uiName)
+ private T LoadUIResource<T>(string uiName) where T : UIBase
+
{
- // 杩欓噷鏄祫婧愬姞杞介儴鍒嗭紝鏍规嵁椤圭洰瀹為檯鎯呭喌瀹炵幇
- // 鍙互浣跨敤Resources.Load鎴栬�呭叾浠栬祫婧愮鐞嗙郴缁�
-
- // 绀轰緥浠g爜锛屽疄闄呴」鐩腑闇�瑕佹浛鎹负鐪熷疄鐨勮祫婧愬姞杞介�昏緫
- GameObject prefab = null;
-
- // TODO: 鍦ㄨ繖閲屽疄鐜拌祫婧愬姞杞介�昏緫
- // prefab = Resources.Load<GameObject>("UI/" + uiName);
+ GameObject prefab = ResManager.Instance.LoadUI(uiName);
if (prefab == null)
{
@@ -189,7 +195,8 @@
}
GameObject uiObject = GameObject.Instantiate(prefab);
- UIBase uiBase = uiObject.GetComponent<UIBase>();
+ uiObject.name = uiName;
+ T uiBase = uiObject.GetComponent<T>();
if (uiBase == null)
{
@@ -202,8 +209,6 @@
// 璁剧疆鐖惰妭鐐逛负UI鏍硅妭鐐�
uiObject.transform.SetParent(GetTransForLayer(uiBase.uiLayer), false);
- // 鍒濆鍖朥I
- uiBase.Init();
// 璁剧疆鎺掑簭椤哄簭
int baseSortingOrder = GetBaseSortingOrderForLayer(uiBase.uiLayer);
@@ -296,8 +301,9 @@
#region 鍏叡鎺ュ彛鏂规硶
// 鎵撳紑鍗曚釜UI绐楀彛
- public UIBase OpenWindow(string uiName)
+ public T OpenWindow<T>() where T : UIBase
{
+ string uiName = typeof(T).Name;
if (string.IsNullOrEmpty(uiName))
{
Debug.LogError("灏濊瘯鎵撳紑绌哄悕绉扮殑UI绐楀彛");
@@ -308,12 +314,12 @@
currentRound++;
// 鍏堝皾璇曡幏鍙栧凡鍔犺浇鐨刄I
- UIBase ui = GetUI(uiName);
+ T ui = GetUI<T>();
// 濡傛灉UI涓嶅瓨鍦紝鍒欏姞杞�
if (ui == null)
{
- ui = LoadUIResource(uiName);
+ ui = LoadUIResource<T>(uiName);
if (ui == null)
return null;
@@ -370,7 +376,7 @@
}
// 鍏抽棴褰撳墠UI閾句笂鐨勯潪System灞俇I
- topUI.Close();
+ topUI.HandleClose();
// 娓呯悊鐖跺瓙鍏崇郴
if (topUI.parentUI != null)
@@ -389,7 +395,7 @@
}
}
- ui.Open();
+ ui.HandleOpen();
// 濡傛灉鏍堜腑鏈夊叾浠朥I锛屽垯灏嗘爤椤禪I璁句负鐖禪I
if (!ui.isMainUI && ui.uiLayer != UILayer.System && uiStack.Count > 0)
@@ -449,8 +455,10 @@
return;
// 鍒涘缓涓�涓垪琛ㄦ潵瀛樺偍闇�瑕佸叧闂殑UI
- List<UIBase> uisToClose = new List<UIBase>();
- uisToClose.Add(ui);
+ List<UIBase> uisToClose = new List<UIBase>
+ {
+ ui
+ };
// 閫掑綊鏀堕泦鎵�鏈夊瓙UI
CollectChildrenUI(ui, uisToClose);
@@ -465,7 +473,7 @@
foreach (var uiToClose in uisToClose)
{
// 鍏抽棴UI
- uiToClose.Close();
+ uiToClose.HandleClose();
// 娓呯悊鐖跺瓙鍏崇郴
if (uiToClose.parentUI != null)
@@ -486,19 +494,6 @@
RemoveFromUIStack(uisToClose);
}
- // 鍏抽棴鎵�鏈塙I绐楀彛
- public void CloseAllWindows()
- {
- foreach (var ui in uiDict.Values)
- {
- if (ui != null)
- {
- ui.Close();
- }
- }
-
- uiStack.Clear();
- }
// 杩斿洖涓婁竴绾I
public void GoBack()
@@ -508,7 +503,8 @@
// 鍏抽棴褰撳墠UI
UIBase currentUI = uiStack.Pop();
- currentUI.Close();
+
+ CloseWindow(currentUI);
// 鏇存柊鎺掑簭椤哄簭
UpdateUISortingOrder();
@@ -545,7 +541,9 @@
// 閿�姣佹墍鏈塙I
public void DestroyAllUI()
{
- foreach (var ui in uiDict.Values)
+ List<string> uiNames = new List<string>(uiDict.Keys);
+
+ foreach (var ui in uiNames)
{
if (ui != null)
{
diff --git a/Utility/DontDestroyOnLoad.cs b/Utility/DontDestroyOnLoad.cs
new file mode 100644
index 0000000..7f3489e
--- /dev/null
+++ b/Utility/DontDestroyOnLoad.cs
@@ -0,0 +1,11 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class DontDestroyOnLoad : MonoBehaviour
+{
+ void Awake()
+ {
+ DontDestroyOnLoad(gameObject);
+ }
+}
diff --git a/Utility/DontDestroyOnLoad.cs.meta b/Utility/DontDestroyOnLoad.cs.meta
new file mode 100644
index 0000000..d8483e0
--- /dev/null
+++ b/Utility/DontDestroyOnLoad.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ebddc3e48e1baa844a56615981c5c152
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
--
Gitblit v1.8.0