Files
Cielonos/Assets/Scripts/MainGame/Items/Data/ComboData.cs
SoulliesOfficial ef7b479712 initial
2025-11-25 08:19:33 -05:00

177 lines
5.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Linq;
using Sirenix.OdinInspector;
using UnityEngine;
namespace Cielonos.MainGame.Inventory
{
/// <summary>
/// 存储连招树定义的 ScriptableObject。
/// 这是你的“蓝图”资产。
/// </summary>
[CreateAssetMenu(fileName = "ComboData", menuName = "Cielonos/Items/ComboData")]
public class ComboData : ScriptableObject
{
public float defaultDisappearTime;
[InlineProperty] [HideLabel] public ComboTreeData tree;
[OnInspectorInit]
private void OnEnable()
{
defaultDisappearTime = 0.25f;
tree ??= new ComboTreeData();
// 确保总有一个 RootNode
if (tree.nodes == null || tree.nodes.Count == 0)
{
tree.nodes = new List<ComboNodeData>();
// 添加不可删除的 RootNode
tree.nodes.Add(new ComboNodeData() { referenceName = "Root" });
}
// 关键一步:将树实例传递给所有子节点,以便它们能填充下拉列表
tree.InitializeNodeReferences();
}
}
/// <summary>
/// 连招树的数据容器
/// </summary>
[Serializable]
public class ComboTreeData
{
// --- 修改点 ---
// 将标题移到这里,使其在内联属性的顶部显示
[Title("连招树编辑器", "可视化编辑连招树的节点和分支")]
// --- 修改结束 ---
[ListDrawerSettings(
DraggableItems = true, // 现在可以安全地拖动排序了!
NumberOfItemsPerPage = 20,
CustomAddFunction = "AddNode",
CustomRemoveElementFunction = "RemoveNode")]
public List<ComboNodeData> nodes;
/// <summary>
/// Odin Inspector 自定义添加按钮的实现
/// </summary>
private void AddNode()
{
// 查找一个唯一的默认名称
int counter = nodes.Count - 1;
string newName = counter.ToString();
while (nodes.Any(n => n.referenceName == newName))
{
counter++;
newName = counter.ToString();
}
var newNode = new ComboNodeData() { referenceName = newName };
nodes.Add(newNode);
// 添加后,立即初始化引用
InitializeNodeReferences();
}
/// <summary>
/// Odin Inspector 自定义移除按钮的实现
/// </summary>
private void RemoveNode(ComboNodeData node)
{
// 规则:不可删除 RootNode
if (node.referenceName == "Root")
{
Debug.LogWarning("不能删除 Root 节点。");
return;
}
nodes.Remove(node);
InitializeNodeReferences(); // 移除后,更新引用
}
/// <summary>
/// 将父树实例传递给所有节点和分支用于Odin下拉列表
/// </summary>
public void InitializeNodeReferences()
{
if (nodes == null) return;
}
/// <summary>
/// 帮助 Odin 下拉列表获取所有可用节点名称
/// </summary>
public IEnumerable<string> GetNodeReferenceNames()
{
if (nodes == null) return Enumerable.Empty<string>();
return nodes.Select(n => n.referenceName).Where(n => !string.IsNullOrEmpty(n));
}
public ComboSubmodule.ComboTree ToRuntime()
{
var runtimeTree = new ComboSubmodule.ComboTree();
runtimeTree.nodes = new List<ComboSubmodule.ComboTree.Node>();
// 创建运行时节点
foreach (var nodeData in nodes)
{
var runtimeNode = new ComboSubmodule.ComboTree.Node(nodes.IndexOf(nodeData), nodeData.referenceName);
runtimeNode.branches = new List<ComboSubmodule.ComboTree.Branch>();
// 创建运行时分支
foreach (var branchData in nodeData.branches)
{
var runtimeBranch = new ComboSubmodule.ComboTree.Branch(nodes.FindIndex(n => n.referenceName == branchData.nextNodeRefName), branchData.operation);
runtimeNode.branches.Add(runtimeBranch);
}
runtimeTree.nodes.Add(runtimeNode);
}
return runtimeTree;
}
}
/// <summary>
/// 连招节点的数据定义
/// </summary>
[Serializable]
public class ComboNodeData
{
[ValidateInput("ValidateReferenceName", "引用名称(Reference Name)必须唯一且不能为空。")]
[InfoBox("这是 Root 节点,是所有连招的起点。", InfoMessageType.Info, "IsRootNode")]
public string referenceName;
[ListDrawerSettings(NumberOfItemsPerPage = 5)]
public List<ComboBranchData> branches = new List<ComboBranchData>();
private bool IsRootNode() => referenceName == "Root";
private bool ValidateReferenceName(string name, ref string errorMessage)
{
if (string.IsNullOrEmpty(name))
{
errorMessage = "引用名称不能为空。";
return false;
}
return true;
}
}
/// <summary>
/// 连招分支的数据定义
/// </summary>
[Serializable]
public class ComboBranchData
{
[Tooltip("触发此分支的输入操作,例如 'L', 'R', 'Attack'")] [HorizontalGroup("Branch", 100)] [LabelWidth(60)]
public string operation;
[Tooltip("此分支链接到的下一个节点")]
[HorizontalGroup("Branch")]
[LabelText("下一个节点")]
public string nextNodeRefName; // <-- 使用名称引用,而不是索引
// --- Odin 辅助字段和方法 ---
}
}