本文介绍ReplaceComponentAttributte,方便使用自定义组件替换Unity原生组件。

Unity-ObjectFactory官方文档click here!

本篇文章,如果有不懂,欢迎留言~click here!

前言

在项目中有时候会拓展Unity原生组件,例如ImagePro替换Image组件,为了避免项目中其他同事继续使用Image组件。Unity提供了一个ObjectFactory,其中的componentWasAdded能监听到组件被添加,基于ObjectFactory就可以实现原生组件在被Add时替换成拓展组件了。

源码

ReplaceComponentAttribute

1
2
3
4
5
6
7
8
9
10
11

using System;

public class ReplaceComponentAttribute : Attribute
{
public Type ReplaceType { get; private set; }
public ReplaceComponentAttribute(Type replaceType)
{
ReplaceType = replaceType;
}
}

ObjectFactoryExtensionEditor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using System.Reflection;
using UnityEditor;
using UnityEngine;

[InitializeOnLoad]
internal static class ObjectFactoryExtensionEditor
{
static ObjectFactoryExtensionEditor()
{
//注册组件被Add时的回调
ObjectFactory.componentWasAdded += OnComponentWasAdded;
}

private static void OnComponentWasAdded(Component addCom)
{
//获取所有ReplaceComponentAttribute的type
Assembly asm = Assembly.GetAssembly(typeof(ReplaceComponentAttribute));
System.Type[] types = asm.GetExportedTypes();
for (int i = 0; i < types.Length; i++)
{
if (types[i] == typeof(ReplaceComponentAttribute))
{
continue;
}
var attributes = types[i].GetCustomAttributes(typeof(ReplaceComponentAttribute), true);
if (attributes.Length > 0)
{
//如果ReplaceType 是 当前被添加的组件,则替换
ReplaceComponentAttribute replaceComponentAttribute = (ReplaceComponentAttribute)attributes[0];
if (addCom.GetType() == replaceComponentAttribute.ReplaceType)
{
//替换
EditorApplication.delayCall += () =>
{
GameObject go = addCom.gameObject;
Object.DestroyImmediate(addCom);
go.AddComponent(types[i]);
};
break;
}
}
}
}
}

测试

新建一个ImagePro组件

1
2
3
4
5
6
7
8
using UnityEngine.UI;

//替换Image组件
[ReplaceComponent(typeof(Image))]
public class ImagePro : Image
{
//Your Code
}

测试结果动图

以上知识分享,如有错误,欢迎指出,共同学习,共同进步。如果有不懂,欢迎留言评论!