首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >生成类和获取类型

生成类和获取类型
EN

Stack Overflow用户
提问于 2022-07-10 07:46:00
回答 1查看 107关注 0票数 0

我希望在运行时创建一个新类,获取该类型,并创建该类型的列表。例如:

代码语言:javascript
复制
    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 (类本身和资产)。所以我有一个基类,比如:

代码语言:javascript
复制
public abstract class State : ScriptableObject{}

正如您所看到的,它将是一个StateMachine。现在,我想要一个带有文本字段的窗口,在该窗口中输入一个状态的名称,并创建一个新的类,如:

代码语言:javascript
复制
public class Idle : State{}

在此之后,它通过以下方式创建资产:

代码语言:javascript
复制
AssetDatabase.CreateAsset<Idle>("/path/to/somewhere");

编辑几乎可以工作的代码

代码语言:javascript
复制
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();
         
            }
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-10 16:47:24

可以使用以下方法从字符串创建类型:

代码语言:javascript
复制
Type.GetType(string typeAssemblyQualifiedName);

但是您需要为此使用Type.assemblyQualifiedName,所以如果使用名称空间或程序集,“空闲”可能无法工作,其他选项是获取当前域中的所有类型。

代码语言:javascript
复制
var allTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(assembly => assembly.GetTypes());

在列表上找到你想要的类型

代码语言:javascript
复制
var inputType = allTypes.Find(type => typeof(State).IsAssignableFrom(type) && type.Name == inputName);

然后使用该类型创建脚本对象实例。

代码语言:javascript
复制
var so = ScriptableObject.CreateInstance(inputType);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72926916

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档