[英]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.