Files
ichni_Creator_Studio/Assets/Scripts/EditorGame/GameElements/GameElement.cs

285 lines
8.8 KiB
C#
Raw Normal View History

using System;
using System.Collections;
using System.Collections.Generic;
using Dreamteck.Splines;
2025-02-09 23:47:42 -05:00
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
using Sirenix.OdinInspector;
using Unity.VisualScripting;
using UnityEngine;
2025-02-11 22:58:56 -05:00
using UnityEngine.UI;
using UnityEngine.UIElements;
2025-02-12 18:46:46 -05:00
using Inspector = Ichni.Editor.Inspector;
namespace Ichni.RhythmGame
{
public abstract partial class GameElement : SerializedMonoBehaviour, IBaseElement, IComparable<GameElement>
{
//物体名
public string elementName;
//标识 GUID
public Guid elementGuid;
//标签
public List<string> tags;
//父游戏物体
public GameElement parentElement;
2025-02-09 23:47:42 -05:00
//与游戏物体连接的Tab
public HierarchyTab connectedTab;
//子物体列表
public List<GameElement> childElementList = new List<GameElement>();
//次级模块
public List<SubmoduleBase> submoduleList = new List<SubmoduleBase>();
//存档类
public BaseElement_BM matchedBM { get; set; }
public virtual int HierarchyPriority => 0;
/// <summary>
/// 首次初始化
/// </summary>
/// <param name="name">物体名</param>
public virtual void Initialize(string name, Guid elementGuid, List<string> tags,
2025-02-09 23:47:42 -05:00
bool isFirstGenerated, GameElement parentElement)
{
this.elementName = name;
this.elementGuid = elementGuid;
this.tags = tags;
2025-02-08 23:09:50 -05:00
EditorManager.instance.beatmapContainer.gameElementList.Add(this);
submoduleList = new List<SubmoduleBase>();
2025-04-16 08:33:34 -04:00
if (isFirstGenerated)
{
SetDefaultSubmodules();
}
2025-02-09 23:47:42 -05:00
SetParent(parentElement);
EditorManager.instance.uiManager.hierarchy.GenerateTab(this, parentElement);
2025-02-19 09:15:51 -05:00
//GameManager.beatMapContainer.beatMapElementList.Add(this);
//serialNumber = totalSerialNumber++;
//SetTransformObserver();
}
/// <summary>
/// 设置次级模块
/// </summary>
2025-03-16 01:35:05 -04:00
public virtual void SetDefaultSubmodules()
2025-02-17 14:46:14 -05:00
{
2025-02-17 14:46:14 -05:00
}
2025-04-16 08:33:34 -04:00
public virtual void SetEditorSubmodules()
{
}
/// <summary>
/// 在所有物体生成完毕后,执行的初始化方法
/// </summary>
public virtual void AfterInitialize()
{
2025-04-16 08:33:34 -04:00
SetEditorSubmodules();
}
/// <summary>
/// 设置父物体
/// </summary>
/// <param name="parentElement">父物体</param>
public void SetParent(GameElement parentElement)
{
if (parentElement != null)
{
parentElement.childElementList.Add(this);
this.parentElement = parentElement;
transform.SetParent(parentElement.transform);
}
}
public int CompareTo(GameElement other)
{
return HierarchyPriority.CompareTo(other.HierarchyPriority);
}
}
public abstract partial class GameElement //存档,删除,复制,粘贴
{
2025-02-12 18:46:46 -05:00
public virtual void Refresh()
{
if (connectedTab != null) connectedTab.tabButtonText.text = this.elementName;
2025-02-12 18:46:46 -05:00
}
/// <summary>
/// 用于生成存档
/// </summary>
public virtual void SaveBM()
{
throw new NotImplementedException();
}
/// <summary>
/// 当物体被删除时执行的方法
/// </summary>
public virtual void OnDelete()
{
}
/// <summary>
/// 删除物体,包括所有子物体
/// </summary>
public virtual void Delete()
{
2025-02-19 19:01:21 -05:00
if (childElementList is { Count: > 0 })
{
for (int i = 0; i < childElementList.Count; i++)
{
childElementList[i].Delete(); //删除子GameElement、
}
}
OnDelete();
2025-02-19 19:06:26 -05:00
//LogWindow.Log("Deleted element: " + elementName);
2025-02-08 23:09:50 -05:00
EditorManager.instance.beatmapContainer.gameElementList.Remove(this); //从保存列表中剔除
2025-02-19 19:01:21 -05:00
if (connectedTab != null)
{
Destroy(connectedTab.gameObject);
}
Destroy(gameObject); //销毁
}
}
2025-02-11 22:58:56 -05:00
public abstract partial class GameElement
{
public virtual void SetUpInspector() //被点击时设置第一层Inspector
2025-02-11 22:58:56 -05:00
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Element Info");
2025-04-14 17:49:47 -04:00
//基础信息
var info = container.GenerateSubcontainer(3);
var nameInputField = inspector.GenerateInputField(this, info, GetType().Name + "'s Name", nameof(elementName));
var guidText = inspector.GenerateParameterText(this, info, "Element GUID", nameof(elementGuid));
var tagsListButton = inspector.GenerateButton(this, info, "Tags List", () =>
{
2025-02-13 14:26:37 -05:00
inspector.GenerateCompositeParameterWindow(this, "Tags List", nameof(tags)).SetAsStringList();
});
2025-04-14 17:49:47 -04:00
//次级模块
2025-02-12 18:46:46 -05:00
foreach (var submodule in submoduleList)
{
submodule.SetUpInspector();
}
2025-02-11 22:58:56 -05:00
}
2025-03-20 02:42:10 -04:00
2025-02-21 14:08:32 -05:00
/// <summary>
2025-03-01 12:50:13 -05:00
/// 获取所有子GameElement
2025-02-21 14:08:32 -05:00
/// </summary>
2025-03-01 12:50:13 -05:00
/// <param name="includeThis">是否包括自身</param>
public List<GameElement> GetAllGameElementsFromThis(bool includeThis = true)
2025-02-21 14:08:32 -05:00
{
void GetAllChildrenRecursively(GameElement parent, List<GameElement> elements)
{
foreach (var child in parent.childElementList)
{
elements.Add(child);
GetAllChildrenRecursively(child, elements);
}
}
2025-02-21 14:08:32 -05:00
List<GameElement> gameElements = new List<GameElement> { this };
GetAllChildrenRecursively(this, gameElements);
if (!includeThis) gameElements.Remove(this);
2025-02-21 14:08:32 -05:00
return gameElements;
}
2025-02-11 22:58:56 -05:00
}
namespace Beatmap
{
[System.Serializable]
public abstract class GameElement_BM : BaseElement_BM
{
[System.NonSerialized]
public static Dictionary<Guid, GameElement_BM> identifier = new(); //存档类的标识符
[System.NonSerialized]
public GameElement matchedElement; //存档类对应的游戏物体
public string elementName;
public List<string> tags;
public Guid elementGuid;
public GameElement_BM()
{
}
public GameElement_BM(string elementName, Guid elementGuid, List<string> tags, GameElement_BM attachedElement)
{
this.elementName = elementName;
this.elementGuid = elementGuid;
this.tags = tags;
this.attachedElementGuid = attachedElement?.elementGuid ?? Guid.Empty;
identifier.TryAdd(this.elementGuid, this);
}
public static GameElement_BM GetElementBM(Guid id)
{
if (identifier.TryGetValue(id, out GameElement_BM element_BM))
{
return element_BM;
}
return null;
}
public static GameElement GetElement(Guid id)
{
if (identifier.TryGetValue(id, out GameElement_BM element_BM))
2025-02-08 23:09:50 -05:00
{
return element_BM.matchedElement;
}
2025-02-08 23:09:50 -05:00
return null;
}
/// <summary>
/// 复制物体
/// </summary>
2025-02-11 22:58:56 -05:00
/// <param name="attached">父物体</param>
public abstract GameElement DuplicateBM(GameElement attached);
2025-03-24 13:41:50 -04:00
public static List<BaseElement_BM> GetAllAttachedBaseElements(GameElement_BM gameElement, List<BaseElement_BM> clip)
{
Guid elementGuid = gameElement.elementGuid;
List<BaseElement_BM> result = new List<BaseElement_BM>();
foreach (BaseElement_BM element in clip)
{
if (element.attachedElementGuid == elementGuid)
{
result.Add(element);
}
}
return result;
}
}
}
}