Я создаю новый скрипт из шаблона. Однако этот новый тип скрипта недоступен до тех пор, пока сборка не будет перекомпилирована. Я пытаюсь создать экземпляр нового 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(); На данный момент тип еще не существует. Приходится ждать, пока Ассамблея перекомпилирует и капитулирует типа...
Я погуглил концепцию обновления сборки, но ничего не нашел.
Я также гуглил, используя async/await, чтобы отложить вызов CreateInstance(), пока ПОСЛЕ сборки, конечно, не будет новый тип... До сих пор эти попытки либо блокировали редактор, либо не работали должным образом ... (я новичок в этом асинхронном стиле в С#)
Я открыт либо для решения Assembly, либо для асинхронного решения для решения этой проблемы.





Одним из решений является сохранение запроса на создание вашего объекта для сценариев в 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
}
}
Вот что получилось:
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, когда пользователь нажимает кнопку «Добавить» в EditorWindow:
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' с кодом. Он также должен был быть защищен логическим кодом, чтобы убедиться, что он запускается только тогда, когда пользователь вводит новый Add.
Не могли бы вы добавить код того, как вы пытались использовать
async?