Search Unity

Any way to override the default editor for one string in your editor instance?

Discussion in 'Immediate Mode GUI (IMGUI)' started by WizardGameDev, Mar 7, 2015.

  1. WizardGameDev

    WizardGameDev

    Joined:
    Jul 25, 2012
    Posts:
    62
    This is a simplified example of what I'm trying to do.

    I have list of spells in a collection.

    Let's say each spell has three simple fields.

    Name - String
    Effect - String
    Power - Float


    Now I have a collection of simple effects so instead of having to key that effect string into the editor... I want to pick from the list of effects.

    So, I know how I could do this if I built an editor for the entire spell class. But since the spell has a ton of properties and collections... in fact the effect above is really a collection of effects. There are also collections for animations, audio, and even collections of the requirements to learn the spell in the first place. Therefore I don't want to have to code a 200 line editor when the default editor is fine for 90% of it... I just would really like to overrride a few string fields to pick there values from lists.

    Is this possible and what would be the syntax, or an example, if it is?

    Thanks in advance!
     
  2. WizardGameDev

    WizardGameDev

    Joined:
    Jul 25, 2012
    Posts:
    62
    Ok, So I can add more to this and it is naturally more messed up than I had hoped.

    Part of what causes my complexity is I need everything serialized... Well apparently the custom editor stuff breaks apart if you are not basing your classes on monobehavior. Yet if you do that, then you get in a vicious circle.

    The error I'm specifically getting is:

    Assets/Editor/EffectEditor.cs(23,57): error CS0030: Cannot convert type `UnityEngine.Object' to `ParticleEffect'

    From the code:

    ParticleEffect Target = (ParticleEffect)target;

    Now if I change my particle effect class over to a monobehavior I can the inspector to populate the list as I need, but I lose the ability then to serialize the classes out.

    It's a bit of a vicious circle I'm sure others have figured out yet clearly must not be ultra easy because after watching probably 20 different videos and looking at quite a bit of examples nobody seems to want to tackle the combination of both an editor that has multiple collections, can have a custom editor and is serialized.

    Part of it that makes it particularly dissapointing is that I was hoping to allow people who buy the game to customize the spells using the editor. I would basically have a simplified project that lets them save and load spell books. So having tons of text fields to have to key cryptic effect names into it is bad enough when you are working as a developer. But for the end gamer who wants to maybe try some different values its going to be even more painful. So much better if they could just pick an effect from a list... but I'm realizing that I'm getting to the point that hand coding the strings even though prone to error is going to get me back on making the game better rather than messing with this custom editor stuff.
     
  3. WizardGameDev

    WizardGameDev

    Joined:
    Jul 25, 2012
    Posts:
    62
    Well I figured out a way to make it happen.

    The key is property drawers. One thing that tripped me up is when I put the scripts in the editors folder, then that would actually make them stop working.

    This is the script I ended up with. More code that I hoped but it solves problems.

    Code (CSharp):
    1. public class EffectEditor : PropertyAttribute {
    2.         public string[] items;
    3.         public EffectEditor()
    4.         {
    5.         string[] values = new string[EffectLibrary.EffectList.Length];
    6.         for(int i=0;i < EffectLibrary.EffectList.Length ; i++)
    7.             values[i] = EffectLibrary.EffectList[i].name;
    8.             this.items = values;
    9.         }
    10.     }
    11.  
    12.     [CustomPropertyDrawer( typeof( EffectEditor))]
    13.     public class PopupDrawer : PropertyDrawer
    14.     {
    15.         private int textHeight = 16;
    16.         public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    17.         {
    18.             EditorGUI.BeginProperty (position, label, property);
    19.                 int origIndent = EditorGUI.indentLevel;
    20.             string[] values = ((EffectEditor)attribute).items;
    21.             int index = 0;
    22.             for (; index < values.Length ; index++) {
    23.                                 if (values [index].Equals (property.stringValue))
    24.                                         break;
    25.                         }
    26.             EditorGUI.LabelField (new Rect (position.xMin, position.yMin, position.width / 3f, textHeight),
    27.                                  property.name);
    28.             index = EditorGUI.Popup (
    29.                 new Rect (position.xMax / 3f,
    30.                      position.yMin, position.width - (position.width / 3f),
    31.                      textHeight), index, values);
    32.             if (index < values.Length)
    33.                                 property.stringValue = values [index];
    34.             EditorGUI.indentLevel = origIndent;
    35.             EditorGUI.EndProperty ();
    36.  
    37.         }
    38.     }