using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEngine; using XericLibrary.Runtime.MacroLibrary; using XericLibrary.Runtime.Type; using static UnityEngine.GraphicsBuffer; namespace XericLibrary.Runtime.Generation { public class BaseGenerate : WeaklyMonoBase where T : WeaklyObject { #region 字段属性 /// /// 生成器 /// [SerializeField] private T GenerationCompute; #endregion #region 生命周期 #endregion #region 快捷静态 /// /// 复制一个组件到另一个组件中 /// /// 这个方法只能用于 MonoBehaviours 或普通 C# 类的字段和属性, /// 不能用于 Unity 内置组件(例如 Transform、Rigidbody 等)的复制, /// 因为这些组件的字段和属性通常是私有的。 /// /// /// /// /// /// public static COMPONENT CopyComponentToAnother(COMPONENT source, COMPONENT copied) where COMPONENT : Component { if(source == null || copied == null) { Debug.LogWarning("Source or target component is null. Cannot copy parameters."); return null; } System.Type type = typeof(T); var fields = type.GetFields(); var properties = type.GetProperties(); // 复制只考虑公共字段属性 foreach(var field in fields) { if(!field.IsStatic) { field.SetValue(copied, field.GetValue(source)); } } foreach(var property in properties) { if(property.CanWrite) { property.SetValue(copied, property.GetValue(source, null), null); } } return copied; } /// /// 从给定的物体上克隆一个组件到新的物体上 /// /// 这个方法适用于所有类型的组件 /// /// /// /// /// /// public static COMPONENT CopyComponentToNew(GameObject source, out GameObject copied) where COMPONENT : Component { Component[] allComponents = source.GetComponents(); copied = Instantiate(source); foreach(Component component in copied.GetComponents()) { if(component.GetType() != typeof(COMPONENT)) { #if UNITY_EDITOR if(PlayModeState != PlayModeStateChange.EnteredPlayMode) DestroyImmediate(component); else Destroy(component); #else Destroy(component); #endif } } return copied.GetComponent(); } #endregion #region 快捷方法 /// /// 创建节点 /// protected GameObject CreatOrGetGameNode(string name, Transform parent = null) { var targetParent = parent == null ? transform : parent; var node = targetParent.GetChildren() .Where(a => a.name == name) .Select(a => a.gameObject) .FirstOrDefault(); if(node != null) return node; node = new GameObject(name); node.transform.parent = targetParent; return node; } /// /// 使给定的游戏节点断子绝孙 /// protected void DieSonless(Transform transform) { foreach(var target in transform.GetChildren().ToList()) { #if UNITY_EDITOR if(PlayModeState != PlayModeStateChange.EnteredPlayMode) DestroyImmediate(target.gameObject); else Destroy(target.gameObject); #else Destroy(target.gameObject); #endif } } /// /// 使给定的游戏节点断子绝孙 /// protected void DieSonless(GameObject target) { DieSonless(target.transform); } /// /// 提取所有组件,然后在同级中另起一个节点进行对指定组件结构的覆盖 /// /// /// 要提取组件的节点 /// 复制时另起节点的名称 /// 最大检索深度 protected void ExtractAllComponent(Transform transform, string name, int MaxStackDepth = 20) where COMPONENT : Component { var root = CreatOrGetGameNode(name, transform); DieSonless(root); int index = 0; // 提取组件 foreach(var comp in transform.GetComponentsInRecursionChildren(MaxStackDepth)) { CreatOrGetGameNode($"component.{index++}", root.transform); CopyComponentToNew(comp.gameObject, out var copiedObj); copiedObj.transform.parent = root.transform; } } #endregion } #if UNITY_EDITOR /// /// 基本的创建辅助器,用于在inspecter上创建按钮或其他功能 /// public class BaseGenerateEditor : Editor { public override void OnInspectorGUI() { base.OnInspectorGUI(); if(GUILayout.Button("生成更新")) UpdateGen(); } /// /// 更新生成 /// protected void UpdateGen() { var script = (StairsGenerate)target; } } #endif }