Я пытаюсь использовать JsonUtility, но он мало что делает.
using System;
using System.Collections.Generic;
using UnityEditor.Callbacks;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
namespace UnityEditor.TreeViewExamples
{
class CustomHeightWindow : EditorWindow
{
[NonSerialized] bool m_Initialized;
[SerializeField] TreeViewState m_TreeViewState; // Serialized in the window layout file so it survives assembly reloading
SearchField m_SearchField;
static CustomHeightTreeView m_TreeView;
MyTreeAsset m_MyTreeAsset;
SimpleTreeView simple_m_TreeView;
private static int numofconversations = 10;
private static int oldnumofconversations;
[MenuItem("TreeView Examples/Custom Row Heights")]
public static CustomHeightWindow GetWindow()
{
var window = GetWindow<CustomHeightWindow>();
window.titleContent = new GUIContent("Custom Heights");
window.Focus();
window.Repaint();
oldnumofconversations = numofconversations;
CustomHeightTreeView.numberofactive = 0;
return window;
}
protected void OnEnable()
{
var data = EditorPrefs.GetString("CustomHeightWindow", JsonUtility.ToJson(this, false));
// Then we apply them to this window
JsonUtility.FromJsonOverwrite(data, this);
}
protected void OnDisable()
{
// We get the Json data
var data = JsonUtility.ToJson(this, false);
// And we save it
EditorPrefs.SetString("CustomHeightWindow", data);
}
[OnOpenAsset]
public static bool OnOpenAsset(int instanceID, int line)
{
var myTreeAsset = EditorUtility.InstanceIDToObject(instanceID) as MyTreeAsset;
if (myTreeAsset != null)
{
var window = GetWindow();
window.SetTreeAsset(myTreeAsset);
return true;
}
return false; // we did not handle the open
}
void SetTreeAsset(MyTreeAsset myTreeAsset)
{
m_MyTreeAsset = myTreeAsset;
m_Initialized = false;
}
Rect treeViewRect
{
get { return new Rect(20, 70, position.width - 40, position.height - 100); }
}
Rect toolbarRect
{
get { return new Rect(20f, 10f, position.width - 40f, 20f); }
}
Rect bottomToolbarRect
{
get { return new Rect(20f, position.height - 18f, position.width - 40f, 16f); }
}
void InitIfNeeded()
{
if (!m_Initialized)
{
// Check if it already exists (deserialized from window layout file or scriptable object)
if (m_TreeViewState == null)
m_TreeViewState = new TreeViewState();
var treeModel = new TreeModel<MyTreeElement>(GetData());
m_TreeView = new CustomHeightTreeView(m_TreeViewState, treeModel);
m_SearchField = new SearchField();
m_SearchField.downOrUpArrowKeyPressed += m_TreeView.SetFocusAndEnsureSelectedItem;
m_Initialized = true;
}
}
IList<MyTreeElement> GetData()
{
if (m_MyTreeAsset != null && m_MyTreeAsset.treeElements != null && m_MyTreeAsset.treeElements.Count > 0)
return m_MyTreeAsset.treeElements;
// generate some test data
return MyTreeElementGenerator.GenerateRandomTree(numofconversations);
}
void OnSelectionChange()
{
if (!m_Initialized)
return;
var myTreeAsset = Selection.activeObject as MyTreeAsset;
if (myTreeAsset != null && myTreeAsset != m_MyTreeAsset)
{
m_MyTreeAsset = myTreeAsset;
m_TreeView.treeModel.SetData(GetData());
m_TreeView.Reload();
}
}
void OnGUI()
{
if(oldnumofconversations != numofconversations)
{
m_Initialized = false;
oldnumofconversations = numofconversations;
}
InitIfNeeded();
SearchBar(toolbarRect);
DoTreeView(treeViewRect);
BottomToolBar(bottomToolbarRect);
DoFields();
DoTreeView();
}
void SearchBar(Rect rect)
{
m_TreeView.searchString = m_SearchField.OnGUI(rect, m_TreeView.searchString);
}
void DoTreeView(Rect rect)
{
m_TreeView.OnGUI(rect);
}
void BottomToolBar(Rect rect)
{
GUILayout.BeginArea(rect);
using (new EditorGUILayout.HorizontalScope())
{
var style = "miniButton";
if (GUILayout.Button("Expand All", style))
{
m_TreeView.ExpandAll();
}
if (GUILayout.Button("Collapse All", style))
{
m_TreeView.CollapseAll();
}
}
GUILayout.EndArea();
}
void DoFields()
{
DrawBox(new Rect(20, 35, position.width - 40, 30),"", Color.white);
numofconversations = EditorGUI.IntField(new Rect(187, 43, 50, 15), numofconversations);
GUI.Label(new Rect(37, 41, 150, 15), "Number of conversations");
GUI.Label(new Rect(250, 41, 220, 15), "Number of collapsed conversations");
EditorGUI.IntField(new Rect(458, 43, 50, 15), CustomHeightTreeView.numberofactive);
}
void DrawBox(Rect position, string content, Color color)
{
Color oldColor = GUI.color;
GUI.color = color;
GUI.Box(position, content);
GUI.color = oldColor;
}
void DoTreeView()
{
}
}
}
По какой-то причине, когда я закрываю и затем снова открываю окно, он сохраняет переменную numofconversations, но только эту переменную.Если при открытии окна в редакторе я изменю значение numofconversations на 100, в следующий раз я открою окно, и оно будет равно 100.
Но я также хочу сохранить, например, переменную state:
CustomHeightTreeView.numberofactive
Я установил его на 0, но когда его значение изменяется в редакторе, оно не сохраняется.
Это пользовательский сценарий:
using UnityEditor.IMGUI.Controls;
using UnityEngine;
namespace UnityEditor.TreeViewExamples
{
internal class CustomHeightTreeView : TreeViewWithTreeModel<MyTreeElement>
{
public static int numberofactive = 0;
public static bool isactive = false;
static class Styles
{
public static GUIStyle background = "RL Background";
public static GUIStyle headerBackground = "RL Header";
}
public CustomHeightTreeView(TreeViewState state, TreeModel<MyTreeElement> model)
: base(state, model)
{
// Custom setup
showBorder = true;
customFoldoutYOffset = 3f;
Reload();
}
protected override float GetCustomRowHeight (int row, TreeViewItem item)
{
var myItem = (TreeViewItem<MyTreeElement>)item;
if (myItem.data.enabled)
return 85f;
return 30f;
}
public override void OnGUI (Rect rect)
{
// Background
if (Event.current.type == EventType.Repaint)
DefaultStyles.backgroundOdd.Draw(rect, false, false, false, false);
// TreeView
base.OnGUI (rect);
}
protected override void RowGUI (RowGUIArgs args)
{
var item = (TreeViewItem<MyTreeElement>) args.item;
var contentIndent = GetContentIndent (item);
// Background
var bgRect = args.rowRect;
bgRect.x = contentIndent;
bgRect.width = Mathf.Max (bgRect.width - contentIndent, 155f) - 5f;
bgRect.yMin += 2f;
bgRect.yMax -= 2f;
DrawItemBackground(bgRect);
if(item.data.enabled == true && isactive == true)
{
DrawItemBackgroundColor(bgRect);
}
/*if(item.data.enabled == true && isactive == false)
{
isactive = true;
numberofactive++;
DrawItemBackgroundColor(bgRect);
}*/
// Custom label
var headerRect = bgRect;
headerRect.xMin += 5f;
headerRect.xMax -= 10f;
headerRect.height = Styles.headerBackground.fixedHeight;
HeaderGUI (headerRect, args.label, item);
// Controls
var controlsRect = headerRect;
controlsRect.xMin += 20f;
controlsRect.y += headerRect.height;
if (item.data.enabled)
ControlsGUI (controlsRect, item);
}
void DrawItemBackground (Rect bgRect)
{
if (Event.current.type == EventType.Repaint)
{
var rect = bgRect;
rect.height = Styles.headerBackground.fixedHeight;
Styles.headerBackground.Draw(rect, false, false, false, false);
rect.y += rect.height;
rect.height = bgRect.height - rect.height;
Styles.background.Draw(rect, false, false, false, false);
}
}
void DrawItemBackgroundColor(Rect bgRect)
{
if (Event.current.type == EventType.Repaint)
{
Color oldColor = GUI.color;
GUI.color = new Color32(255, 182, 193,100);
var rect = bgRect;
rect.height = Styles.headerBackground.fixedHeight;
Styles.headerBackground.Draw(rect, false, false, false, false);
rect.y += rect.height;
rect.height = bgRect.height - rect.height;
Styles.background.Draw(rect, false, false, false, false);
GUI.color = oldColor;
}
}
void HeaderGUI (Rect headerRect, string label, TreeViewItem<MyTreeElement> item)
{
headerRect.y += 1f;
// Do toggle
Rect toggleRect = headerRect;
toggleRect.width = 16;
EditorGUI.BeginChangeCheck ();
item.data.enabled = EditorGUI.Toggle(toggleRect, item.data.enabled); // hide when outside cell rect
if (EditorGUI.EndChangeCheck())
{
RefreshCustomRowHeights();
if (item.data.enabled == true)
{
isactive = true;
numberofactive++;
}
else
{
numberofactive--;
}
}
Rect labelRect = headerRect;
labelRect.xMin += toggleRect.width + 2f;
GUI.Label (labelRect, label);
}
void ControlsGUI(Rect controlsRect, TreeViewItem<MyTreeElement> item)
{
var rect = controlsRect;
rect.y += 3f;
rect.height = EditorGUIUtility.singleLineHeight;
item.data.floatValue1 = EditorGUI.Slider(rect, GUIContent.none, item.data.floatValue1, 0f, 1f);
rect.y += rect.height + EditorGUIUtility.standardVerticalSpacing;
item.data.material = (Material)EditorGUI.ObjectField(rect, GUIContent.none, item.data.material, typeof(Material), false);
rect.y += rect.height + EditorGUIUtility.standardVerticalSpacing;
item.data.text = GUI.TextField(rect, item.data.text);
}
protected override Rect GetRenameRect (Rect rowRect, int row, TreeViewItem item)
{
// Match label perfectly
var renameRect = base.GetRenameRect (rowRect, row, item);
renameRect.xMin += 25f;
renameRect.y += 2f;
return renameRect;
}
// Rename
//--------
protected override bool CanRename(TreeViewItem item)
{
// Only allow rename if we can show the rename overlay with a certain width (label might be clipped by other columns)
Rect renameRect = GetRenameRect (treeViewRect, 0, item);
return renameRect.width > 30;
}
protected override void RenameEnded(RenameEndedArgs args)
{
// Set the backend name and reload the tree to reflect the new model
if (args.acceptedRename)
{
var element = treeModel.Find(args.itemID);
element.name = args.newName;
Reload();
}
}
}
}
В этомскрипт Я устанавливаю переменную numberofactive в соответствии с количеством включенных в данный момент элементов:
void HeaderGUI (Rect headerRect, string label, TreeViewItem<MyTreeElement> item)
{
headerRect.y += 1f;
// Do toggle
Rect toggleRect = headerRect;
toggleRect.width = 16;
EditorGUI.BeginChangeCheck ();
item.data.enabled = EditorGUI.Toggle(toggleRect, item.data.enabled); // hide when outside cell rect
if (EditorGUI.EndChangeCheck())
{
RefreshCustomRowHeights();
if (item.data.enabled == true)
{
isactive = true;
numberofactive++;
}
else
{
numberofactive--;
}
}
Rect labelRect = headerRect;
labelRect.xMin += toggleRect.width + 2f;
GUI.Label (labelRect, label);
}
Когда окно открывается в редакторе, если я переключаю и сворачиваю, например, 5 элементов, оно обновляет переменную numberofactive до5, а затем, если переключить только 3, то на 3. Но он не сохраняет его.
Это одна переменная, которую он не сохраняет, есть и другие.Например, он не сохраняет также состояния item.enable.Если item.enable имеет значение true или false, он не сохраняет его и не переключает его при первом открытии окна.
Я знаю, что код длинный, но идея заключается в том, чтобы сохранить в окне редактора состояния переменных и визуальные значенияграфический интерфейс.