I am attempting to dynamically use values derived from one array, on name labels in a custom editor window for another array. Which works fine. But to display each target array value I use this code:
EditorGUILayout.FloatField(m_target.weights*);
*
I suspect that targeting a value inside the array is causing trouble. The trouble is that the editing box for each array index looks editable, but reverts to the original array value when focus is lost (or enter is pressed).
!(https://i.imgur.com/hBxpza0.png)
In case it would be useful - here is the code for the entire custom inspector class
[CustomEditor(typeof(HeightToTileType))]
public class HeightToTileTypeEditor : Editor
{
-
private HeightToTileType m_target;*
-
void OnEnable()*
-
{*
-
m_target = (HeightToTileType)target;*
-
}*
-
private int spriteCount = 0;*
-
private bool IsSpriteCountChanged()*
-
{*
-
return spriteCount != m_target.sprites.sprites.Length;*
-
}*
-
public override void OnInspectorGUI()*
-
{*
-
int length = m_target.sprites.sprites.Length;*
-
if(IsSpriteCountChanged())*
-
{*
-
float[] weights = new float[length];*
-
m_target.weights = weights;*
-
spriteCount = length;*
-
}*
-
EditorGUILayout.LabelField("Tile Weights");*
-
EditorGUILayout.Space();*
-
for(int i = 0; i < length; i++)*
-
{*
-
EditorGUILayout.BeginHorizontal();*
EditorGUILayout.LabelField(m_target.sprites.sprites*.name);
EditorGUILayout.FloatField(m_target.weights);
_ EditorGUILayout.EndHorizontal();
}
DrawDefaultInspector();
}
}*_
Hi there, I read through your question, since I don’t know what you trying to implement so I will provide 2 ways to fix this.
- In case you just want to see the meaning of array, you don’t want this element to be editable. (I think of this because of this phrase:
The trouble is that the editing box for each array index looks editable
so I thought you may want this field not editable)
for(int i = 0; i < length; i++)
{
EditorGUILayout.BeginHorizontal();
// I added this line
GUI.enable = false;
EditorGUILayout.LabelField(m_target.sprites.sprites*.name);*
EditorGUILayout.FloatField(m_target.weights*);
_// and this line*_
GUI.enable = true;
EditorGUILayout.EndHorizontal();
}
1. You want this value editable and by some way, you will update your m_target.weigh array later, then you can try this:
float[] m_tempWeights = null;
void OnEnable(){
// Add these lines of code after your code
m_tempWeights = m_target.weight;
}
void OnInspectorGUI(){
// replace your for with these codes,
// Note: this script will error or not right in case you change your m_target.weights array lengh.
// Since I don’t know exactly what you are doing with this HeighToTileType so I just provide you
// a fix within your design
for (int i = 0; i < length; i++)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(m_target.sprites.sprites*.name)
float value = Mathf.Approximately(m_tempWeights, m_target.weights) ? m_target.weights : m_tempWeights;
EditorGUILayout.FloatField(value);
EditorGUILayout.EndHorizontal();
_}
}
Now I will explain why your variable reset. To understand this problem, if you interesting in Unity IMGUI system, you can take a look at [this][1]. Bunny83 has provided a very detail explanation about IMGUI. The reason why it reset when lost focus or press enter is because of OnInspectorGUI update every “frame” of Unity editor (unity editor don’t have frame definition) end each time it’s updated, in your case, it will just display your m_target.weights original value, nothing of your updated cached, (that’s why it’s call IMGUI - Immediate Mode GUI). So my second solution is just simply to cache your updated value. You have to update back that temp value to your original array.
Hope this helped you. Sorry for my poor English.
Vince
[1]: https://answers.unity.com/questions/360901/editor-timeline-create-his-personnal-gui-timeline-.html?childToView=360910#answer-360910*_