W.U. 2: Editing Game Data

This is weekly update number 2. That previous weekly update was just a bonus.

So I had been working on the data representation of melee attacks. I thought it was a good time to make a nice editor front-end for editing them:

This is the nice thing with Unity, you can extend the editor GUI yourself since it’s quite modular in showing data (i.e. components). That MeleeLimits is a ScriptableObject type of class.

What is that for? Its an idea I had in my old version of Tactics Ensemble.

But since I’ve neglected to put proper polish on the current incarnation, it looks like this right now:

I’ll have to explain what all that is in another post.

Back to the editor GUI: But then, whenever I edit the source code of my editor GUI script, that particular MeleeLimits file being shown gets its data reset. All that data, gone. I have a hunch I’m just doing things wrong.

However, I realized if I am to support my goal of letting the game be moddable, the game data has to be in a readable, open-standard text file format (i.e. JSON or YAML).

So I think I’m going to have to give up the nice front-end GUI and ScriptableObject. If only there was a way to let Unity read text files and allow the editing of them using Editor GUI scripts… I actually could, using EditorWindow. And I think I can still use the Editor script using my MonoBehaviour class (ActionMelee).

The equivalent of that data in JSON is this:

{
  "Omnidirectional" : "True",

  "Front" : {
    "Angle" : 0,
    "MinRange" : 0,
    "Ranges" : [{
      "Range" : 2,
      "AnimationName" : "HeadButt",
      "BaseDamage" : 10
    },{
      "Range" : 5,
      "AnimationName" : "DashKick",
      "BaseDamage" : 20
    }]
  },

  "HasSideLimits" : "False",
  "SideLimitType" : "BothEven",

  "Side" : {
    "Angle" : 0,
    "MinRange" : 0,
    "Ranges" : []
  },

  "Right" : {
    "Angle" : 0,
    "MinRange" : 0,
    "Ranges" : []
  },

  "HasBackLimits" : "False",

  "Back" : {
    "Angle" : 0,
    "MinRange" : 0,
    "Ranges" : []
  }
}

Here’s the equivalent in YAML:

Omnidirectional: true

Front:
  Angle: 0
  MinRange: 0
  Ranges:
    - Range: 2
      AnimationName: "HeadButt"
      BaseDamage: 10
    - Range: 5
      AnimationName: "DashKick"
      BaseDamage: 20

HasSideLimits: false
SideLimitType: BothEven

Side:
  Angle: 0
  MinRange: 0
  Ranges: []

Right:
  Angle: 0
  MinRange: 0
  Ranges: []

HasBackLimits: false

Back:
  Angle: 0
  MinRange: 0
  Ranges: []

I admit the YAML version is more readable.

Just for kicks, here’s how it looks like in XML:

<Omnidirectional>true</Omnidirectional>

<Front>
  <Angle>0</Angle>
  <MinRange>0</MinRange>
  <Ranges>
    <Range>
      <Range>2</Range>
      <AnimationName>HeadButt</AnimationName>
      <BaseDamage>10</BaseDamage>
    </Range>
    <Range>
      <Range>5</Range>
      <AnimationName>DashKick</AnimationName>
      <BaseDamage>20</BaseDamage>
    </Range>
  </Ranges>
</Front>

<HasSideLimits>false</HasSideLimits>
<SideLimitType>BothEven</SideLimitType>

<Side>
  <Angle>0</Angle>
  <MinRange>0</MinRange>
  <Ranges></Ranges>
</Side>

<Right>
  <Angle>0</Angle>
  <MinRange>0</MinRange>
  <Ranges></Ranges>
</Right>

<HasBackLimits>false</HasBackLimits>

<Back>
  <Angle>0</Angle>
  <MinRange>0</MinRange>
  <Ranges></Ranges>
</Back>

Its… how should I say this, I need some syntax coloring to be able to get that in a glance, as opposed to the JSON or YAML versions.

Because JSON serializing/deserializing is reported to be faster than YAML, I think I can live with JSON since I don’t use the more advanced features of YAML anyway.

Advertisements

5 thoughts on “W.U. 2: Editing Game Data

    • Yes it was a ScriptableObject. I have a MonoBehaviour script called ActionMelee (look at the 2nd image in this post, see the MonoBehaviour above the red outline) that has MeleeLimits as one of its variables.

      Then I have an Editor script for ActionMelee that displays the MeleeLimits on the Inspector (and allow editing).

      But now I’ve turned it into a JSON text file. To Unity, its a TextAsset, but the idea remains. The Editor script parses the JSON file and displays the contents, and allow editing (it overwrites the JSON file via Mono’s System.IO functions).

      • Thanks for your response! Out of interest the custom editor that is shown for `MeleeLimits`, is that just rendered as part of `ActionMeleeEditor.OnInspectorGUI` or do you have a custom editor for `MeleLimits` as well?

        I am assuming that you are using `EditorGUILayout.InspectorTitlebar`. If you are using two custom editors to achieve what is shown in the screenshot I would love to know how!

        I have a scenario where I would like to be able to display the custom editors of various components (not my own) into a custom `EditorWindow`, but the only way that I can find to achieve this requires undocumented functionality `UnityEditor.ActiveEditorTracker.MakeCustomEditor `.

        I have posted about this in the forums with no response (http://forum.unity3d.com/threads/37514-SerializedObject-and-SerializedProperty) as numberkruncher.

      • Yes, the part that shows MeleeLimits is done by ActionMeleeEditor.OnInspectorGUI.

        Actually that image was when I was using a ScriptableObject, so yeah, in that image I was using InspectorTitlebar. Now that I’m using a TextAsset, I just use EditorGUILayout.Foldout.

        What I do is, my code for displaying a MeleeLimits is put into a static function that takes in a MeleeLimits, so now, any of my editor code can display a MeleeLimits.

        But if the custom editors you want to display aren’t stuff you made yourself, I can see that could be a problem, if you don’t want to edit those scripts (or if they are built-in Unity components).

        So you’re essentially trying to aggregate all the OnInspectorGUI’s of those custom editors into one EditorWindow?

        Unfortunately I haven’t dabbled that much into editor scripting. But it looks like you got something running, from what I can see in the forum thread.

        So from what I understand of the original problem in the thread, he’s tring to expose a class’ properties right? And he wants it to be automated, not have to type down each property/variable by hand, is that correct? A class’ properties can probably be looped through via Mono’s System.Reflection functions. You can even edit a class’ private variables that way. I have some sample code to do that if you want.

  1. Essentially yes, I am working on a tile system and have created a brush designer window that allows people to design the tiles that they paint with. It would be neat if I could integrate the custom editors of certain components into the window with an “Add Component” menu.

    Enumerating the properties of existing components doesn’t actually need reflection because you can enumerate them using SerializedObject and SerializedProperty. But, unfortunately this ignores the custom editors.

    When I read your blog post I was hoping that you knew a way around this. I have put a request on the feedback site (http://feedback.unity3d.com/forums/15792-unity/suggestions/2948619-document-unityeditor-activeeditortracker-makecust) so I’ll just have to wait until somebody from Unity responds.

    Thank you for taking the time to respond, much appreciated!

    You have a great blog, I will be checking back!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s