|
I'm trying to make a simple track editor that uses a Bezier Path to generate a 3d mesh for a friend's racing game. The track data is an array of custom TrackDataPoint objects which store the position, tangent and other properties of each point on the track. Here is the TrackData and TrackDataPoint class code (I removed update functions of TrackData and all the "using" stuff to keep it compact here):
[System.Serializable]
public class TrackDataPoint : MonoBehaviour {
Vector3 position = Vector3.zero;
Vector3 tangentDir = Vector3.right;
float tangentWeightIn = 1.0f;
float tangentWeightOut = 1.0f;
}
[System.Serializable]
public class TrackData : MonoBehaviour {
public TrackDataPoint[] points;
}
In my editor class, I am able to get a custom editor displaying, get a the list of points and get each point into a SerializedProperty object, however, I cannot figure out how to get the data into the list of TrackDataPoints stored in TrackData (points). I can add a new point using the small editor interface I made, but it is not initialized, so just appears as an empty space when I try to display it.
[CustomEditor(typeof(TrackData))]
public class TrackDataEditor : Editor {
private SerializedObject trackData;
private SerializedProperty points;
void OnEnable () {
trackData = new SerializedObject(target);
points = trackData.FindProperty("points");
}
public override void OnInspectorGUI () {
trackData.Update();
//draw GUI for each point
for (int i = 0; i < points.arraySize; ++i) {
EditorGUILayout.BeginHorizontal();
GUILayout.Label(i + ":", GUILayout.MaxWidth(20.0f));
SerializedProperty dataPoint = points.GetArrayElementAtIndex(i);
EditorGUILayout.PropertyField(dataPoint, true);
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Add point")) {
points.array Size++;
// NOW WHAT!? :)
}
EditorGUILayout.EndHorizontal();
trackData.ApplyModifiedProperties();
}
}
How can I create a new TrackDataPoint and assign it to the empty array element from my editor script? If points happens to be a list of standard types, such as Vector3s, this happens automatically. As it is, I get new elements added to the array, but they are empty and display as a drop box for prefabs. If I remove the : MonoBehaviour from TrackDataPoint nothing shows up. Ideally I'd like to display a custom editor per point by having another editor for TrackDataPoint. Is this possible?
(comments are locked)
|
|
Here's the working version using List<>: The basic idea is to get a reference to the object you are editing by using myTrackData = (TrackData)target; That way you can do all the stuff you would normally do with arrays and such and don't have to worry about SerializedProperty at all. So you can add an element by adjusting the array length and adding the new point like you would do outside of the editor. Since you are working on the "target" object, only casted differently, all changes should automatically reflect in the editor. Hope that points you into the right direction, delstrega Wow, I had no idea that that would work! I'll give it a go. Seems kind of obvious now, but I thought target was a serializedObject and it wasn't possible to access the members at all. I was a little annoyed about that because it's normal to access the object directly in the other editor functions (OnSceneGUI etc.) I'll convert the array to a list and add some code to make working with it from the editor class easier and then everything should be hunky dory. Thanks!
Jun 23 '12 at 12:56 PM
AndyP
Yea, you can access your class as normal just casting "target". But now that I tested the code I posted it must say that it won't work like that. I'll try to fix the bugs and edit my answers to reflect the changes. Stay tuned ;)
Jun 23 '12 at 01:15 PM
delstrega
Tested it and you're right! It works perfectly. I spent so long looking at the docs for SerializedProperty and SerializedObject and completely overlooked the target parameter of Editor. DOH!
Jun 23 '12 at 01:25 PM
AndyP
Haha, I'm glad it's working for you. I spent the last 30 minutes trying to get the code I to work. Well I edited my above post in case anyone is interested. :) You're welcome AndyP :D
Jun 23 '12 at 01:42 PM
delstrega
I have a question. Who actually instanciateS the "points" List in TrackData?
Feb 06 at 09:32 PM
fwalker
(comments are locked)
|

And there is some reason, in the future, why you need this custom GUI? - Because the standard GUI would edit your objects in an array without and allow you to add ones...
It's not actually something I desperately need to do, as displaying the points in the inspector is not something that will make for a nice editing experience. I will add an interactive editor in the scene view to make things easy. However, I don't like not knowing how to do things so I am trying to learn.
Also, the standard editor shows an empty array. I can't initialize new objects - I have to drag them in from a prefab, which is definitely NOT the way I want to add them.