- Home /
Getting component variables in InitializeOnLoad editor script?
I have a script that I'm trying to run in editor and I have some objects that have a component with data that I want. This is the simple component that is on target objects and I have already set the public string to have a value in the inspector:
[DisallowMultipleComponent]
public class HierarchyLabelAssignment : MonoBehaviour {
public string label;
}
The issue is in my editor script that has InitializeOnLoad, inside of its constructor, I can manage to retrieve that component just fine, but any value that the variable has is null even if it has a previously set value.
[InitializeOnLoad]
public static class HierarchyWindow {
// --- Initialization
static HierarchyWindow() {
GameObject test = GameObject.Find("Main Camera");
HierarchyLabelAssignment labelAssignment = test.GetComponent<HierarchyLabelAssignment>();
if (labelAssignment != null) {
Debug.Log("TEST: " + labelAssignment.label);
}
}
}
Every time I modify the script, the HierarchyWindow "function" is called again obviously. I just can't figure out why the labelAssignment.label is null when it clearly isn't in the inspector.
Any ideas? I don't do a whole lot of editor coding usually.
Answer by felipin · Jul 09, 2018 at 11:55 PM
Use SerializedObject and SerializedProperty.
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public static class HierarchyWindow {
// --- Initialization
static HierarchyWindow() {
GameObject test = GameObject.Find("Main Camera");
HierarchyLabelAssignment labelAssignment = test.GetComponent<HierarchyLabelAssignment>();
if (labelAssignment) {
SerializedObject serializedObject = new SerializedObject(labelAssignment);
SerializedProperty serializedProperty = serializedObject.FindProperty("label");
Debug.Log("TEST: " + serializedProperty.stringValue);
}
}
}
That code is looking very promising, but serializedProperty.stringValue is still being printed as an empty string... I'll look into it some more.
Okay, yeah, this way seems to work only if the label variable in the small HierarchyLabelAssignment is initialized inside of the script, so:
public class HierarchyLabelAssignment : $$anonymous$$onoBehaviour {
public string label = "my test";
}
That will work and print out the value with the code you posted. But since that value isn't initialized in the class, it isn't printing out I guess.
Thats a little bit weird I've tried it and works fine, the printed string was the same value as in inspector. i dont think so but you can try use the method SerializedObject.Update right after instantiated it.
Alright, after a fair amount of research, I believe I can clarify my issue. Using the method you described in your code, that will retrieve the serialized value of that variable (not sure I'm totally using the word right). The value that is serialized though is whatever the variable is initialized with. This seems to match the behavior I am getting. When I ask for the value of the SerializedProperty, I am getting that initial value. So, my focused question would be: how do I update that serialized value of the variable? I've looked in to SerializedObject.Apply$$anonymous$$odifiedProperties() and SerializedObject.Update() but nothing seems to work. Here is my code at the moment (testing code):
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
// Placed on "$$anonymous$$ain Camera" for testing
[ExecuteInEdit$$anonymous$$ode]
public class SerializationTest : $$anonymous$$onoBehaviour {
public string newLabel = "Blue";
public bool changeButton = false; // A "button" for the inspector (just for quick testing)
public void Update() {
if (changeButton == true) {
Debug.Log("Changing Label");
EditorScript.SetSerializedValue(newLabel);
changeButton = false;
}
}
}
[InitializeOnLoad]
public static class EditorScript {
private static GameObject mainCam;
private static HierarchyLabelAssignment monoScript;
// --- Initialization
static EditorScript() {
mainCam = GameObject.Find("$$anonymous$$ain Camera");
monoScript = mainCam.GetComponent<HierarchyLabelAssignment>();
PrintSerializedValue();
}
public static void SetSerializedValue(string newLabel) {
if (monoScript) {
monoScript.label = newLabel;
// --- Can't figure out how to save the changed variable!
SerializedObject serializedObject = new SerializedObject(monoScript);
SerializedProperty serializedProperty = serializedObject.FindProperty("label");
serializedObject.Apply$$anonymous$$odifiedProperties();
EditorUtility.SetDirty(monoScript);
}
}
public static void PrintSerializedValue() {
if (monoScript) {
SerializedObject serializedObject = new SerializedObject(monoScript);
SerializedProperty serializedProperty = serializedObject.FindProperty("label");
Debug.Log("Label = " + serializedProperty.stringValue);
}
}
}
Every time I use the little toggle button in the inspector out of play mode to set the label variable, it seems to set it visually. However, when I go back into the code, make a change, and trigger a recompile, the printed label is still an empty string.