我希望在运行时创建一个新类,获取该类型,并创建该类型的列表。例如:
void CreateNewClass(string name)
{
File file = CreateFile(name);
Type type = GetTypeOfFile(file);
List<type> someList = new List<type>();
}
void CreateFile(string name)
{
//Get a template file
//copy that file
//change some names and stuff in it
//return the file
}
Type GetTypeOfFile(File file)
{
//get the class(type) of that file
// return type
}我不想在内存中生成那个类,我需要将这个类作为一个文件。文件的创建不是一个问题。
我只想知道:
的列表
我想有些事需要发生,但在那之后,我就无所适从。
编辑:
FYI:我实际上不想创建一个列表,我需要一个统一项目的这个功能。对于熟悉它的人:我想通过单击按钮创建ScriptableObjects (类本身和资产)。所以我有一个基类,比如:
public abstract class State : ScriptableObject{}正如您所看到的,它将是一个StateMachine。现在,我想要一个带有文本字段的窗口,在该窗口中输入一个状态的名称,并创建一个新的类,如:
public class Idle : State{}在此之后,它通过以下方式创建资产:
AssetDatabase.CreateAsset<Idle>("/path/to/somewhere");编辑几乎可以工作的代码
using System;
using System.IO;
using System.Linq;
using System.Text;
using AI.StateMachine.BaseClasses;
using UnityEditor;
using UnityEngine;
namespace AI.StateMachine.Editor
{
public class ActionWizard : EditorWindow
{
[MenuItem("Tools/AI/StateMachine/ActionWizard")]
static void Init()
{
// Get existing open window or if none, make a new one:
ActionWizard window = (ActionWizard) EditorWindow.GetWindow(typeof(ActionWizard));
window.Show();
}
private string actionName;
void OnGUI()
{
actionName = GUILayout.TextField(actionName);
if (GUILayout.Button("Create Action"))
{
//Get base class content
string baseClassContent =
File.ReadAllText($"{Application.dataPath}/Scripts/AI/StateMachine/BaseClasses/SM_Action.cs");
//refactor base class content to create derived class content
string newClassContent = baseClassContent
.Replace("SM_Action", actionName)
.Replace("ScriptableObject", "SM_Action")
.Replace("abstract ", "")
.Replace("namespace AI.StateMachine.BaseClasses", "namespace AI.StateMachine.Assets.Actions.Scripts")
.Replace("//", "");
//create derived class
using (FileStream fs = File.Create($"{Application.dataPath}/Scripts/AI/StateMachine/Assets/Actions/Scripts/{actionName}.cs"))
{
byte[] info = new UTF8Encoding(true).GetBytes(newClassContent);
fs.Write(info, 0, info.Length);
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
//get type of created class
var allTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(assembly => assembly.GetTypes()).ToList();
var inputType = allTypes.Find(type => typeof(SM_Action).IsAssignableFrom(type) && type.Name == actionName);
//null....
//if type was created before it works and finds the desired type
Debug.Log(inputType);
//create scriptable object instance of created type
// var so = ScriptableObject.CreateInstance(inputType);
//save scriptable object asset
// AssetDatabase.CreateAsset(so,"Assets/Scripts/AI/StateMachine/Actions/"+actionName + ".asset");
// AssetDatabase.Refresh();
}
}
}
}发布于 2022-07-10 16:47:24
可以使用以下方法从字符串创建类型:
Type.GetType(string typeAssemblyQualifiedName);但是您需要为此使用Type.assemblyQualifiedName,所以如果使用名称空间或程序集,“空闲”可能无法工作,其他选项是获取当前域中的所有类型。
var allTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(assembly => assembly.GetTypes());在列表上找到你想要的类型
var inputType = allTypes.Find(type => typeof(State).IsAssignableFrom(type) && type.Name == inputName);然后使用该类型创建脚本对象实例。
var so = ScriptableObject.CreateInstance(inputType);https://stackoverflow.com/questions/72926916
复制相似问题