Unity--加载预制体时通过特性将脚本挂载在预制体上

 

 

 

 

定义特性类BindPre

using System;

[AttributeUsage(AttributeTargets.Class)]//特性使用限定为类
public class BindPre : Attribute
{
    public string Path { get; private set; }

    public BindPre(string path)
    {
        Path = path;
    }
}

在脚本上添加特性

using UnityEngine;

[BindPre("Prefabs/12Attribute/StartView")]
public class StartView : MonoBehaviour
{
}

绑定路径和类型的工具类

using System;
using System.Collections.Generic;
using UnityEngine;

public class BindUtil
{
    private static Dictionary _prefabAndScriptMap = new Dictionary();

    public static void Bind(string path, Type type)
    {
        if (!_prefabAndScriptMap.ContainsKey(path))
        {
            _prefabAndScriptMap.Add(path, type);
        }
        else
        {
            Debug.LogError("当前数据中已存在路径:" + path);
        }
    }

    public static Type GetType(string path)
    {
        if (_prefabAndScriptMap.ContainsKey(path))
        {
            return _prefabAndScriptMap[path];
        }
        else
        {
            Debug.LogError("当前数据中未包含路径:" + path);
            return null;
        }
    }
}

利用反射初始化自定义的特性

using System;
using System.Reflection;

public class InitCustomAttributes
{
    public void Init()
    {
        Assembly assembly = Assembly.GetAssembly(typeof(BindPre));
        Type[] types = assembly.GetExportedTypes();

        foreach (Type type in types)
        {
            foreach (Attribute attribute in Attribute.GetCustomAttributes(type, true))
            {
                if (attribute is BindPre)
                {
                    BindPre data = attribute as BindPre;
                    BindUtil.Bind(data.Path, type);
                }
            }
        }
    }
}

 

//加载的接口

using UnityEngine;

public interface ILoader
{
    GameObject LoadPrefab(string path, Transform parent = null);
}

Resources加载预制体,实现ILoader的接口

using UnityEngine;

public class ResourcesLoader : ILoader
{
    public GameObject LoadPrefab(string path, Transform parent = null)
    {
        GameObject prefab = Resources.Load(path);
        GameObject temp = Object.Instantiate(prefab, parent);
        return temp;
    }
}

加载管理类,加载预制体并添加绑定该预制体的脚本

using System;
using UnityEngine;

public class LoadMgr : Singleton
{
    private ILoader _loader;

    public LoadMgr()
    {
        _loader = new ResourcesLoader();
    }

    public GameObject LoadPrefab(string path, Transform parent = null)
    {
        GameObject temp = _loader.LoadPrefab(path, parent);
        //Type type = Type.GetType(temp.name.Remove(temp.name.Length - 7));
        Type type = BindUtil.GetType(path);
        temp.AddComponent(type);
        return temp;
    }
}

启动游戏时的第一个脚本, 初始化用

using UnityEngine;

public class LaunchGame : MonoBehaviour
{
    void Awake()
    {
        InitCustomAttributes initAtt = new InitCustomAttributes();
        initAtt.Init();
        LoadMgr.Instance.LoadPrefab("Prefabs/12Attribute/StartView", transform);
    }
}

 

你可能感兴趣的:(Unity3D)