I want to create a new class at runtime, get the type, and create a List of that type. For example:
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
}
I do not want to generate that class in memory, I need to have that class as a file. The file creation is not a problem.
I just need to know:
- How to load the file/class and get it's type
- How to create a list with the loaded type
I guess something with Reflections need to happen, but after that I'm clueless.
edit:
FYI: I don't actually want to create a List, I need this functionallity for a Unity Project. For those who are familiar with it: I want to create ScriptableObjects (the class itself and the asset) with one button click. So I have a base class like:
public abstract class State : ScriptableObject{}
As you can see it's going to be a StateMachine. Now I want kind of a window with a text field where I enter a name for a state and it creates a new class like:
public class Idle : State{}
And after that it creates the asset itself via:
AssetDatabase.CreateAsset<Idle>("/path/to/somewhere");
edit nearly working code
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();
}
}
}
}