Generating Scripts with Unity Menu Item

I am trying to make a menu item to generate scripts. I want this item to show in the “Add Component” menu for game objects. The goal is for the menu item to ask for a string input_text and generate a script with that name. Then, the script is attached to the game object it was called on if the function was called from the “Add Component” menu. The writing onto the text file is giving me problems.

using System.IO;
using UnityEditor;
using UnityEngine;

public class ScriptBundle : EditorWindow{
    private string input_text = "";
    
    [MenuItem("Component/Custom Items/Script and Editor")]
    public static void ShowWindow(){
        ScriptBundle win = GetWindow<ScriptBundle>("Script + Editor Generator");
        win.minSize = new Vector2(400,100);
        win.maxSize = new Vector2(400,100);
        win.position = new Rect(Screen.width/2, Screen.height/2, 400, 100);
    }

    private void OnEnable(){
        this.minSize = new Vector2(400,100);
        this.maxSize = new Vector2(400,100);
        this.position = new Rect(Screen.width/2, Screen.height/2, 400, 100);
    }

    private void OnGUI(){
        GUILayout.Label("Generate a script and its inspector editor script", EditorStyles.boldLabel);
        input_text = EditorGUILayout.TextField("Script Name: ", input_text);

        GUILayout.Space(10);

        if (GUILayout.Button("Generate")){
            Debug.Log(input_text);
            
            GenerateScript(input_text);
            attachScriptToGameobject(input_text);

            Close();
        }
    }

    private void GenerateScript(string input_text){
        Debug.Log("Generate");
        
        string path = $"Assets/{input_text}.cs";

        if (File.Exists(path)){
            Debug.LogError("A script with this name already exists.");
        }

        string template = "using UnityEngine;nnpublic class " + input_text + " : MonoBehaviourn{nn}";

        try{
            //File.WriteAllText(path,template);
        }catch(Exception ex){
            Debug.Log($"Faild to write: {ex}")
        }

        AssetDatabase.Refresh();
    }

    private void attachScriptToGameobject(string input_text){
        Gameobject selected = Selection.activeGameObject;
        Debug.log(selected.transform.name);
        
        if (selected != null){
            selected.AddComponent(System.Type.GetType(input_text));
            Debug.Log("Script Attached");
        }
    }
}

Notice how the line for writing the template to the script is commented. This line causes issues when it is executed. None of the Debug.Logs run be them before or after the WriteAllText. Also, the code won’t recognize the active Gameobject at all and hence won’t attach the script to it.

What could be the problem, and how can I fix it?

Think about the process of manually adding a component. After creating a script file, you need to wait for Unity to complete compilation and reload the assemblies before you can add this component through the Add Component menu. Now you need to wait for this process programmatically.

OnEnable is a callback event that informs you the assemblies have been reloaded, so you can save the script name (in EditorPrefs) after writting the script file, then attach the script to the game object until the next invocation of OnEnable.

File.WriteAllText(path, template);
EditorPrefs.SetString("LASTADDEDSCRIPT", input_text);

private void OnEnable()
{
    ....
    var s = EditorPrefs.GetString("LASTADDEDSCRIPT");
    if(!string.IsNullOrEmpty(s))
    {
        EditorPrefs.DeleteKey("LASTADDEDSCRIPT");
        attachScriptToGameobject(s);
        Close();
    }
}

Something need to be noted:

  1. The type name passed to GetType should be assembly-qualified, thus you need to append the assembly name. (e.g. Assembly-CSharp)

    System.Type.GetType(input_text + ",Assembly-CSharp")
    
  2. The selected object can be changed during this process, you need to find other ways to retain it. (e.g. GlobalObjectId)

  3. There are also other ways to learn about assemblies reload event, such as AssemblyReloadEvents, InitializeOnLoadAttribute, etc.

I haven’t explicitly tried it, but you probably want to use AssetDatabase.ImportAsset with the ImportAssetOptions.ForceSynchronousImport.

This should synchronously import the newly created asset. Furthermore you probably want to use LoadAssetAtPath with your asset path. Keep in mind that asset path always starts with "Assets/" and always uses forward slashes. LoadAssetAtPath will actually return a MonoScript instance. A MonoScript is actually a TextAsset but has additional methods. The one relevant for you is the GetClass method which returns the System.Type reference of the class that is represented by this script asset.

Also note that editor scripts should not use AddComponent. For editor scripts there’s the Undo class which offers all sorts of methods like AddComponent to carry out editor actions. This class ensures that those changes are properly registrated in the Undo system.

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật