【unity】c#通过反射和attribute特性实现工厂模式
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
namespace Common
{
//根据Attribute提取类
public class ClassEnumerator
{
protected List<Type> results = new List<Type>();
public List<Type> Results
{
get
{
return results;
}
}
private Type AttributeType;
private Type InterfaceType;
public ClassEnumerator(Type InAttributeType, Type InInterfaceType, Assembly InAssembly, bool bIgnoreAbstract = true, bool bInheritAttribute = false, bool bShouldCrossAssembly = false)
{
AttributeType = InAttributeType;
InterfaceType = InInterfaceType;
try
{
if (bShouldCrossAssembly)
{
Assembly[] Assemblys = AppDomain.CurrentDomain.GetAssemblies();
if (Assemblys != null)
{
for (int i = 0, len = Assemblys.Length; i < len; i++)
{
CheckInAssembly(Assemblys[i], bIgnoreAbstract, bInheritAttribute);
}
}
}
else
{
CheckInAssembly(InAssembly, bIgnoreAbstract, bInheritAttribute);
}
}
catch (Exception e)
{
Debug.LogError("Error in enumerate classes: " + e.Message);
}
}
private void CheckInAssembly(Assembly InAssembly, bool bInIgnoreAbstract, bool bInInheritAttribute)
{
Type[] types = InAssembly.GetTypes();
if (null == types)
{
return;
}
for (int i = 0, len = types.Length; i < len; i++)
{
var type = types[i];
if (InterfaceType == null || InterfaceType.IsAssignableFrom(type))
{
if (!bInIgnoreAbstract || (bInIgnoreAbstract && !type.IsAbstract))
{
if (type.GetCustomAttributes(AttributeType, bInInheritAttribute).Length > 0)
{
results.Add(type);
}
}
}
}
}
}
}
//自定义Attribute
public sealed class LoaderAttribute : Attribute
{
public string LoaderType { get; private set; }
public LoaderAttribute(string loaderType)
{
LoaderType = loaderType;
}
}
/// <summary>
/// 加载器接口
/// </summary>
public interface ILoader
{
bool Load(LoaderContext context);
}
/// <summary>
/// 加载器管理类
/// </summary>
public class LoaderManager
{
public static LoaderManager Instance
{
get
{
if (_instance == null)
{
_instance = new LoaderManager();
_instance.InitAllLoaders();
}
return _instance;
}
set
{
_instance = value;
}
}
// 通过类型获取加载器
public ILoader GetLoader(string strType)
{
ILoader loader = null;
if (_loaderList.TryGetValue(strType, out loader))
{
return loader;
}
else
{
return null;
}
}
/// <summary>
/// 初始化所有加载器
/// </summary>
void InitAllLoaders()
{
_loaderList = new Dictionary<string, ILoader>();
//读取所有带有LoaderAttribute的类
var classEnumerator = new ClassEnumerator(typeof(LoaderAttribute), null, typeof(ILoader).Assembly);
var em = classEnumerator.Results.GetEnumerator();
while (em.MoveNext())
{
var classType = em.Current;
var atts = classType.GetCustomAttributes(typeof(LoaderAttribute), true);
if (atts.Length > 0)
{
var att = atts[0] as LoaderAttribute;
if (null != att)
{
//读取LoaderAttribute
_loaderList.Add(att.LoaderType, Activator.CreateInstance(classType) as ILoader);
}
}
}
}
static private LoaderManager _instance; // 单例
private Dictionary<string, ILoader> _loaderList; // 加载器列表
}
/// <summary>
/// 部件动画加载器
/// </summary>
[LoaderAttribute("模型动画")]
public class ModelAnimLoader : ILoader
{
public string path;
public bool Load(LoaderContext context)
{
XmlElement elem = context.elem;
string uid = elem.GetAttribute(PathConfig.STR_UNITYEXPORT_ID);
float startTime = float.Parse(elem.GetAttribute(PathConfig.STR_UNITYEXPORT_STARTTIME));
float endTime = float.Parse(elem.GetAttribute(PathConfig.STR_UNITYEXPORT_ENDTIME));
if (!MyModelManager.Instance.IsModelExist(uid))
{
return false;
}
MyModel model = MyModelManager.Instance.GetModelById(uid);
AnimManager.Instance.AddAnim(new ModelAnimationAction(model._transform, startTime, endTime));
return true;
}
void GetVector3(ref Vector3 vec, XmlElement elem, string key)
{
// 不存在属性则不读取
if(!elem.HasAttribute(key))
{
return;
}
vec = elem.GetAttribute(key).ToVector3();
}
}
本文作者:香菇0_0
本文链接:https://www.cnblogs.com/Xiang-gu/p/16512337.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步