How do you instantiate a script from a monoscript?

I’m making en editor tool to create prefabs from selected scripts. Selection.objects returns a list of objects which are actually monoscripts. Monoscripts can’t seem to be cast as anything, and while I can use GetClass() to find the type, I don’t know how to use that type to instantiate a new, properly casted script object. Instantiate(obj) as ScriptName returns a null, and I can’t figure out how to fit the returned (GetClass()) type into a New() method, since unity doesn’t register that as a type.

Important note: This class doesn’t derive from monobehaviour.
Previous it did, and I was using AddComponent<((Monoscript)obj).GetClass()>(), but since then I’ve discovered I need it to be a custom class.

Here’s the entire, currently mangled script so you can see what I’m doing:

using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections;

public class CreateItemPrefabs : EditorWindow {

	[MenuItem ("Tools/Create Item Prefabs")]
	static void CreatePrefabs () 	// goes through each script selected in the editor and creates a prefab
	{
		foreach (Object obj in Selection.objects)
		{

			var go = new GameObject();
			//System.Type itemType = ((MonoScript)obj).GetClass();
			Item instance = Instantiate( obj) as Item;

			var container = go.AddComponent<ItemContainer>();
			container.m_Item = instance;
			Debug.Log(instance.GetType());
			Item _item = go.GetComponent<Item>();

			if( !(instance is Item))
			{
				Debug.Log("skipped");
				continue;
			}

			// Add interactive script and tag it
			var pickupScript = go.AddComponent<InteractData>();
			pickupScript.interactTag = "Item";
			pickupScript.hoverMessage = "pick up " + _item.itemName;

			// Change tag to interact
			go.tag = "Interact";


			Object prefab = AssetDatabase.LoadAssetAtPath("Assets/Prefabs/Items/"+obj.name+".prefab", typeof(Object));

			// if no prefab is found, create one.
			if (prefab == null)
			{
				prefab = PrefabUtility.CreateEmptyPrefab("Assets/Prefabs/Items/"+obj.name+".prefab");
			}

			// Replace prefab
			PrefabUtility.ReplacePrefab(go, prefab, ReplacePrefabOptions.ReplaceNameBased);
			DestroyImmediate(go);
		}
	}
}

Here are your options depending on your base class. Since .NET is a statically typed language you must know a common base that all your instances will share. Note .Net has recently added great support for the dynamic type, but it is a long way from making it to Unity (Mono 2.6).

Base Class System.Object:

MyCommonClass myCommonClass = Activator.CreateInstance(myMonoScript.GetClass()) as MyCommonClass;

Base Class ScriptableObject:

MyCommonClass myCommonClass = ScriptableObject.CreateInstance(myMonoScript.GetClass()) as MyCommonClass;

I know this is years later, but I wanted to leave a solution here for anyone that’s struggled with this exact problem for hours on end. @dustingunn


NOTE: This is using ScriptableObject, and hasn’t been tested with @aidesigner’s suggestion of creating a Base Class System.Object.


Step 1 - Abstract class FTW

Declare an abstract class that inherits from ScriptableObject and include any methods you may need.

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

public abstract class CommonScriptableClass : ScriptableObject
{
	public abstract void DoSomething();
}

Step 2 - Subclass

Create a new script (or scripts) that you want to inherit from CommonScriptableClass and override any of its methods if applicable.

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

public class TestClass : CommonScriptableClass
{
	public override void DoSomething(){}
}

Step 3 - Create SO from MonoScript

Now, in your custom Editor Window of choice:

CommonScriptableObject newScript =
(CommonScriptableObject)ScriptableObject.CreateInstance(monoScript.GetClass());
newScript.DoSomething();
Editor.CreateEditor(newScript).OnInspectorGUI();

Works in an Editor Window and displays correctly. Hope this helps someone.