- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下创建自定义检查器窗口的 EditorWindow 脚本。在此窗口中按下按钮后,id
将递增 1。
static int id = 10000;
[MenuItem("Custom/CustomMenu")]
static void Init()
{
// Get existing open window or if none, make a new one:
CustomMenu window = (CustomMenu)EditorWindow.GetWindow(typeof(CustomMenu));
window.Show();
}
if (GUILayout.Button("someButton"))
{
id++;
Repaint();
EditorUtility.SetDirty(this);
}
这工作正常,但是当我启动播放模式或关闭 unity 编辑器时,id
的增量值丢失,并将重置回 10000。
使用 int id
的非静态版本将使该值在“播放” session 中持续存在,但一旦您关闭 unity 仍会丢失。
有没有办法在编辑器/unity session 之间存储这个值,类似于 playerprefs
但对于编辑器可能?
最佳答案
也许更像“统一”的方式是使用专用的 ScriptableObject
(另见 Introduction to ScriptableObjects)
您可以将它与 [InitializeOnLoadMethod]
结合使用为了实现一个加载方法,该方法将在打开编辑器并重新编译以创建 ScriptableObject 一次后调用。
// we don't need the CreateAssetMenu attribute since the editor window
// will create the ScriptableObject once by itself
public class CustomMenuData : ScriptableObject
{
public int Id;
}
确保将其放在单独的脚本中。
public class CustomMenu : EditorWindow
{
// we can go privtae again ;)
private static CustomMenuData data;
// This method will be called on load or recompile
[InitializeOnLoadMethod]
private static void OnLoad()
{
// if no data exists yet create and reference a new instance
if (!data)
{
// as first option check if maybe there is an instance already
// and only the reference got lost
// won't work ofcourse if you moved it elsewhere ...
data = AssetDatabase.LoadAssetAtPath<CustomMenuData>("Assets/CustomMenuData.asset");
// if that was successful we are done
if(data) return;
// otherwise create and reference a new instance
data = CreateInstance<CustomMenuData>();
AssetDatabase.CreateAsset(data, "Assets/CustomMenuData.asset");
AssetDatabase.Refresh();
}
}
[MenuItem("Custom/CustomMenu")]
private static void Init()
{
// Get existing open window or if none, make a new one:
var window = (CustomMenu)EditorWindow.GetWindow(typeof(CustomMenu));
window.Show();
}
private void OnGUI()
{
// Note that going through the SerializedObject
// and SerilaizedProperties is the better way of doing this!
//
// Not only will Unity automatically handle the set dirty and saving
// but it also automatically adds Undo/Redo functionality!
var serializedObject = new SerializedObject(data);
// fetches the values of the real instance into the serialized one
serializedObject.Update();
// get the Id field
var id = serializedObject.FindProperty("Id");
// Use PropertyField as much as possible
// this automaticaly uses the correct layout depending on the type
// and automatically reads and stores the according value type
EditorGUILayout.PropertyField(id);
if (GUILayout.Button("someButton"))
{
// Only change the value throgh the serializedProperty
// unity marks it as dirty automatically
// also no Repaint required - it will be done .. guess .. automatically ;)
id.intValue += 1;
}
// finally write back all modified values into the real instance
serializedObject.ApplyModifiedProperties();
}
}
这样做的巨大优势:
一个简单但不是那么有效的替代解决方案是将其存储到一个文件中,例如作为像这样的 JSON
using System.IO;
using UnityEditor;
using UnityEngine;
public class CustomMenu : EditorWindow
{
private const string FileName = "Example.txt";
// shorthand property for getting the filepath
public static string FilePath
{
get { return Path.Combine(Application.streamingAssetsPath, FileName); }
}
private static int id = 10000;
// Serialized backing field for storing the value
[SerializeField] private int _id;
[MenuItem("Custom/CustomMenu")]
static void Init()
{
// Get existing open window or if none, make a new one:
CustomMenu window = (CustomMenu)EditorWindow.GetWindow(typeof(CustomMenu));
if (File.Exists(FilePath))
{
// read the file content
var json = File.ReadAllText(FilePath)
// If the file exists deserialize the JSON and read in the values
// for only one value ofcourse this is overkill but for multiple values
// this is easier then parsing it "manually"
JsonUtility.FromJsonOverwrite(json, window);
// pass the values on into the static field(s)
id = window._id;
}
window.Show();
}
private void OnGUI()
{
id = EditorGUILayout.IntField(id);
if (GUILayout.Button("someButton"))
{
id++;
Repaint();
EditorUtility.SetDirty(this);
// do everything in oposide order
// first fetch the static value(s) into the serialized field(s)
_id = id;
// if not exists yet create the StreamingAssets folder
if (!Directory.Exists(Application.streamingAssetsPath))
{
AssetDatabase.CreateFolder("Assets", "StreamingAssets");
}
// serialize the values into json
var json = JsonUtility.ToJson(this);
// write into the file
File.WriteAllText(FilePath, json);
// reload the assets so the created file becomes visible
AssetDatabase.Refresh();
}
}
}
目前每次打开窗口时都会读取文件,每次单击按钮时都会写入文件。这仍然可以改进。
同样,您可以使用 [InitializeOnLoadMethod]
为了只读取文件一次 - 即当您打开编辑器或重新编译时
public class CustomMenu : EditorWindow
{
// Instead of having the field values directly as static fields
// rather store the information in a proper serializable class
[Serializable]
private class CustomMenuData
{
public int Id;
}
// made this publlic for the saving process (see below)
public static readonly CustomMenuData data = new CustomMenuData();
// InitializeOnLoadMethod makes this method being called everytime
// you load the project in the editor or after re-compilation
[InitializeOnLoadMethod]
private static void OnLoad()
{
if (!File.Exists(FilePath)) return;
// read in the data from the json file
JsonUtility.FromJsonOverwrite(File.ReadAllText(FilePath), data);
}
...
}
为了优化保存并仅在您在 UnityEditor 中保存时执行文件写入,您可以实现专用的 AssetModificationProcessor
喜欢
public class CustomMenuSaver : SaveAssetsProcessor
{
static string[] OnWillSaveAssets(string[] paths)
{
// do change nothing in the paths
// but additionally store the data in the file
// if not exists yet create the StreamingAssets folder
if (!Directory.Exists(Application.streamingAssetsPath))
{
AssetDatabase.CreateFolder("Assets", "StreamingAssets");
}
// serialize the values into json v That's why I made it public
var json = JsonUtility.ToJson(CustomMenu.data);
// write into the file v needs to be public as well
File.WriteAllText(CustomMenu.FilePath, json);
return paths;
}
}
关于c# - 在编辑器 session 之间存储编辑器值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56594340/
我正在运行一个辅助角色,并检查 Azure 上托管的存储中是否存在数据。当我将连接字符串用于经典类型的存储时,我的代码可以正常工作,但是当我连接到 V2 Azure 存储时,它会抛出此异常。 “远程服
在我的应用程序的主页上,我正在进行 AJAX 调用以获取应用程序各个部分所需的大量数据。该调用如下所示: var url = "/Taxonomy/GetTaxonomyList/" $.getJSO
大家好,我正在尝试将我的商店导入我的 Vuex Route-Gard。 路由器/auth-guard.js import {store} from '../store' export default
我正在使用 C# 控制台应用程序 (.NET Core 3.1) 从 Azure Blob 存储读取大量图像文件并生成这些图像的缩略图。新图像将保存回 Azure,并将 Blob ID 存储在我们的数
我想将 Mlflow 设置为具有以下组件: 后端存储(本地):在本地使用 SQLite 数据库存储 Mlflow 实体(run_id、params、metrics...) 工件存储(远程):使用 Az
我正在使用 C# 控制台应用程序 (.NET Core 3.1) 从 Azure Blob 存储读取大量图像文件并生成这些图像的缩略图。新图像将保存回 Azure,并将 Blob ID 存储在我们的数
我想将 Mlflow 设置为具有以下组件: 后端存储(本地):在本地使用 SQLite 数据库存储 Mlflow 实体(run_id、params、metrics...) 工件存储(远程):使用 Az
我的 Windows 计算机上的本地文件夹中有一些图像。我想将所有图像上传到同一容器中的同一 blob。 我知道如何使用 Azure Storage SDKs 上传单个文件BlockBlobServi
我尝试发出 GET 请求来获取我的 Azure Blob 存储帐户的帐户详细信息,但每次都显示身份验证失败。谁能判断形成的 header 或签名字符串是否正确或是否存在其他问题? 代码如下: cons
这是用于编写 JSON 的 NeutralinoJS 存储 API。是否可以更新 JSON 文件(推送数据),而不仅仅是用新的 JS 对象覆盖数据。怎么做到的??? // Javascript
我有一个并行阶段设置,想知道是否可以在嵌套阶段之前运行脚本,所以像这样: stage('E2E-PR-CYPRESS') { when { allOf {
我想从命令行而不是从GUI列出VirtualBox VM的详细信息。我对存储细节特别感兴趣。 当我在GUI中单击VM时,可以看到包括存储部分在内的详细信息: 但是到目前为止,我还没有找到通过命令行执行
我有大约 3500 个防洪设施,我想将它们表示为一个网络来确定流动路径(本质上是一个有向图)。我目前正在使用 SqlServer 和 CTE 来递归检查所有节点及其上游组件,只要上游路径没有 fork
谁能告诉我 jquery data() 在哪里存储数据以及何时删除以及如何删除? 如果我用它来存储ajax调用结果,会有性能问题吗? 例如: $("body").data("test", { myDa
有人可以建议如何为 Firebase 存储中的文件设置备份。我能够备份数据库,但不确定如何为 firebase 存储中的文件(我有图像)设置定期备份。 最佳答案 如何进行 Firebase 存储的本地
我最近开始使用 firebase 存储和 firebase 功能。现在我一直在开发从功能到存储的文件上传。 我已经让它工作了(上传完成并且文件出现在存储部分),但是,图像永远保持这样(永远在右侧加载)
我想只允许用户将文件上传到他们自己的存储桶中,最大文件大小为 1MB,仍然允许他们删除文件。我添加了以下内容: match /myusers/{userId}/{allPaths=**} { al
使用生命周期管理策略将容器的内容从冷访问层移动到存档。我正在尝试以下策略,希望它能在一天后将该容器中的所有文件移动到存档层,但事实并非如此在职的。我设置了选择标准“一天未使用后”。 这是 json 代
对于连接到 Azure 存储端点,有 http 和 https 两个选项。 第一。 https 会带来开销,可能是 5%-10%,但我不支付同一个数据中心的费用。 第二。 http 更快,但 Auth
有人可以帮我理解这一点吗?我创建了Virtual Machine in Azure running Windows Server 2012 。我注意到 Azure 自动创建了一个存储帐户。当我进入该存
我是一名优秀的程序员,十分优秀!