TPC 3.0.14
1. Projectile incorrectly displays m_InternalImpact, m_DefaultImpactDamageData, m_ImpactActionGroup fields twice.
Code to improve this:
Opsive\UltimateCharacterController\Editor\Inspectors\Objects\TrajectoryObjectInspector.cs
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
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.
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:
1. Projectile incorrectly displays m_InternalImpact, m_DefaultImpactDamageData, m_ImpactActionGroup fields twice.
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.
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;
}