个人博客地址:
https://www.jingfengji.tech/2020/08/22/unity-bian-ji-qi-tuo-zhan-zhi-san-shi-san-replacecomponentattributte-zu-jian-ti-huan/
本文介绍ReplaceComponentAttributte,方便使用自定义组件替换Unity原生组件。
Unity-ObjectFactory官方文档click here!
本篇文章,如果有不懂,欢迎留言~click here!
前言
在项目中有时候会拓展Unity原生组件,例如ImagePro替换Image组件,为了避免项目中其他同事继续使用Image组件。Unity提供了一个ObjectFactory,其中的componentWasAdded能监听到组件被添加,基于ObjectFactory就可以实现原生组件在被Add时替换成拓展组件了。
源码
ReplaceComponentAttribute
using System;
public class ReplaceComponentAttribute : Attribute
{
public Type ReplaceType { get; private set; }
public ReplaceComponentAttribute(Type replaceType)
{
ReplaceType = replaceType;
}
}
ObjectFactoryExtensionEditor
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组件
using UnityEngine.UI;
//替换Image组件
[ReplaceComponent(typeof(Image))]
public class ImagePro : Image
{
//Your Code
}
以上知识分享,如有错误,欢迎指出,共同学习,共同进步。如果有不懂,欢迎留言评论!