What's the best way to store a reference to a script asset?

To clarify, at runtime I’m looking to create and add a script to an object based on what type the reference has. This functionality already exists in the form of MonoScript (ScriptReference/MonoScript.html). However MonoScript only works in the editor.

I’ve considered the following 2 approaches but they seem either inefficient or error prone:

  1. Use string properties and call gameObject.AddComponent(myString)
  2. Store script asset references as a TextAsset and then call gameObject.AddComponent(myTextAsset.name);

Option 2 might be ok but I don’t want Unity to load up the whole script file just to get its name.

Is there a better way?

You can probably just use an object reference or component reference and use AddComponent.


Scripts are compiled into an assembly and so are all available at runtime. I do not know if the representative assets have to be loaded however.

I would just input the name of the script using a regular string variable.

If you are using Unity 4 then you can implement a custom property drawer and attribute to achieve drag & drop in the inspector:


public class SomeBehaviour : MonoBehaviour {
    public string myScriptName;

    public void Foo() {

Attribute Implementation:

using UnityEngine;

public class ScriptPickerAttribute : PropertyAttribute {

Drawer Implementation:

using UnityEngine;
using UnityEditor;

public class ScriptPickerPropertyDrawer : PropertyDrawer {
    public override void OnGUI(Rect position, SerializedProperty prop, GUIContent) {
        Rect rect;
        int controlID = GUIUtility.GetControlID(FocusType.Passive);
        int objectFieldWidth = 45;
        // Detect drag & drop
        CheckDragAndDrop(position, prop, controlID);
        // Allow manual text entry
        rect = new Rect(
            position.width - objectFieldWidth - 2,
        prop.stringValue = EditorGUI.TextField(
            rect, label, prop.stringValue
        // Allow drag & drop or selection from dialog
        rect = new Rect(
            position.xMax - objectFieldWidth,
        MonoScript script = (MonoScript)EditorGUI.ObjectField(
            rect, null, typeof(MonoScript), false
        if (script != null) {
            prop.stringValue = script.name;
    private void CheckDragAndDrop(Rect position, SerializedProperty prop, int controlID) {
        Event e = Event.current;
        EventType eventType = e.GetTypeForControl(controlID);
        switch (eventType) {
            case EventType.DragUpdated:
            case EventType.DragPerform:
                if (position.Contains(e.mousePosition)
                    && DragAndDrop.objectReferences.Length == 1
                    && DragAndDrop.objectReferences[0] is MonoScript)
                    if (eventType == EventType.DragUpdated) {
                        DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
                        DragAndDrop.activeControlID = controlID;
                    else {
                        prop.stringValue = DragAndDrop.objectReferences[0].name;
                        DragAndDrop.visualMode = DragAndDropVisualMode.None;