内容将会持续更新,有错误的地方欢迎指正,谢谢!
拥有更好的学习体验 —— 不断努力,不断进步,不断探索 |
助力快速掌握 组件复制与粘贴 为初学者节省宝贵的学习时间,避免困惑! |
前言:
在Unity的开发过程中,特别是当你在编辑场景中处理多个对象时,如何高效地管理和操作组件是一项关键技能。手动为每个GameObject重新添加组件,尤其是在处理复杂场景时,是一个耗时的过程。
为此,本文将介绍如何在Unity编辑器中编写一个工具,允许你复制和粘贴组件,并提供多种粘贴模式,如序列化和非序列化,同时忽略某些不必要的组件。你还可以根据需要清除特定组件。
文章目录
一、创建组件忽略列表
在复制组件的时候,我们允许忽略一些组件不进行复制,那么在复制组件的时候就不会复制这些类型的组件,同时也不会进行粘贴。
using UnityEngine;
using System.Collections.Generic;
namespace CopyPasteComponents.Editor
{
[CreateAssetMenu(fileName = "ComponentsIgnoreList", menuName = "ScriptableObjects/ComponentsIgnoreList", order = 1)]
public class ComponentsIgnoreList : ScriptableObject
{
public List<string> IgnoreList = new List<string>();
}
}
在这里我们对Transform、MeshRenderer和MeshFilter组件进行忽略,因为这3个组件是组成一个游戏对象最基本的组件,一般不需要进行复制粘贴。
二、实现组件复制粘贴删除功能
以下是组件的复制粘贴与删除的具体功能:
public class CopyPasteComponents
{
static Component[] copiedComponentCaches;
static Dictionary<GameObject, Component[]> pastedComponentCaches = new Dictionary<GameObject, Component[]>();
static ComponentsIgnoreList componentsIgnoreList;
static Type[] ignoreComponentTypes;
[InitializeOnLoadMethod]
static void Init()
{
componentsIgnoreList = Resources.Load<ComponentsIgnoreList>("ComponentsIgnoreList");
Assembly assembly = Assembly.Load("UnityEngine.CoreModule");
ignoreComponentTypes = componentsIgnoreList.IgnoreList.Select(item =>assembly.GetType(item)).ToArray();
}
static Component GetNewAddComponents(GameObject targetObj)
{
// 获取粘贴后的SerializedObject
SerializedObject serializedObjectAfter = new SerializedObject(targetObj);
SerializedProperty componentProperty = serializedObjectAfter.FindProperty("m_Component");
serializedObjectAfter.Update();
// 获取新添加的组件
SerializedProperty newComponentProperty = componentProperty.GetArrayElementAtIndex(componentProperty.arraySize - 1);
SerializedProperty componentReference = newComponentProperty.FindPropertyRelative("component");
Object componentObject = componentReference.objectReferenceValue;
return componentObject as Component;
}
static void StorePastedComponent(GameObject targetObj, Component[] component)
{
if (!pastedComponentCaches.ContainsKey(targetObj))
{
pastedComponentCaches.Add(targetObj, null);
}
pastedComponentCaches[targetObj] = component;
}
static bool HasDisallowMultipleComponent(Type type)
{
object[] attributes = type.GetCustomAttributes(typeof(DisallowMultipleComponent)