(client) fix:修复DefineManager没有解析数组类型的Define字段导致定义查找失败
This commit is contained in:
@ -686,7 +686,7 @@ MonoBehaviour:
|
|||||||
isGlobal: 1
|
isGlobal: 1
|
||||||
entityLevel: {fileID: 309861628}
|
entityLevel: {fileID: 309861628}
|
||||||
entityPrefab: {fileID: 3332598847335032684, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
entityPrefab: {fileID: 3332598847335032684, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||||
defaultEntityPrefab: {fileID: 0}
|
defaultEntityPrefab: {fileID: 7975757421877276383, guid: 89661daa5f100c64783f0ad9cd37a7ff, type: 3}
|
||||||
--- !u!114 &2036983434
|
--- !u!114 &2036983434
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -87,7 +87,7 @@ namespace Data
|
|||||||
|
|
||||||
position = StringToVector(xmlDef.Attribute("position")?.Value ?? "(0 0)");
|
position = StringToVector(xmlDef.Attribute("position")?.Value ?? "(0 0)");
|
||||||
FPS = float.TryParse(xmlDef.Attribute("FPS")?.Value, out float result) ? result : 1.0f;
|
FPS = float.TryParse(xmlDef.Attribute("FPS")?.Value, out float result) ? result : 1.0f;
|
||||||
foreach (var childNode in xmlDef.Elements("DrawNodeDef"))
|
foreach (var childNode in xmlDef.Elements())
|
||||||
{
|
{
|
||||||
var child = new DrawNodeDef();
|
var child = new DrawNodeDef();
|
||||||
child.Init(childNode);
|
child.Init(childNode);
|
||||||
|
@ -53,7 +53,6 @@ namespace Entity
|
|||||||
aiTree = ConvertToAIBase(pawnDef.behaviorTree);
|
aiTree = ConvertToAIBase(pawnDef.behaviorTree);
|
||||||
affiliation = pawnDef.affiliation;
|
affiliation = pawnDef.affiliation;
|
||||||
InitBody(pawnDef.drawingOrder);
|
InitBody(pawnDef.drawingOrder);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void InitBody(DrawingOrderDef drawingOrder)
|
public virtual void InitBody(DrawingOrderDef drawingOrder)
|
||||||
@ -71,8 +70,7 @@ namespace Entity
|
|||||||
if (drawNode == null) continue;
|
if (drawNode == null) continue;
|
||||||
var directionRoot = new GameObject(orientation.ToString());
|
var directionRoot = new GameObject(orientation.ToString());
|
||||||
directionRoot.transform.SetParent(body.transform, false);
|
directionRoot.transform.SetParent(body.transform, false);
|
||||||
|
InitBodyPart(drawNode, directionRoot,drawingOrder.texturePath);
|
||||||
InitBodyPart(drawNode, directionRoot);
|
|
||||||
bodyNodes[orientation] = directionRoot;
|
bodyNodes[orientation] = directionRoot;
|
||||||
}
|
}
|
||||||
currentOrientation = Orientation.Down;
|
currentOrientation = Orientation.Down;
|
||||||
@ -85,15 +83,27 @@ namespace Entity
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 递归初始化单个绘图节点及其子节点
|
// 递归初始化单个绘图节点及其子节点
|
||||||
public virtual void InitBodyPart(DrawNodeDef drawNode, GameObject parent)
|
public virtual void InitBodyPart(DrawNodeDef drawNode, GameObject parent,string folderPath)
|
||||||
{
|
{
|
||||||
if(drawNode==null) return;
|
if(drawNode==null) return;
|
||||||
|
|
||||||
GameObject nodeObject;
|
GameObject nodeObject;
|
||||||
|
if (drawNode.nodeName == "noName")
|
||||||
|
{
|
||||||
|
nodeObject = new();
|
||||||
|
nodeObject.transform.SetParent(parent.transform);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
switch (drawNode.drawNodeType)
|
switch (drawNode.drawNodeType)
|
||||||
{
|
{
|
||||||
case DrawNodeType.Image:
|
case DrawNodeType.Image:
|
||||||
nodeObject = Instantiate(imagePrefab.gameObject, parent.transform);
|
nodeObject = Instantiate(imagePrefab.gameObject, parent.transform);
|
||||||
|
var texture =
|
||||||
|
Managers.PackagesImageManager.Instance.FindBodyTextures(drawNode.packID, folderPath,
|
||||||
|
$"{drawNode.nodeName}_{currentOrientation}");
|
||||||
|
var image = nodeObject.GetComponent<ImagePrefab>();
|
||||||
|
image.SetSprite(texture[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DrawNodeType.Animation:
|
case DrawNodeType.Animation:
|
||||||
@ -101,15 +111,22 @@ namespace Entity
|
|||||||
ITick tick = nodeObject.GetComponent<SpriteAnimator>();
|
ITick tick = nodeObject.GetComponent<SpriteAnimator>();
|
||||||
if (tick != null)
|
if (tick != null)
|
||||||
bodyAnimationNode[currentOrientation].Add(tick);
|
bodyAnimationNode[currentOrientation].Add(tick);
|
||||||
|
var textures = Managers.PackagesImageManager.Instance.FindBodyTextures(drawNode.packID,
|
||||||
|
folderPath,
|
||||||
|
$"{drawNode.nodeName}_{currentOrientation}");
|
||||||
|
var animator = nodeObject.GetComponent<SpriteAnimator>();
|
||||||
|
animator.SetSprites(textures);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
nodeObject.transform.localPosition = drawNode.position;
|
nodeObject.transform.localPosition = drawNode.position;
|
||||||
|
nodeObject.name = drawNode.nodeName;
|
||||||
// 递归初始化子节点
|
// 递归初始化子节点
|
||||||
foreach (var child in drawNode.children)
|
foreach (var child in drawNode.children)
|
||||||
{
|
{
|
||||||
InitBodyPart(child, nodeObject);
|
InitBodyPart(child, nodeObject,folderPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void Tick()
|
public void Tick()
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -51,28 +52,37 @@ namespace Managers
|
|||||||
|
|
||||||
string currentPackID = string.Empty;
|
string currentPackID = string.Empty;
|
||||||
|
|
||||||
|
|
||||||
void ProcessDefine(Define def)
|
void ProcessDefine(Define def)
|
||||||
{
|
{
|
||||||
if (def == null || def.isReferene)
|
if (def == null || def.isReferene)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
def.packID = currentPackID;
|
def.packID = currentPackID;
|
||||||
|
|
||||||
// 如果字段信息已经缓存,则直接使用缓存
|
// 如果字段信息已经缓存,则直接使用缓存
|
||||||
if (!fieldCache.TryGetValue(def.GetType(), out var defineFields))
|
if (!fieldCache.TryGetValue(def.GetType(), out var defineFields))
|
||||||
{
|
{
|
||||||
// 获取所有字段类型为 Define 或其派生类型的字段
|
// 获取所有字段类型为 Define 或其派生类型的字段
|
||||||
defineFields = def.GetType()
|
defineFields = def.GetType()
|
||||||
.GetFields(BindingFlags.Public | BindingFlags.Instance)
|
.GetFields(BindingFlags.Public | BindingFlags.Instance)
|
||||||
.Where(field => typeof(Define).IsAssignableFrom(field.FieldType))
|
.ToArray(); // 不再过滤,先获取所有字段
|
||||||
.ToArray();
|
|
||||||
// 缓存字段信息
|
// 缓存字段信息
|
||||||
fieldCache[def.GetType()] = defineFields;
|
fieldCache[def.GetType()] = defineFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var defineField in defineFields)
|
foreach (var defineField in defineFields)
|
||||||
|
{
|
||||||
|
var fieldType = defineField.FieldType;
|
||||||
|
|
||||||
|
// 处理单个 Define 类型的字段
|
||||||
|
if (typeof(Define).IsAssignableFrom(fieldType))
|
||||||
{
|
{
|
||||||
var defRef = (Define)defineField.GetValue(def);
|
var defRef = (Define)defineField.GetValue(def);
|
||||||
if (defRef == null)
|
if (defRef == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (defRef.isReferene)
|
if (defRef.isReferene)
|
||||||
{
|
{
|
||||||
defineCache.Add(new Tuple<Define, FieldInfo, Define>(def, defineField, defRef));
|
defineCache.Add(new Tuple<Define, FieldInfo, Define>(def, defineField, defRef));
|
||||||
@ -89,8 +99,46 @@ namespace Managers
|
|||||||
ProcessDefine(defRef);
|
ProcessDefine(defRef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 处理集合类型字段
|
||||||
|
else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(List<>))
|
||||||
|
{
|
||||||
|
var elementType = fieldType.GenericTypeArguments[0];
|
||||||
|
if (typeof(Define).IsAssignableFrom(elementType))
|
||||||
|
{
|
||||||
|
var list = (IList)defineField.GetValue(def);
|
||||||
|
if (list != null)
|
||||||
|
{
|
||||||
|
foreach (var item in list)
|
||||||
|
{
|
||||||
|
if (item is Define defItem && !defItem.isReferene)
|
||||||
|
{
|
||||||
|
ProcessDefine(defItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 处理数组类型字段
|
||||||
|
else if (fieldType.IsArray)
|
||||||
|
{
|
||||||
|
var elementType = fieldType.GetElementType();
|
||||||
|
if (typeof(Define).IsAssignableFrom(elementType))
|
||||||
|
{
|
||||||
|
var array = (Array)defineField.GetValue(def);
|
||||||
|
if (array != null)
|
||||||
|
{
|
||||||
|
foreach (var item in array)
|
||||||
|
{
|
||||||
|
if (item is Define defItem && !defItem.isReferene)
|
||||||
|
{
|
||||||
|
ProcessDefine(defItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var pack in packs)
|
foreach (var pack in packs)
|
||||||
{
|
{
|
||||||
currentPackID = pack.Value.packID;
|
currentPackID = pack.Value.packID;
|
||||||
@ -381,3 +429,4 @@ namespace Managers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ namespace Managers
|
|||||||
catch (System.Exception ex)
|
catch (System.Exception ex)
|
||||||
{
|
{
|
||||||
// 捕获并记录任何异常
|
// 捕获并记录任何异常
|
||||||
Debug.LogError($"An error occurred while generating the entity: {ex.Message}");
|
Debug.LogError($"An error occurred while generating the entity: {ex.Message}\nStack Trace: {ex.StackTrace}");
|
||||||
GenerateDefaultEntity(pos);
|
GenerateDefaultEntity(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using Data;
|
using Data;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@ -15,7 +16,7 @@ namespace Managers
|
|||||||
//包名,图片名
|
//包名,图片名
|
||||||
public Dictionary<string, Dictionary<string, Sprite>> sprites = new();
|
public Dictionary<string, Dictionary<string, Sprite>> sprites = new();
|
||||||
//包名,文件路径,身体部件名
|
//包名,文件路径,身体部件名
|
||||||
public Dictionary<string, Dictionary<string, Dictionary<string, List<Sprite>>>> bodyTexture = new();
|
public Dictionary<string, Dictionary<string, Dictionary<string, Sprite>>> bodyTexture = new();
|
||||||
|
|
||||||
public void Init()
|
public void Init()
|
||||||
{
|
{
|
||||||
@ -83,7 +84,8 @@ namespace Managers
|
|||||||
new Vector2(0.5f, 0.5f) // 中心点
|
new Vector2(0.5f, 0.5f) // 中心点
|
||||||
);
|
);
|
||||||
var name=Path.GetFileNameWithoutExtension(path);
|
var name=Path.GetFileNameWithoutExtension(path);
|
||||||
InsertBodySprite(drawOrder.packID, drawOrder.texturePath, name, spr);
|
InsertBodyTexture(drawOrder.packID, drawOrder.texturePath, name, spr);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,7 +117,7 @@ namespace Managers
|
|||||||
if (!sprites.ContainsKey(packId))
|
if (!sprites.ContainsKey(packId))
|
||||||
sprites[packId] = new Dictionary<string, Sprite>();
|
sprites[packId] = new Dictionary<string, Sprite>();
|
||||||
|
|
||||||
Rect spriteRect = new Rect(0, 0, textureWidth, textureHeight);
|
var spriteRect = new Rect(0, 0, textureWidth, textureHeight);
|
||||||
var sprite = Sprite.Create(texture, spriteRect, new Vector2(0.5f, 0.5f), pixelsPerUnit);
|
var sprite = Sprite.Create(texture, spriteRect, new Vector2(0.5f, 0.5f), pixelsPerUnit);
|
||||||
sprites[packId][baseName] = sprite;
|
sprites[packId][baseName] = sprite;
|
||||||
return;
|
return;
|
||||||
@ -180,34 +182,95 @@ namespace Managers
|
|||||||
return GetSprite(packID, fullName);
|
return GetSprite(packID, fullName);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 插入 Sprite 到指定的嵌套字典中。
|
/// 向 bodyTexture 插入一张 Sprite。
|
||||||
|
/// 如果包名、路径或部件名原本不存在,会自动建立对应的 Dictionary。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="packageName">包名。</param>
|
/// <param name="packageName">包名</param>
|
||||||
/// <param name="filePath">文件路径。</param>
|
/// <param name="filePath">文件路径</param>
|
||||||
/// <param name="bodyPartName">身体部件名。</param>
|
/// <param name="bodyPartName">身体部件名</param>
|
||||||
/// <param name="sprite">要插入的 Sprite 对象。</param>
|
/// <param name="sprite">要插入的 Sprite</param>
|
||||||
public void InsertBodySprite(string packageName, string filePath, string bodyPartName, Sprite sprite)
|
public void InsertBodyTexture(string packageName,
|
||||||
|
string filePath,
|
||||||
|
string bodyPartName,
|
||||||
|
Sprite sprite)
|
||||||
{
|
{
|
||||||
// 确保第一层字典(包名)存在
|
if (sprite == null)
|
||||||
if (!bodyTexture.ContainsKey(packageName))
|
|
||||||
{
|
{
|
||||||
bodyTexture[packageName] = new Dictionary<string, Dictionary<string, List<Sprite>>>();
|
Debug.LogWarning("InsertBodyTexture: sprite 为 null,已忽略。");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 确保第二层字典(文件路径)存在
|
// 1) 处理包名层级
|
||||||
if (!bodyTexture[packageName].ContainsKey(filePath))
|
if (!bodyTexture.TryGetValue(packageName, out var pathDict))
|
||||||
{
|
{
|
||||||
bodyTexture[packageName][filePath] = new Dictionary<string, List<Sprite>>();
|
pathDict = new Dictionary<string, Dictionary<string, Sprite>>();
|
||||||
|
bodyTexture[packageName] = pathDict;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 确保第三层字典(身体部件名)存在
|
// 2) 处理文件路径层级
|
||||||
if (!bodyTexture[packageName][filePath].ContainsKey(bodyPartName))
|
if (!pathDict.TryGetValue(filePath, out var partDict))
|
||||||
{
|
{
|
||||||
bodyTexture[packageName][filePath][bodyPartName] = new List<Sprite>();
|
partDict = new Dictionary<string, Sprite>();
|
||||||
|
pathDict[filePath] = partDict;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将 Sprite 添加到列表中
|
// 3) 插入或覆盖部件名
|
||||||
bodyTexture[packageName][filePath][bodyPartName].Add(sprite);
|
partDict[bodyPartName] = sprite;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 查找身体部件的所有Sprite变体(支持带编号的图片)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="packageName">包名</param>
|
||||||
|
/// <param name="filePath">文件路径</param>
|
||||||
|
/// <param name="bodyPartName">身体部件名</param>
|
||||||
|
/// <returns>按编号排序的Sprite数组,未找到时返回空数组</returns>
|
||||||
|
public Sprite[] FindBodyTextures(string packageName, string filePath, string bodyPartName)
|
||||||
|
{
|
||||||
|
// 检查包名是否存在
|
||||||
|
if (!bodyTexture.TryGetValue(packageName, out var packageDict))
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"Package '{packageName}' not found.");
|
||||||
|
return Array.Empty<Sprite>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查文件路径是否存在
|
||||||
|
if (!packageDict.TryGetValue(filePath, out var pathDict))
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"File path '{filePath}' not found in package '{packageName}'.");
|
||||||
|
return Array.Empty<Sprite>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 收集所有匹配的Sprite
|
||||||
|
var sprites = new List<(int order, Sprite sprite)>();
|
||||||
|
|
||||||
|
// 查找完全匹配的项(无编号)
|
||||||
|
if (pathDict.TryGetValue(bodyPartName, out var baseSprite))
|
||||||
|
{
|
||||||
|
sprites.Add((0, baseSprite));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查找带编号的变体
|
||||||
|
var prefix = bodyPartName + "_";
|
||||||
|
foreach (var (key, value) in pathDict)
|
||||||
|
{
|
||||||
|
// 检查是否以部件名+下划线开头
|
||||||
|
if (key.StartsWith(prefix) && key.Length > prefix.Length)
|
||||||
|
{
|
||||||
|
var suffix = key.Substring(prefix.Length);
|
||||||
|
|
||||||
|
// 尝试解析编号
|
||||||
|
if (int.TryParse(suffix, out var number))
|
||||||
|
{
|
||||||
|
sprites.Add((number, Value: value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按编号排序(无编号视为0)
|
||||||
|
return sprites
|
||||||
|
.OrderBy(x => x.order)
|
||||||
|
.Select(x => x.sprite)
|
||||||
|
.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
File diff suppressed because one or more lines are too long
@ -14,9 +14,9 @@
|
|||||||
<attributes>TestCharacter</attributes>
|
<attributes>TestCharacter</attributes>
|
||||||
<affiliation>player</affiliation>
|
<affiliation>player</affiliation>
|
||||||
<drawingOrder>
|
<drawingOrder>
|
||||||
<texturePath>Resources/Character/CatGirl</texturePath>
|
<texturePath>Resources\Character\Test</texturePath>
|
||||||
<drawingOrder_down>
|
<drawingOrder_down>
|
||||||
<node name="body"/>
|
<node name="Body"/>
|
||||||
</drawingOrder_down>
|
</drawingOrder_down>
|
||||||
</drawingOrder>
|
</drawingOrder>
|
||||||
<behaviorTree>
|
<behaviorTree>
|
||||||
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
Reference in New Issue
Block a user