Suggestions for improving the editor inspector

WeiYiHua

Member
TPC 3.0.14

1. Projectile incorrectly displays m_InternalImpact, m_DefaultImpactDamageData, m_ImpactActionGroup fields twice.1691770467992.png

Code to improve this:
Opsive\UltimateCharacterController\Editor\Inspectors\Objects\TrajectoryObjectInspector.cs

Code:
// Adding the fields is required otherwise they won't be initialized properly.
for (int i = 0; i < m_ShowOnCollisionModeReflect.Count; i++) {
    m_ImpactFoldout.Add(m_ShowOnCollisionModeReflect[i]);
}
for (int i = 0; i < m_ShowOnCollisionModeCollide.Count; i++) {
    m_ImpactFoldout.Add(m_ShowOnCollisionModeCollide[i]);
}
if (target is ProjectileBase) {
    m_ExcludeFields.Add("m_InternalImpact");
    m_ExcludeFields.Add("m_DefaultImpactDamageData");
    m_ExcludeFields.Add("m_ImpactActionGroup");
    m_ImpactFoldout.Add(GetPropertyField("m_InternalImpact"));
    m_ImpactFoldout.Add(GetPropertyField("m_DefaultImpactDamageData"));
    m_ImpactFoldout.Add(GetPropertyField("m_ImpactActionGroup"));
}

var audioFoldout = PropertiesFoldout(container, "Audio", m_ExcludeFields, new[]
{
    "m_ActiveAudioClipSet",
});

2. Prefabs with TrajectoryObject scripts are incorrectly set to Dirty every time they are opened.

Code to improve this:
Opsive\UltimateCharacterController\Editor\Inspectors\Objects\TrajectoryObjectInspector.cs
Code:
    // Show certain fields depending on the value of the collision mode.
    var collisionModeField = GetPropertyField("m_CollisionMode");
    m_ImpactFoldout.Add(collisionModeField);
    collisionModeField.RegisterValueChangeCallback(ctx =>
    {
        var newValue = ctx.changedProperty.enumValueIndex;
        OnCollisionModeChange((TrajectoryObject.CollisionMode)newValue, true);
    });

...

    var curveFoldout = PropertiesFoldout(container, "Curve", m_ExcludeFields, new[]
    {
        "m_MaxPositionCount",
    });

    OnCollisionModeChange((target as TrajectoryObject)?.Collision ?? TrajectoryObject.CollisionMode.Collide, false);
}

/// <summary>
/// The collision mode has changed.
/// </summary>
/// <param name="newValue">The new Collision mode.</param>
/// <param name="setDirty">Whether to mark the target as dirty.</param>
private void OnCollisionModeChange(TrajectoryObject.CollisionMode newValue, bool setDirty)
{
    var showReflect = newValue != TrajectoryObject.CollisionMode.Collide && newValue != TrajectoryObject.CollisionMode.Ignore;
    var showCollide = newValue == TrajectoryObject.CollisionMode.Collide;
    
    for (int i = 0; i < m_ShowOnCollisionModeReflect.Count; i++) {
        m_ShowOnCollisionModeReflect[i].style.display = showReflect ? DisplayStyle.Flex : DisplayStyle.None;
    }

    for (int i = 0; i < m_ShowOnCollisionModeCollide.Count; i++) {
        m_ShowOnCollisionModeCollide[i].style.display = showCollide ? DisplayStyle.Flex : DisplayStyle.None;
    }

    if (setDirty)
    {
        Shared.Editor.Utility.EditorUtility.SetDirty(target);
    }
}

3. Provide GenericReorderableList<T> with more things that subclasses can control.
In my example, change some methods to protected virtual, add m_PropertiesToExclude to exclude fields that are not displayed, and the DrawModule method returns whether the drawing is successful.

1691771563821.png

4. AnimatorAudioStateSetControl's Foldout text is displayed as the field name, preventing multiple AnimatorAudioStateSet fields from displaying the same name on the inspector

Code to improve this:
Code:
/// <summary>
/// Returns the control that should be used for the specified ControlType.
/// </summary>
/// <param name="input">The input to the control.</param>
/// <returns>The created control.</returns>
protected override VisualElement GetControl(TypeControlInput input)
{
    var container = new Foldout() { text = ObjectNames.NicifyVariableName(input.Field.Name) };
    AddSelector(input.UnityObject, input.Value, container, (o) => { input.OnChangeEvent(o); });
    AddAudioStateSetList(input.UnityObject, input.Value, container, (o) => { input.OnChangeEvent(o); });
    return container;
}
 
5. Prefabs with CameraController scripts are incorrectly set to Dirty every time they are opened.

Code to improve this:
Opsive\UltimateCharacterController\Editor\Inspectors\Camera\CameraControllerInspector.cs
1692010576874.png
 
6. Compiler warning CS0649 in FoldoutListView.

To fix this warning:
Opsive\UltimateCharacterController\Editor\Inspectors\Inventory\FoldoutListView.cs
Code:
public class FoldoutListView: VisualElement
{
    protected IList m_List;
    protected List<FoldoutListViewElement> m_ElementList;
    
    private VisualElement m_Header;
    private VisualElement m_Content;
    private Label m_EmptyListNotice;
    private ScrollView m_ScrollView = null;
    public ScrollView ScrollView => m_ScrollView;
 
Just giving you a heads up that I have made these changes for the next update. Thanks for letting me know.
 
Thank you for improving these codes in the 3.0.15 update, but I have found an issue. The content suggested in the third item should be added to GenericReorderableList<T> instead of CharacterItemActionModuleGroupField. GenericReorderableList<T> is the base class that should be inherited.
 
Last edited:
Top