[Serializable]
public class SomeClass : ScriptableObject{
public OtherClass[] others;
}
[Serializable]
public class OtherClass{
public string name;
// ....
public static OtherClass GenerateOtherClass(){ /* .... */ }
}
and there is a Custom Editor for SomeClass
[CustomEditor(typeof(SomeClass))]
public class SomeClassEditor : UnityEditor.Editor {
public override void OnInspectorGUI() {
var others = serializedObject.FindProperty("others");
// ....
if (GUILayout.Button("Generate")) {
var o = OtherClass.GenerateOther();
/** append o to 'others' **/
}
// ....
sobj.ApplyModifiedProperties();
}
}
I want to add a new OtherClass object to the list of others. note: OtherClass is not a ScriptableObject
edit
to clarify, the question is how do i get every variable/field/member of a Serializable-Object into a Serializeableproperty (structure) without listing every element manually end-edit
would be cool if someone knows a solution for this.
You could use SerializedProperty.InsertArrayElementAtIndex. Note that this will insert an empty object to the array at given index.
if (GUILayout.Button("Generate"))
{
int newIndex = others.arraySize;
others.InsertArrayElementAtIndex(newIndex);
/* you can get the SerializedProperty of your new object using
"others.GetArrayElementAtIndex(newIndex);" if you need to */
}
Well i think i got it myself. Maybe theres some nicer solution. but here is mine:
private void fillPropertyFromObject(SerializedProperty property, object o) {
if(! o.GetType().IsSerializable) throw new ArgumentException("object is not Serializable");
var it = property.Copy();
it.NextVisible(true);
var d = it.depth;
do {
var field = o.GetType().GetField(it.name);
switch (it.propertyType) {
case SerializedPropertyType.Generic:
break;
case SerializedPropertyType.Integer:
it.intValue = (int) field.GetValue(o);
break;
case SerializedPropertyType.Boolean:
it.boolValue = (bool)field.GetValue(o);
break;
case SerializedPropertyType.Float:
it.floatValue = (float)field.GetValue(o);
break;
case SerializedPropertyType.String:
it.stringValue = (string)field.GetValue(o);
break;
default:
throw new NotImplementedException();
}
} while(it.NextVisible(false) && it.depth >= d);
}