From e5ed968d12958644bfbf3a9891e7522f4edcf8fc Mon Sep 17 00:00:00 2001 From: m0_75251201 Date: Mon, 14 Jul 2025 11:39:31 +0800 Subject: [PATCH 1/5] =?UTF-8?q?(client)=20chore:=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E5=86=85=E8=81=94=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Client/Assets/Scripts/Data/DefinePack.cs | 43 +++++++++++++++++++----- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/Client/Assets/Scripts/Data/DefinePack.cs b/Client/Assets/Scripts/Data/DefinePack.cs index a626b75..25e39cb 100644 --- a/Client/Assets/Scripts/Data/DefinePack.cs +++ b/Client/Assets/Scripts/Data/DefinePack.cs @@ -6,6 +6,7 @@ using System.Text; using System.Xml.Linq; using Configs; using UnityEngine; +using Object = System.Object; namespace Data { @@ -141,7 +142,7 @@ namespace Data if (string.IsNullOrEmpty(className)) continue; // Debug.Log("1"); - var def = LoadDefineClass(element); + var def = LoadDefineClass(element,element.Name.ToString()); if (def == null) continue; // Debug.Log("2"); @@ -152,9 +153,8 @@ namespace Data } } - private Define LoadDefineClass(XElement defineDoc) + private Define LoadDefineClass(XElement defineDoc,string className) { - var className = defineDoc.Name.ToString(); var assembly = Assembly.GetExecutingAssembly(); Type type; @@ -206,8 +206,14 @@ namespace Data } if (define.Init(defineDoc)) return define; - // 获取类的所有字段(不包括私有字段) - var fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic); + DefaultInitDefine(define,defineDoc, type); + + return define; + } + + public void DefaultInitDefine(Define define,XElement defineDoc,Type defineType) + { + var fields = defineType.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic); // 遍历字段并尝试从 XElement 中赋值 foreach (var field in fields) @@ -217,8 +223,11 @@ namespace Data if (element != null) try { - // 将子元素的值转换为目标类型并赋值 - var value = Convert.ChangeType(element.Value, field.FieldType); + Object value; + if (IsFieldTypeInheritedFrom(field, typeof(Define))) + value = LoadDefineClass(element, field.FieldType.Name); + else + value = Convert.ChangeType(element.Value, field.FieldType); field.SetValue(define, value); } catch (Exception ex) @@ -226,8 +235,6 @@ namespace Data Debug.LogWarning($"Error setting field {field.Name}: {ex.Message}"); } } - - return define; } /// @@ -278,5 +285,23 @@ namespace Data return sb.ToString(); } + + /// + /// 检查字段的类型是否继承自指定的类 + /// + /// 字段信息 + /// 要检查的基类类型 + /// 如果字段的类型是基类或其派生类,则返回 true + public static bool IsFieldTypeInheritedFrom(FieldInfo field, Type baseType) + { + // 获取字段的类型 + var fieldType = field.FieldType; + // 如果字段的类型为 null 或不是基类的派生类,则返回 false + if (!baseType.IsAssignableFrom(fieldType)) + return false; + + // 如果字段的类型直接是基类或其派生类,则返回 true + return fieldType != baseType && baseType.IsAssignableFrom(fieldType); + } } } \ No newline at end of file From 7234b7b57dacc4100325928d08c61f1426513b7d Mon Sep 17 00:00:00 2001 From: m0_75251201 Date: Mon, 14 Jul 2025 11:40:08 +0800 Subject: [PATCH 2/5] =?UTF-8?q?(client)=20feat:=E6=B7=BB=E5=8A=A0=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E5=8A=A0=E8=BD=BD=E7=9B=B8=E5=85=B3=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Client/Assets/Scripts/Data/CharacterDefine.cs | 108 ++++++++++++++++-- 1 file changed, 97 insertions(+), 11 deletions(-) diff --git a/Client/Assets/Scripts/Data/CharacterDefine.cs b/Client/Assets/Scripts/Data/CharacterDefine.cs index c80679d..82ecd12 100644 --- a/Client/Assets/Scripts/Data/CharacterDefine.cs +++ b/Client/Assets/Scripts/Data/CharacterDefine.cs @@ -1,48 +1,134 @@ +using System; using System.Collections.Generic; +using System.Text.RegularExpressions; using System.Xml.Linq; +using UnityEngine; namespace Data { + public enum Orientation + { + Down, + Left, + Right, + Up + } + + public enum DrawNodeType + { + Image, + Animation + } + public class CharacterDef : Define { + public string texturePath = null; public DrawingOrderDef drawingOrder_down, drawingOrder_up, drawingOrder_left, drawingOrder_right; + + public DrawingOrderDef GetDrawingOrder(Orientation orientation) + { + // 定义一个临时变量用于存储结果 + DrawingOrderDef result = null; + + // 根据传入的 Orientation 获取对应的 DrawingOrderDef + switch (orientation) + { + case Orientation.Down: + result = drawingOrder_down; + break; + case Orientation.Up: + result = drawingOrder_up; + break; + case Orientation.Left: + result = drawingOrder_left; + break; + case Orientation.Right: + result = drawingOrder_right; + break; + default: + throw new ArgumentException("Invalid orientation value."); + } + + // 如果当前方向的结果为空,则尝试用 drawingOrder_down 填充 + if (result == null) result = drawingOrder_down; + + // 如果 drawingOrder_down 仍然为空,则尝试用其他非空方向填充 + if (result == null) result = drawingOrder_up ?? drawingOrder_left ?? drawingOrder_right; + + return result; + } } public class DrawingOrderDef : Define { - public List DrawNodes { get; set; } = new List(); + public List drawNodes = new(); public override bool Init(XElement xmlDef) { base.Init(xmlDef); - foreach (var node in xmlDef.Elements("DrawNodes")) + foreach (var node in xmlDef.Elements("DrawNodeDef")) { - DrawNodeDef drawNode = new DrawNodeDef(); + var drawNode = new DrawNodeDef(); drawNode.Init(node); - DrawNodes.Add(drawNode); + drawNodes.Add(drawNode); } + return true; } } - public partial class DrawNodeDef : Define + + public class DrawNodeDef : Define { - public string NodeName { get; set; } - public List Children { get; set; } = new(); + public List children = new(); + public DrawNodeType drawNodeType = DrawNodeType.Image; + public string nodeName; + public Vector2 position = new(0, 0); + public float FPS = 1; + public override bool Init(XElement xmlDef) { base.Init(xmlDef); - NodeName = xmlDef.Attribute("name")?.Value; - foreach (var childNode in xmlDef.Elements("DrawNode")) + + nodeName = xmlDef.Attribute("name")?.Value; + drawNodeType = Enum.TryParse(xmlDef.Attribute("type")?.Value, true, out DrawNodeType typeResult) + ? typeResult + : DrawNodeType.Image; + + position = StringToVector(xmlDef.Attribute("position")?.Value ?? "(0 0)"); + FPS = float.TryParse(xmlDef.Attribute("FPS")?.Value, out float result) ? result : 1.0f; + foreach (var childNode in xmlDef.Elements("DrawNodeDef")) { - DrawNodeDef child = new DrawNodeDef(); + var child = new DrawNodeDef(); child.Init(childNode); - Children.Add(child); + children.Add(child); } return true; } + public Vector2 StringToVector(string vectorDef) + { + // 去掉可能存在的括号和多余的空格 + string cleanedInput = vectorDef.Replace("(", "").Replace(")", "").Trim(); + + // 使用正则表达式匹配两个浮点数 + Match match = Regex.Match(cleanedInput, @"\s*(-?\d+(\.\d*)?)\s*[, ]\s*(-?\d+(\.\d*)?)\s*"); + + if (match.Success) + { + // 提取匹配到的两个浮点数 + float x = float.Parse(match.Groups[1].Value); + float y = float.Parse(match.Groups[3].Value); + + // 返回 Vector2 对象 + return new Vector2(x, y); + } + else + { + return Vector2.zero; + } + } } } \ No newline at end of file From 1eeb91c3bb7a1e4ef7c380eef9331aca5b37f193 Mon Sep 17 00:00:00 2001 From: m0_75251201 Date: Mon, 14 Jul 2025 11:40:55 +0800 Subject: [PATCH 3/5] =?UTF-8?q?(client)=20feat:=E6=B7=BB=E5=8A=A0=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E7=9A=84=E7=B1=BB=E5=9E=8B=E5=90=8D=E7=A7=B0=E9=93=BE?= =?UTF-8?q?=E6=8E=A5=E7=B4=A2=E5=BC=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Assets/Scripts/Managers/DefineManager.cs | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/Client/Assets/Scripts/Managers/DefineManager.cs b/Client/Assets/Scripts/Managers/DefineManager.cs index 776a6f9..bdd79a2 100644 --- a/Client/Assets/Scripts/Managers/DefineManager.cs +++ b/Client/Assets/Scripts/Managers/DefineManager.cs @@ -21,8 +21,39 @@ namespace Managers var pack = new DefinePack(); if (pack.LoadPack(folder)) packs.Add(pack.packID, pack); } - } + foreach (var pack in packs) + { + foreach (var define in pack.Value.defines) + { + var typeName=define.Key; + var defList=define.Value; + if (!defines.ContainsKey(typeName)) + defines[typeName] = new Dictionary(); + foreach (var def in defList) + { + defines[typeName][def.defName] = def; + } + } + } + } + /// + /// 查找指定定义类型的定义名对应的 Define 对象。 + /// + /// 定义类型 + /// 定义名 + /// 如果找到,返回 Define 对象;否则返回 null。 + public Define FindDefine(string defineType, string defineName) + { + if (defines.TryGetValue(defineType, out var typeDict)) + { + if (typeDict.TryGetValue(defineName, out var define)) + { + return define; + } + } + return null; + } public override string ToString() { if (packs == null || packs.Count == 0) From 5aaf13e169d72f03050717729965f58c62625566 Mon Sep 17 00:00:00 2001 From: m0_75251201 Date: Mon, 14 Jul 2025 11:41:31 +0800 Subject: [PATCH 4/5] =?UTF-8?q?(client)=20chore:=E5=B0=86=E7=A4=BA?= =?UTF-8?q?=E4=BE=8B=E5=AE=9A=E4=B9=89=E9=80=82=E9=85=8D=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Client/Data/Core/Define/Player/CatGirl.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Client/Data/Core/Define/Player/CatGirl.xml b/Client/Data/Core/Define/Player/CatGirl.xml index 4f56ae6..22e2f8c 100644 --- a/Client/Data/Core/Define/Player/CatGirl.xml +++ b/Client/Data/Core/Define/Player/CatGirl.xml @@ -24,7 +24,7 @@ - + @@ -32,4 +32,5 @@ + \ No newline at end of file From a07c4a2bc15e8126318b62bc015bc0d835be914d Mon Sep 17 00:00:00 2001 From: m0_75251201 Date: Mon, 14 Jul 2025 11:42:02 +0800 Subject: [PATCH 5/5] =?UTF-8?q?(client)=20feat:=E5=AE=9E=E7=8E=B0=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E7=94=9F=E6=88=90=E6=B8=B2=E6=9F=93=E6=A0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Client/Assets/Scenes/Test.unity | 17 +++- Client/Assets/Scripts/Entity/Character.cs | 96 +++++++++++++++++++ .../Assets/Scripts/Entity/Character.cs.meta | 2 + Client/Assets/Scripts/Test/TestDefine.cs | 2 +- 4 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 Client/Assets/Scripts/Entity/Character.cs create mode 100644 Client/Assets/Scripts/Entity/Character.cs.meta diff --git a/Client/Assets/Scenes/Test.unity b/Client/Assets/Scenes/Test.unity index bcfa585..cdafdf0 100644 --- a/Client/Assets/Scenes/Test.unity +++ b/Client/Assets/Scenes/Test.unity @@ -479,6 +479,7 @@ Transform: serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: -10} + m_LocalPosition: {x: 0, y: 0, z: -10} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] @@ -660,8 +661,9 @@ GameObject: serializedVersion: 6 m_Component: - component: {fileID: 1485465861} + - component: {fileID: 1485465862} m_Layer: 0 - m_Name: CatGirl + m_Name: Character m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -682,6 +684,18 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1485465862 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1485465860} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 757576bb4354ac54da09868e1be02eec, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!1660057539 &9223372036854775807 SceneRoots: m_ObjectHideFlags: 0 @@ -691,3 +705,4 @@ SceneRoots: - {fileID: 613797070} - {fileID: 912467178} - {fileID: 1485465861} + - {fileID: 1485465861} diff --git a/Client/Assets/Scripts/Entity/Character.cs b/Client/Assets/Scripts/Entity/Character.cs new file mode 100644 index 0000000..51dd66f --- /dev/null +++ b/Client/Assets/Scripts/Entity/Character.cs @@ -0,0 +1,96 @@ +using System; +using System.Linq; +using Data; +using UnityEngine; + +namespace Entity +{ + public class Character : MonoBehaviour + { + private void Start() + { + if (Managers.DefineManager.Instance.defines.TryGetValue("DrawingOrderDef",out var typeDict)) + { + GenerateDrawNode(typeDict.Values?.FirstOrDefault()as DrawingOrderDef); + } + } + + public void Init(CharacterDef def) + { + + if (def == null) + return; + GenerateDrawNode(def.GetDrawingOrder(Orientation.Down)); + } + + // 生成图片或动画节点 + private void GenerateDrawNode(DrawingOrderDef def) + { + // Debug.Log(def); + // 删除现有子节点 + DeleteAllChildren(); + + // 生成根节点下的所有节点 + foreach (var nodeDef in def.drawNodes) GenerateNode(nodeDef, transform); // 在当前节点下生成 + } + + // 递归生成节点 + private void GenerateNode(DrawNodeDef nodeDef, Transform parent) + { + // Debug.Log(nodeDef.nodeName); + // 创建新的 GameObject 表示节点 + var nodeObject = new GameObject(nodeDef.nodeName); + + // 设置父节点 + nodeObject.transform.SetParent(parent, false); + + // 根据节点类型生成不同的内容 + switch (nodeDef.drawNodeType) + { + case DrawNodeType.Image: + CreateImageNode(nodeObject); + break; + + case DrawNodeType.Animation: + CreateAnimationNode(nodeObject); + break; + + default: + Debug.LogWarning($"Unsupported node type: {nodeDef.drawNodeType}"); + break; + } + + // 递归生成子节点 + if (nodeDef.children != null && nodeDef.children.Count > 0) + foreach (var childNodeDef in nodeDef.children) + GenerateNode(childNodeDef, nodeObject.transform); // 在当前节点下生成子节点 + } + + // 创建图片节点 + private void CreateImageNode(GameObject nodeObject) + { + // 添加 SpriteRenderer 组件表示图片 + var spriteRenderer = nodeObject.AddComponent(); + spriteRenderer.sprite = Resources.Load("DefaultImage"); // 加载默认图片 + spriteRenderer.color = Color.white; // 设置默认颜色 + } + + // 创建动画节点 + private void CreateAnimationNode(GameObject nodeObject) + { + // 添加 Animator 组件表示动画 + var animator = nodeObject.AddComponent(); + animator.runtimeAnimatorController = + Resources.Load("DefaultAnimation"); // 加载默认动画控制器 + } + + private void DeleteAllChildren() + { + // 获取当前对象的 Transform + var parentTransform = transform; + + // 删除所有子对象 + foreach (Transform child in parentTransform) Destroy(child.gameObject); // 使用 Destroy 方法删除子对象 + } + } +} \ No newline at end of file diff --git a/Client/Assets/Scripts/Entity/Character.cs.meta b/Client/Assets/Scripts/Entity/Character.cs.meta new file mode 100644 index 0000000..20578c1 --- /dev/null +++ b/Client/Assets/Scripts/Entity/Character.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 757576bb4354ac54da09868e1be02eec \ No newline at end of file diff --git a/Client/Assets/Scripts/Test/TestDefine.cs b/Client/Assets/Scripts/Test/TestDefine.cs index d3730f4..1f9b464 100644 --- a/Client/Assets/Scripts/Test/TestDefine.cs +++ b/Client/Assets/Scripts/Test/TestDefine.cs @@ -7,7 +7,7 @@ namespace Test public class TestDefine : MonoBehaviour { // Start is called once before the first execution of Update after the MonoBehaviour is created - void Start() + void Awake() { Managers.DefineManager.Instance.Init(); Debug.Log(Managers.DefineManager.Instance);