我死去
目前添加了一个能够深度查找和设置反射的helper,但是Tag的系统仍然不完全,另外我觉得console可以重构了 Signed-off-by: TRAfoer <lhf190@outlook.com>
This commit is contained in:
@@ -113,21 +113,19 @@ namespace Ichni.RhythmGame
|
||||
}
|
||||
namespace Ichni.Editor
|
||||
{
|
||||
public class TagManager : IBaseElement//这玩意大概不需要分BM的
|
||||
public class TagManager : IBaseElement
|
||||
{
|
||||
// ... (你的原有代码: matchedBM, 构造函数等保持不变) ...
|
||||
public BaseElement_BM matchedBM { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
public List<TagMatcher> tagMatchers;
|
||||
|
||||
public TagManager()
|
||||
{
|
||||
tagMatchers = new List<TagMatcher>();
|
||||
tempTagMatcherName = "";
|
||||
tempElementTypeName = "";
|
||||
tempParameterName = "";
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
// ... (Add/Remove 方法保持不变) ...
|
||||
public void AddTagMatcher(string name, Type elementType, string parameterName)
|
||||
{
|
||||
//check
|
||||
@@ -161,51 +159,53 @@ namespace Ichni.Editor
|
||||
{
|
||||
RemoveTagMatcher(tagMatchers.First(i => i.name == o));
|
||||
}
|
||||
// ... 其他 Add/Remove ...
|
||||
|
||||
public List<IBaseElement> GetMachedElements(TagMatcher o)
|
||||
{
|
||||
return EditorManager.instance.beatmapContainer.gameElementList
|
||||
.Where(p => o.Match(p)).Cast<IBaseElement>().ToList();
|
||||
.Where(p => o.Match(p)).Cast<IBaseElement>().ToList();
|
||||
}
|
||||
|
||||
public List<TagMatcher> GetMatcher(GameElement baseElement)
|
||||
{
|
||||
return tagMatchers.Where(p => p.Match(baseElement)).ToList();
|
||||
|
||||
}
|
||||
|
||||
// --- 修改 1: 使用 ReflectionHelper 设置值 ---
|
||||
public void SetMatchedElements(TagMatcher o, object value)
|
||||
{
|
||||
foreach (var i in GetMachedElements(o))
|
||||
{
|
||||
// 直接调用修改后的 SetValue
|
||||
o.SetValue(i, value);
|
||||
}
|
||||
}
|
||||
|
||||
// --- 修改 2: 使用 ReflectionHelper 同步值 ---
|
||||
public void SyncTagedElement(GameElement gameElement)
|
||||
{
|
||||
foreach (var matcher in GetMatcher(gameElement))
|
||||
{
|
||||
var matchedElements = GetMachedElements(matcher);
|
||||
|
||||
// A. 获取源值 (使用 ReflectionHelper 以支持嵌套路径,如 "transform.position")
|
||||
var value = ReflectionHelper.GetDeepValue(gameElement, matcher.parameterName);
|
||||
|
||||
foreach (var element in matchedElements)
|
||||
{
|
||||
var value = gameElement.GetType().GetField(matcher.parameterName).GetValue(gameElement);
|
||||
// B. 设置目标值 (TagMatcher 内部现在使用 ReflectionHelper)
|
||||
matcher.SetValue(element, value);
|
||||
element.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public string tempTagMatcherName = "";
|
||||
public string tempElementTypeName = "";
|
||||
public string tempParameterName = "";
|
||||
public void SetUpInspector()
|
||||
internal void SetUpInspector()
|
||||
{
|
||||
tempTagMatcherName = "";
|
||||
tempElementTypeName = "";
|
||||
tempParameterName = "";
|
||||
// tempTagMatcherName = "";
|
||||
// tempElementTypeName = "";
|
||||
// tempParameterName = "";
|
||||
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
|
||||
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
|
||||
var container = inspector.GenerateContainer("Tag Manager");
|
||||
@@ -217,7 +217,11 @@ namespace Ichni.Editor
|
||||
var sub = container.GenerateSubcontainer(2);
|
||||
inspector.GenerateHintText(this, sub, $"Name: {matcher.name}");
|
||||
inspector.GenerateHintText(this, sub, $"Type: {matcher.ElementType?.Name ?? "<null>"}");
|
||||
inspector.GenerateHintText(this, sub, $"Param: {matcher.parameterName}");
|
||||
var e = inspector.GenerateInputField(sub, "Parameter", matcher.parameterName);
|
||||
e.AddListenerFunction(() =>
|
||||
{
|
||||
matcher.parameterName = e.inputField.text;
|
||||
});
|
||||
inspector.GenerateButton(this, sub, "Remove", () =>
|
||||
{
|
||||
RemoveTagMatcher(matcher);
|
||||
@@ -225,86 +229,96 @@ namespace Ichni.Editor
|
||||
});
|
||||
}
|
||||
|
||||
// 新增TagMatcher区域
|
||||
var addSub = container.GenerateSubcontainer(3);
|
||||
// 输入Tag名称
|
||||
var nameInput = inspector.GenerateInputField(this, addSub, "Tag Name", nameof(tempTagMatcherName));
|
||||
// 下拉选择类型
|
||||
List<Type> typeList = TypeHelper.GetInheritedTypes<GameElement>();
|
||||
List<string> typeNames = typeList.ConvertAll(t => t.FullName);
|
||||
var typeDropdown = inspector.GenerateDropdown(this, addSub, "Element Type", typeNames, nameof(tempElementTypeName))
|
||||
.AddListenerFunction(() =>
|
||||
{
|
||||
// 选择类型后刷新参数下拉
|
||||
Type selectedType = typeList.FirstOrDefault(t => t.FullName == tempElementTypeName);
|
||||
List<string> paramNames = selectedType != null
|
||||
? selectedType.GetFields().Select(f => f.Name).ToList()
|
||||
: new List<string>();
|
||||
//inspector.GenerateDropdown(this, addSub, "Parameter", paramNames, nameof(tempParameterName));
|
||||
});
|
||||
// // 新增TagMatcher区域
|
||||
// var addSub = container.GenerateSubcontainer(3);
|
||||
// // 输入Tag名称
|
||||
// var nameInput = inspector.GenerateInputField(this, addSub, "Tag Name", nameof(tempTagMatcherName));
|
||||
// // 下拉选择类型
|
||||
// List<Type> typeList = TypeHelper.GetInheritedTypes<GameElement>();
|
||||
// List<string> typeNames = typeList.ConvertAll(t => t.FullName);
|
||||
// var typeDropdown = inspector.GenerateDropdown(this, addSub, "Element Type", typeNames, nameof(tempElementTypeName))
|
||||
// .AddListenerFunction(() =>
|
||||
// {
|
||||
// // 选择类型后刷新参数下拉
|
||||
// Type selectedType = typeList.FirstOrDefault(t => t.FullName == tempElementTypeName);
|
||||
// List<string> paramNames = selectedType != null
|
||||
// ? selectedType.GetFields().Select(f => f.Name).ToList()
|
||||
// : new List<string>();
|
||||
// //inspector.GenerateDropdown(this, addSub, "Parameter", paramNames, nameof(tempParameterName));
|
||||
// });
|
||||
|
||||
// 参数下拉(初始为空,随类型变化刷新)
|
||||
if (!string.IsNullOrEmpty(tempElementTypeName))
|
||||
{
|
||||
Type selectedType = typeList.FirstOrDefault(t => t.FullName == tempElementTypeName);
|
||||
List<string> paramNames = selectedType != null
|
||||
? selectedType.GetFields().Select(f => f.Name).ToList()
|
||||
: new List<string>();
|
||||
inspector.GenerateDropdown(this, addSub, "Parameter", paramNames, nameof(tempParameterName));
|
||||
}
|
||||
else
|
||||
{
|
||||
inspector.GenerateDropdown(this, addSub, "Parameter", new List<string>(), nameof(tempParameterName));
|
||||
}
|
||||
// if (!string.IsNullOrEmpty(tempElementTypeName))
|
||||
// {
|
||||
// Type selectedType = typeList.FirstOrDefault(t => t.FullName == tempElementTypeName);
|
||||
// List<string> paramNames = selectedType != null
|
||||
// ? selectedType.GetFields().Select(f => f.Name).ToList()
|
||||
// : new List<string>();
|
||||
// inspector.GenerateDropdown(this, addSub, "Parameter", paramNames, nameof(tempParameterName));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// inspector.GenerateDropdown(this, addSub, "Parameter", new List<string>(), nameof(tempParameterName));
|
||||
// }
|
||||
|
||||
// 添加按钮
|
||||
var addButton = inspector.GenerateButton(this, addSub, "Add TagMatcher", () =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(tempTagMatcherName) || string.IsNullOrEmpty(tempElementTypeName) || string.IsNullOrEmpty(tempParameterName))
|
||||
{
|
||||
Debug.LogWarning("请填写完整信息再添加TagMatcher。");
|
||||
return;
|
||||
}
|
||||
if (tagMatchers.Any(t => t.name == tempTagMatcherName))
|
||||
{
|
||||
Debug.LogWarning("TagMatcher's name is repeated!");
|
||||
return;
|
||||
}
|
||||
Type selectedType = typeList.FirstOrDefault(t => t.FullName == tempElementTypeName);
|
||||
TagMatcher matcher = new TagMatcher
|
||||
{
|
||||
name = tempTagMatcherName,
|
||||
ElementType = selectedType,
|
||||
parameterName = tempParameterName
|
||||
};
|
||||
AddTagMatcher(matcher);
|
||||
inspectorMain.SetInspector(EditorManager.instance.projectInformation);
|
||||
});
|
||||
// // 添加按钮
|
||||
// var addButton = inspector.GenerateButton(this, addSub, "Add TagMatcher", () =>
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(tempTagMatcherName) || string.IsNullOrEmpty(tempElementTypeName) || string.IsNullOrEmpty(tempParameterName))
|
||||
// {
|
||||
// Debug.LogWarning("请填写完整信息再添加TagMatcher。");
|
||||
// return;
|
||||
// }
|
||||
// if (tagMatchers.Any(t => t.name == tempTagMatcherName))
|
||||
// {
|
||||
// Debug.LogWarning("TagMatcher's name is repeated!");
|
||||
// return;
|
||||
// }
|
||||
// Type selectedType = typeList.FirstOrDefault(t => t.FullName == tempElementTypeName);
|
||||
// TagMatcher matcher = new TagMatcher
|
||||
// {
|
||||
// name = tempTagMatcherName,
|
||||
// ElementType = selectedType,
|
||||
// parameterName = tempParameterName
|
||||
// };
|
||||
// AddTagMatcher(matcher);
|
||||
// inspectorMain.SetInspector(EditorManager.instance.projectInformation);
|
||||
// });
|
||||
|
||||
// 按需禁用添加按钮
|
||||
if (string.IsNullOrEmpty(tempTagMatcherName) || string.IsNullOrEmpty(tempElementTypeName) || string.IsNullOrEmpty(tempParameterName))
|
||||
{
|
||||
addButton.button.interactable = false;
|
||||
}
|
||||
// // 按需禁用添加按钮
|
||||
// if (string.IsNullOrEmpty(tempTagMatcherName) || string.IsNullOrEmpty(tempElementTypeName) || string.IsNullOrEmpty(tempParameterName))
|
||||
// {
|
||||
// addButton.button.interactable = false;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ... (Inspector 变量保持不变) ...
|
||||
|
||||
public struct TagMatcher
|
||||
{
|
||||
public string name;
|
||||
public Type ElementType;
|
||||
public string parameterName;
|
||||
public string parameterName; // 现在可以填 "transform.position.x" 这种路径了
|
||||
|
||||
public readonly bool Match(GameElement gameElement)
|
||||
{
|
||||
string o = name;
|
||||
return gameElement.tags.Any(i => i == o);
|
||||
// 注意:这里建议加空检查,防止 gameElement.tags 为 null
|
||||
return gameElement.tags != null && gameElement.tags.Any(i => i == o);
|
||||
}
|
||||
|
||||
// --- 修改 3: TagMatcher 内部逻辑更新 ---
|
||||
public readonly void SetValue(IBaseElement baseElement, object value)
|
||||
{
|
||||
if (ElementType != baseElement.GetType()) return;
|
||||
ElementType.GetField(parameterName).SetValue(baseElement, value);
|
||||
// 原有逻辑:严格检查类型
|
||||
// if (ElementType != baseElement.GetType()) return;
|
||||
|
||||
// 新逻辑建议:
|
||||
// 1. 既然是用 Tag 匹配,不同类可能有相同的字段名 (鸭子类型),去掉严格类型检查可能更灵活。
|
||||
// 2. 如果必须检查,保留上面那行。
|
||||
|
||||
// 使用 ReflectionHelper 处理赋值 (自动处理 Struct 回写和嵌套)
|
||||
ReflectionHelper.SetDeepValue(baseElement, parameterName, value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -83,6 +83,13 @@ namespace Ichni.RhythmGame
|
||||
new List<string>(), true, this, 1000f));
|
||||
|
||||
}
|
||||
public override void OnDelete()
|
||||
{
|
||||
if (cameraManager.gameCamera == this)
|
||||
{
|
||||
cameraManager.SwitchCamera();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public partial class GameCamera
|
||||
|
||||
Reference in New Issue
Block a user