[英]Reload Assembly for access to new ScriptableObject script type
我正在從模板創建一個新腳本。 但是,直到大會有機會重新編譯之前,無法訪問此新腳本類型。 我試圖創建新的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搜索刷新大會的概念,但沒有發現任何東西。
我也使用async / await進行了Google搜索,以延遲調用CreateInstance(),直到確定該程序集具有新類型后為止。到目前為止,這些嘗試要么鎖定了編輯器,要么無法正常工作...(我是C#中這種異步樣式的新手)
我願意使用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;
}
}
}
當用戶在EditorWindow中按下“添加”按鈕時,布爾值設置為true:
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”添加代碼以添加新對象。 為了確保它僅在用戶發出新的“添加”時才運行,還需要對其進行防呆保護。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.