vexe / VFW

MIT License
492 stars 67 forks source link

Showing game object name instead of script name for script member variable in inspector #27

Closed colms closed 9 years ago

colms commented 9 years ago

I have a monster called "AngelBaby" (don't ask). He has a script attached called "PouterChaseState" which causes the monster to chase the player character. The "PouterChaseState" does this using a Propulsion subtype, in this case, "ForceBasedPropulsion". I dragged the attached "ForceBasedPropulsion" into the Propulsion slot for the "PouterChaseState" but rather than saying the name of the script ("ForceBasedPropulsion") in that slot as I expected, it says the name of the game object ("AngelBaby").

Screenshot highlighted relevant parts: http://i.imgur.com/hrct0sP.png

Is this a design decision or a bug? I'm treating it as a bug because I'm about to start working on a script that will have a list of Propulsion types and I now won't be able to know which is which in the list because they'll all have the same name after I've dragged them in (in this case "AngelBaby").

ajboni commented 9 years ago

Hey check (this)[https://github.com/vexe/VFW/issues/24]

The way It worked it was like vexe suggested: Override theToString method. This allowed great customization, for example I've used formatMethod to format the Label with an Actor name, and the ToString Method to display a speech string instead of the gameObject Name.

Hope it helps!

colms commented 9 years ago

Thanks. I took your advice and gave this a try but without success:

public class ForceBasedLocomotion : Locomotion
{
    Rigidbody2D rigidBody_;
    [Serialize] float movementForce_;

    ...

    public override string ToString()
    {
        return this.GetType().Name;
    }
}

What am I missing?

ajboni commented 9 years ago

I'm not sure, but I think ForceBasedLocomotion should be a system object in order to work. Maybe you can use Display(FormatMethod)] to format the object's label instead?

Anyways you should wait if Vexe replies. Im still a noob at this.

vexe commented 9 years ago

Hey colms,

unfortunately this is a Unity thing, if you use ObjectField on any non-null unity object, it will just display its name. In the case of Components (thus behaviours) the name property resolves to the gameObject name the component's attached to. But if you use PropertyField and have a serializedProperty wrapping your component field, it will show "GameObjectName (BehaviourType)" (via the internal property.objectReferenceStringValue) which is what you want I suppose. Since I don't deal with serializedProperties I use ObjectField, thus you get this useless display. I'm gonna try and see how to hack my way in. Worst case I could just use the field style I used on System.Objects, gives you total control over the display text, with a custom picker and all that. I would rather not to though but we'll see.

vexe commented 9 years ago

An alternative solution is to include the type name in the label text and use FormatMethod like peladovii suggested, does this work for you?

[Display(FormatMethod = "FormatBehaviour")]
public MonoBehaviour behaviour;

string FormatBehaviour(MonoBehaviour value)
{
    return value == null ? "Behaviour" : "Behaviour (" +  behaviour.GetType().Name + ")";
}

untitled

OK I'm hardcoding "Behaviour" here but I'm just trying to see if this style of display works for you or not. I could for instance pass in the MemberInfo of 'behaviour' so you'd get reusable formatting applied on any UnityEngine.Object, i.e:

string FormatObject(UnityObject value, MemberInfo member)
{
      string display = member.GetNiceName();
      if (value == null)
          return display
      return display + " (" + value.GetType().Name + ")";
}
colms commented 9 years ago

Thank you very much :)