首先调用Unity提供的注释可以在点下Play之后,在游戏真正启动前去执行一些脚本,要注意执行脚本要放在Assets/Editor下
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
要想运用反射机制来进行动态脚本的创建,就需要先遍历获得全部文件:
//创建文件路径
DirectoryInfo direction = new("Assets/Script/");
//获得所有文件
FileInfo[] files = direction.GetFiles("*", SearchOption.AllDirectories);
//通过遍历筛选有用的
for (int i = 0; i < files.Length; i++)
{
Debug.Log(files[i].Name);
}
因为Editor下的代码集和默认代码集不一样,想在脚本里直接访问对应的代码集最简单的方法,就是让默认代码集直接返回一个集合过来:
public static class AssemblyUtil
{
public static Assembly getScriptAssembly() {
return Assembly.GetExecutingAssembly();
}
}
接下来就是用映射来创建真正实例了:
// 获取脚本所在程序集
Assembly assembly = AssemblyUtil.getScriptAssembly();
//通过类型创建实例,并塞入加载结果里
Type type = assembly.GetType(name, true);
T obj = (T)Activator.CreateInstance(type);
整体代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEditor;
using System.IO;
using System.Reflection;
public static class RequireUtil
{
private static Dictionary<string, BaseScript> scriptMap;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void Init()
{
Debug.Log("初始化引用构造函数");
//构造脚本映射表
scriptMap = LoadAllFile<BaseScript>("Assets/Script/Logic", "cs");
foreach ((_, BaseScript script) in scriptMap)
{
script.Ctor();
}
}
/// <summary>
/// 加载指定路径下的文件,并给与指定格式
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="path"></param>
/// <param name="suffix"></param>
/// <returns></returns>
static Dictionary<string, T> LoadAllFile<T>(string path, string suffix)
{
//路径补全
string fullPath = path + "/";
Dictionary<string, T> map = new Dictionary<string, T>();
//获取指定路径下面的所有资源文件
if (Directory.Exists(fullPath))
{
//创建文件路径
DirectoryInfo direction = new(fullPath);
//获得所有文件
FileInfo[] files = direction.GetFiles("*", SearchOption.AllDirectories);
// 获取脚本所在程序集
Assembly assembly = AssemblyUtil.getScriptAssembly();
//通过遍历筛选有用的
for (int i = 0; i < files.Length; i++)
{
//切割文本判断是否符合需求
int fileSuffix = files[i].Name.LastIndexOf('.');
string strSuffix = files[i].Name.Substring(fileSuffix);
string strName = files[i].Name.Substring(0, fileSuffix);
if (strSuffix.EndsWith("meta") || suffix != null && !strSuffix.EndsWith(suffix))
{
continue;
}
//通过类型创建实例,并塞入加载结果里
Type type = assembly.GetType(strName, true);
T obj = (T)Activator.CreateInstance(type);
map.Add(strName, obj);
}
}
return map;
}
}