0
\$\begingroup\$

I'm trying to make an editor window to ease my workflow of creating enemies. Most parts work fine apart from creating a class and adding it.

    void SaveAndCreate()
    {
       string guid = AssetDatabase.CreateFolder("Assets/Scripts/Enemies/EnemyTypes", enemyData.EnemyName);
        string newFolderPath = AssetDatabase.GUIDToAssetPath(guid);
        TextAsset templateTextFile = AssetDatabase.LoadAssetAtPath("Assets/CharacterTemplate.txt", typeof(TextAsset)) as TextAsset;

        string contents = "";
        if (templateTextFile != null)
        {
            contents = templateTextFile.text;
            contents = contents.Replace("CUSTOMCLASS_", enemyData.EnemyName.Replace(" ", ""));
        }
        using (StreamWriter sw = new StreamWriter(string.Format(newFolderPath + "/{0}.cs", new object[] { enemyData.EnemyName.Replace(" ", "") })))
        {
            sw.Write(contents);
        }

        objToCreate = new GameObject(enemyData.EnemyName);
        objToCreate.name = enemyData.EnemyName;
needToAttach = true
    }

Through this im creating the folders and class that i need which uses inheritance from a Monobehaviour. The objects name is the class, so if im making a "Dog" enemy the class that gets generated is "Dog.cs" which inherits from "Animals.cs". Now my issue lies with actually adding that class.

        //_go.AddComponent(Type.GetType(enemyData.EnemyName + ".cs"));//
        String ScriptName = objToCreate.name;
        Type MyScriptType = Type.GetType(ScriptName + "UnityEngine ,Assembly-CSharp");

        objToCreate.AddComponent(MyScriptType);
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();   
needToAttach = false;

As you can see i have tried a few things but since adding components through string is obsolete i cannot! I get this error "AddComponent asking for invalid type". So my question is is there any way for this to happen? I generate the dog.cs through script, create the prefab and assign to it through its name. This way i want to create enemies easy and adding all the necessary components automatically and not having to create each class on my own and assign in the editor. Thank you!

I should note that if i create another GUI button that assigns it , it works. But i do want it to work with the same button. In current setup the function to add the new component is in Update with this code. needToAttach is a bool to check when it needs and i updated the above to include it!

        if (EditorApplication.isCompiling) { return; }
        if (needToAttach)
        {
           // AddClass();
        }
\$\endgroup\$
1

1 Answer 1

0
\$\begingroup\$

Because the newly generated script is not recompiled, it is not added to the assembly.

Your expected behavior is:

  1. Generate some new .cs script while in editor script running.
  2. Recompile
  3. Add the compiled monobehavior class to the specified gameobject.

This cannot be done in the same operation, even using coroutines to wait for the compilation to finish is useless. Operating on another GUI button works because the entire assembly has been recompiled.

You can use UnityEditor.Callbacks.DidReloadScripts to be notified that the script recompilation is complete, and to do so at this time. Also, you don't want to trigger this function every time you recompile, so we need to make sure that adding component after compilation is triggered by generating scripts.

However, due to recompilation, all the context have been destroyed, and things like global variables cannot be used to save marks. We need a persistent storage method that does not rely on memory. e.g. EditorPrefs.

void SaveAndCreate()
{
    //Create scripts...
    EditorPrefs.SetBool("CreateMark", true);
}

[UnityEditor.Callbacks.DidReloadScripts]
static void OnScriptsReloaded ()
{
    var mark = EditorPrefs.GetBool("CreateMark");//default value is false.
    if (mark){
        //Add components...
        EditorPrefs.SetBool("CreateMark", false);
    }
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .