Перезагрузите сборку для доступа к новому типу скрипта ScriptableObject - PullRequest
0 голосов
/ 27 июня 2019

Я создаю новый скрипт из шаблона.Однако этот новый тип сценария недоступен до тех пор, пока сборка не сможет перекомпилироваться.Я пытаюсь создать экземпляр нового ScriptableObject, чтобы сгенерировать его с помощью кода.

public override void Def()
{
  NewAssetName = EditorGUILayout.TextField(NewAssetName);

  EditorGUILayout.BeginHorizontal();
  if (GUILayout.Button("Add"))
  {                    
    TemplateLines = File.ReadAllLines("E:/Unity/Editor/Data/Resources/ScriptTemplates/NewScriptableObject.cs.txt");

    for (int i = 0; i < TemplateLines.Length; i++)
                        {
    if (TemplateLines[i].Contains("#SCRIPTNAME#"))
    {
      TemplateLines[i] = TemplateLines[i].Replace("#SCRIPTNAME#", NewAssetName);
    }
  }

  NewFilePath = "Assets/" + NewAssetName + '/' + NewAssetName + ".cs";
  NewSOPath = "Assets/" + NewAssetName + '/' + NewAssetName + ".asset";

  File.WriteAllLines(NewFilePath, TemplateLines);

  ScriptableObject NewSO = CreateInstance(TypeName);        
  AssetDatabase.CreateAsset(NewSO, NewSOPath);
}

Все работает нормально, пока я не использую CreateInstance ();На данный момент тип еще не существует.Мне нужно подождать, пока Ассамблея перекомпилирует и капитулирует тип ...

У меня есть концепция обновлений сборки Google, но я ничего не нашел.

Я также использовал Google, используя async / await для того, чтобы отложить вызов CreateInstance (), пока ПОСЛЕ сборки, конечно, не появился новый тип ... Пока что эти попытки либо заблокировали Редактор,или не работайте так, как задумано ... (Я новичок в этом асинхронном стиле в C #)

Я открыт либо для решения сборки, либо для асинхронного решения для решения этой проблемы.

Ответы [ 2 ]

0 голосов
/ 01 июля 2019

Вот что получилось:

using UnityEditor;
using UnityEngine;

public class HandleNewScriptAndSO : ScriptableObject
{
    public StringRef ActiveDirectory_Ref;
    public StringRef NewSOName;
    public BoolRef TypeHasBeenAdded_Ref;

    private string NewSOPath;

    private void OnEnable()
    {
        AssemblyReloadEvents.afterAssemblyReload += GenerateNewSO;
    }

    public void GenerateNewSO()
    {
        if (TypeHasBeenAdded_Ref.Val)
        {            
            ScriptableObject NewSO = CreateInstance(NewSOName.Val);
            NewSOPath = ActiveDirectory_Ref.Val + '/' + NewSOName.Val + '/' + NewSOName.Val + ".asset";
            AssetDatabase.CreateAsset(NewSO, NewSOPath);

            TypeHasBeenAdded_Ref.Val = false;
        }            
    }        
}

Логическое значение устанавливается в значение true, когда пользователь нажимает кнопку «Добавить» в окне EditorWock:

  if (GUILayout.Button("Add") && NewSOName_Ref.Val != "")
  {
    AssetDatabase.CreateFolder(ActiveDirectory_Ref.Val, NewSOName_Ref.Val);

    TemplateLines = File.ReadAllLines("E:/Unity/Editor/Data/Resources/ScriptTemplates/NewScriptableObject.cs.txt");

    for (int i = 0; i < TemplateLines.Length; i++)
    {
      if (TemplateLines[i].Contains("#SCRIPTNAME#"))
      {
        TemplateLines[i] = TemplateLines[i].Replace("#SCRIPTNAME#", NewSOName_Ref.Val);
      }
    }

    NewFilePath = ActiveDirectory_Ref.Val + '/' + NewSOName_Ref.Val + '/' + NewSOName_Ref.Val + ".cs";

    File.WriteAllLines(NewFilePath, TemplateLines);

    TypeHasBeenAdded_Ref.Val = true;

    AssetDatabase.Refresh();

  }

Делегированный «AssemblyReloadEvents.afterAssemblyReload» необходимо подписать с помощью кода для добавления новых объектов. Он также должен быть защищен от bool, чтобы убедиться, что он запускается только тогда, когда пользователь запускает новый Add.

0 голосов
/ 28 июня 2019

Одним из решений является сохранение запроса на создание объекта сценариев в EditorPrefs и создание ресурса в обратном вызове после перезагрузки сценариев. К сожалению, вы не можете сделать это без блокировки редактора.

using UnityEditor;
using UnityEngine;

public class EditorUtils
{
    [MenuItem("Tools/Create SO")]
    private static void CreateSO()
    {
        GenerateAndSaveSOClass();

        ShouldCreateSO = true;

        AssetDatabase.Refresh();
        AssetDatabase.SaveAssets();
    }

    private static bool ShouldCreateSO
    {
        get { return EditorPrefs.GetBool("should_create", false); }
        set { EditorPrefs.SetBool("should_create", value);}
    }

    [UnityEditor.Callbacks.DidReloadScripts]
    private static void OnScriptsReloaded()
    {
        if (ShouldCreateSO)
        {
            ShouldCreateSO = false;

            var so = ScriptableObject.CreateInstance("MyClassName");
            var path = "Assets/SO.asset";

            AssetDatabase.CreateAsset(so, path);
        }
    }

    private static void GenerateAndSaveSOClass()
    {
        // TODO: generate and save class
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...