浏览代码

Pingable Editors for most Ingredients (Event/Logic/Actions/State Machines) (#42)

* Renamed Folder

* Base Factorization for Editors

* BreadcrumbBar Base Work

* Improved UI

* Added Ping Upon Selection (Still lacking pingable editors for StateMachine and State)

* Sorting Files

* Added State/StateMachine Inspectors

* Work on GetDefaultName

* More Action GetDefaultNames

* Logic GetDefaultNames

* Side Panel in IngredientEditor

* Panel Scrolling

* Better Handling of Ingredients Explorer Inspector
/main
GitHub 3 年前
当前提交
19f5b2e6
共有 77 个文件被更改,包括 1145 次插入28 次删除
  1. 8
      CHANGELOG.md
  2. 3
      Editor/CustomInspectors/PingableEditor.cs
  3. 104
      Editor/IngredientsExplorer/IngredientsExplorerWindow.cs
  4. 1
      Editor/PropertyDrawers/CallablePropertyDrawer.cs
  5. 4
      Runtime/LevelScripting/Actions/ApplicationExitAction.cs
  6. 5
      Runtime/LevelScripting/Actions/AttachToObjectAction.cs
  7. 7
      Runtime/LevelScripting/Actions/AudioMixParameterAction.cs
  8. 8
      Runtime/LevelScripting/Actions/AudioMixParameterCurveAction.cs
  9. 7
      Runtime/LevelScripting/Actions/AudioMixSnapshotAction.cs
  10. 9
      Runtime/LevelScripting/Actions/AudioPlayClipAction.cs
  11. 4
      Runtime/LevelScripting/Actions/CursorAction.cs
  12. 2
      Runtime/LevelScripting/Actions/CycleResolutionsAction.cs
  13. 2
      Runtime/LevelScripting/Actions/CycleWindowModeAction.cs
  14. 4
      Runtime/LevelScripting/Actions/DestroyObjectAction.cs
  15. 5
      Runtime/LevelScripting/Actions/DirectorControlRigAction.cs
  16. 4
      Runtime/LevelScripting/Actions/FocusUIAction.cs
  17. 6
      Runtime/LevelScripting/Actions/FullScreenFadeAction.cs
  18. 19
      Runtime/LevelScripting/Actions/GameLevelLoadAction.cs
  19. 5
      Runtime/LevelScripting/Actions/GameManagerSendStartupMessageAction.cs
  20. 5
      Runtime/LevelScripting/Actions/GameSaveLoadSaveAction.cs
  21. 13
      Runtime/LevelScripting/Actions/GameSaveSetValueAction.cs
  22. 5
      Runtime/LevelScripting/Actions/LogAction.cs
  23. 5
      Runtime/LevelScripting/Actions/RandomToggleGameObjectAction.cs
  24. 5
      Runtime/LevelScripting/Actions/ReachPositionRigSetTargetAction.cs
  25. 5
      Runtime/LevelScripting/Actions/RigidbodyAction.cs
  26. 5
      Runtime/LevelScripting/Actions/SendMessageAction.cs
  27. 24
      Runtime/LevelScripting/Actions/SetAnimatorParameterAction.cs
  28. 5
      Runtime/LevelScripting/Actions/SetRandomSeedAction.cs
  29. 5
      Runtime/LevelScripting/Actions/SetTimeScaleAction.cs
  30. 10
      Runtime/LevelScripting/Actions/SpawnPrefabAction.cs
  31. 5
      Runtime/LevelScripting/Actions/StreamingLevelAction.cs
  32. 2
      Runtime/LevelScripting/Actions/SwitcherAction.cs
  33. 5
      Runtime/LevelScripting/Actions/TakeScreenshotAction.cs
  34. 5
      Runtime/LevelScripting/Actions/TeleportGameObjectAction.cs
  35. 5
      Runtime/LevelScripting/Actions/TimelineControlAction.cs
  36. 5
      Runtime/LevelScripting/Actions/ToggleBehaviourAction.cs
  37. 5
      Runtime/LevelScripting/Actions/ToggleGameObjectAction.cs
  38. 5
      Runtime/LevelScripting/Actions/ToggleUIAction.cs
  39. 5
      Runtime/LevelScripting/Actions/UnityEventAction.cs
  40. 5
      Runtime/LevelScripting/Actions/VFXSendEventAction.cs
  41. 4
      Runtime/LevelScripting/Actions/VFXSetPropertyAction.cs
  42. 1
      Runtime/LevelScripting/Callable.cs
  43. 2
      Runtime/LevelScripting/Events/OnAwakeEvent.cs
  44. 7
      Runtime/LevelScripting/Logic/DelayedLogic.cs
  45. 5
      Runtime/LevelScripting/Logic/FlipFlopLogic.cs
  46. 5
      Runtime/LevelScripting/Logic/NTimesLogic.cs
  47. 5
      Runtime/LevelScripting/Logic/NextFrameLogic.cs
  48. 5
      Runtime/LevelScripting/Logic/PlatformLogic.cs
  49. 5
      Runtime/LevelScripting/Logic/RandomLogic.cs
  50. 21
      Runtime/LevelScripting/Logic/SaveDataLogic.cs
  51. 5
      Runtime/LevelScripting/Logic/SaveDataSwitchOnIntLogic.cs
  52. 5
      Runtime/LevelScripting/Logic/SetInstigatorFromFactoryLogic.cs
  53. 5
      Runtime/LevelScripting/Logic/SetInstigatorLogic.cs
  54. 12
      Runtime/LevelScripting/Logic/StateLogic.cs
  55. 58
      Documentation~/Images/BreadCrumb.afphoto
  56. 42
      Editor/CustomInspectors/ActionBaseEditor.cs
  57. 11
      Editor/CustomInspectors/ActionBaseEditor.cs.meta
  58. 35
      Editor/CustomInspectors/EventBaseEditor.cs
  59. 11
      Editor/CustomInspectors/EventBaseEditor.cs.meta
  60. 141
      Editor/CustomInspectors/IngredientEditor.cs
  61. 11
      Editor/CustomInspectors/IngredientEditor.cs.meta
  62. 43
      Editor/CustomInspectors/LogicBaseEditor.cs
  63. 11
      Editor/CustomInspectors/LogicBaseEditor.cs.meta
  64. 73
      Editor/CustomInspectors/RigEditor.cs
  65. 35
      Editor/CustomInspectors/StateEditor.cs
  66. 11
      Editor/CustomInspectors/StateEditor.cs.meta
  67. 35
      Editor/CustomInspectors/StateMachineEditor.cs
  68. 11
      Editor/CustomInspectors/StateMachineEditor.cs.meta
  69. 30
      Editor/PropertyDrawers/CallableNamePropertyDrawer.cs
  70. 11
      Editor/PropertyDrawers/CallableNamePropertyDrawer.cs.meta
  71. 42
      Icons/BreadCrumb.png
  72. 108
      Icons/BreadCrumb.png.meta
  73. 7
      Runtime/Attributes/CallableNameAttribute.cs
  74. 11
      Runtime/Attributes/CallableNameAttribute.cs.meta
  75. 8
      Editor/Rigs.meta
  76. 0
      /Editor/CustomInspectors/RigEditor.cs.meta

8
CHANGELOG.md


## 2020.2.4
#### Fixed
#### Added
* CheckWindow: Better search for referenced objects in scene
* Custom Pingable Inspectors for Events, Logic, Actions, State Machines and States.
* Better Automatic Naming for Logic and Actions.
* CheckWindow: Better search for referenced objects in scene
* Obsoleted **SwitcherAction** (left over from the old world)
## 2020.2.3

3
Editor/CustomInspectors/PingableEditor.cs


{
public abstract class PingableEditor : NaughtyInspector
{
public bool needRepaint { get => m_pingValue > 0; }
float m_pingValue;
static MonoBehaviour m_NextToPing;

public override void OnInspectorGUI()
{
Rect r = EditorGUILayout.BeginVertical();
bool needRepaint = UpdatePing(r);
UpdatePing(r);
OnInspectorGUI_PingArea();

104
Editor/IngredientsExplorer/IngredientsExplorerWindow.cs


s_Instance.SelectItem(selected);
}
const int PANEL_WIDTH = 400;
const int MIN_WIDTH = PANEL_WIDTH+60;
const string kPref = "GameplayIngredients.IngredientsExplorer.ShowPanel";
static bool showPanel
{
get => EditorPrefs.GetBool(kPref, false);
set => EditorPrefs.SetBool(kPref, value);
}
public static IngredientsExplorerWindow instance
{
get
{
if (s_Instance == null)
s_Instance = GetWindow<IngredientsExplorerWindow>();
return s_Instance;
}
}
[SerializeField]
static IngredientsExplorerWindow s_Instance;
private void OnDisable()

});
menu.DropDown(buttonRect);
}
if(position.width > MIN_WIDTH)
showPanel = GUILayout.Toggle(showPanel, "...", EditorStyles.toolbarButton);
Rect r = GUILayoutUtility.GetRect(position.width, position.height - tbHeight);
m_TreeView.OnGUI(r);
using(new GUILayout.HorizontalScope())
{
Rect r = GUILayoutUtility.GetRect(position.width - PANEL_WIDTH, position.height - tbHeight);
m_TreeView.OnGUI(r);
if (position.width > MIN_WIDTH && showPanel)
{
PanelGUI();
}
}
}
static void SetEditorFor(MonoBehaviour bh)
{
if (bh == null)
s_Editor = null;
s_Editor = UnityEditor.Editor.CreateEditor(bh);
}
[SerializeField]
static UnityEditor.Editor s_Editor;
[SerializeField]
static Vector2 s_panelScroll;
void PanelGUI()
{
using(new GUILayout.HorizontalScope())
{
Rect r = GUILayoutUtility.GetRect(1, 1, GUILayout.Width(1), GUILayout.ExpandHeight(true));
EditorGUI.DrawRect(r, Color.black);
using(new GUILayout.VerticalScope(GUILayout.Width(PANEL_WIDTH)))
{
s_Editor?.DrawHeader();
using (new GUILayout.HorizontalScope(GUILayout.ExpandHeight(true)))
{
GUILayout.Space(16);
using (new GUILayout.VerticalScope())
{
s_panelScroll = GUILayout.BeginScrollView(s_panelScroll);
GUILayout.Space(4);
s_Editor?.OnInspectorGUI();
GUILayout.EndScrollView();
}
GUILayout.Space(4);
if (s_Editor is PingableEditor)
{
if ((s_Editor as PingableEditor).needRepaint)
{
Repaint();
}
}
}
}
}
}
void SelectItem(MonoBehaviour target)

listRoot.Add(GetNode(item, stack));
}
}
}
CallTreeNode GetNode(MonoBehaviour bhv, Stack<object> stack)

if(m_Bindings[selectedIds[0]].Target != null)
{
var node = m_Bindings[selectedIds[0]];
Selection.activeObject = node.Target;
if (node.Type == CallTreeNodeType.Rig)
RigEditor.PingObject(node.Target as Rig);
if (!(showPanel && instance.position.width > MIN_WIDTH))
{
Selection.activeObject = node.Target;
if (node.Type == CallTreeNodeType.Rig
|| node.Type == CallTreeNodeType.Action
|| node.Type == CallTreeNodeType.Logic
|| node.Type == CallTreeNodeType.Event
|| node.Type == CallTreeNodeType.StateMachine
|| node.Type == CallTreeNodeType.State
)
{
PingableEditor.PingObject(node.Target);
}
}
else
SetEditorFor(node.Target);
}
}

1
Editor/PropertyDrawers/CallablePropertyDrawer.cs


if (GUI.Button(gotoRect, ">"))
{
Selection.activeObject = property.objectReferenceValue;
PingableEditor.PingObject(Selection.activeObject as MonoBehaviour);
}
if (GUI.Button(pickRect, (property.objectReferenceValue as Callable).Name, EditorStyles.popup))

4
Runtime/LevelScripting/Actions/ApplicationExitAction.cs


Application.Quit();
#endif
}
public override string GetDefaultName()
{
return $"Exit Application";
}
}
}

5
Runtime/LevelScripting/Actions/AttachToObjectAction.cs


attachment.transform.parent = null;
}
}
public override string GetDefaultName()
{
return $"{action} : {(AttachInstigator?"instigator":"objects")} to '{parentObject?.name}'";
}
}
}

7
Runtime/LevelScripting/Actions/AudioMixParameterAction.cs


{
public AudioMixer AudioMixer;
public string Parameter;
public string Parameter = "Parameter";
public float Value;
public float InterpDuration = 0;

{
throw new InvalidOperationException("Parameter " + parameter + " does not exist on target AudioMixer : " + mixer.name);
}
}
public override string GetDefaultName()
{
return $"Set Mixer Param:'{Parameter}' to {Value} ({InterpDuration})s";
}
}
}

8
Runtime/LevelScripting/Actions/AudioMixParameterCurveAction.cs


{
public AudioMixer AudioMixer;
public string Parameter;
public AnimationCurve Curve;
public string Parameter = "Parameter";
public AnimationCurve Curve = AnimationCurve.Linear(0,0,1,1);
public float InterpDuration = 2.0f;
public UnityEvent OnInterpComplete;

yield return new WaitForEndOfFrame();
onInterpComplete.Invoke();
}
public override string GetDefaultName()
{
return $"Set Mixer Curve Param:'{Parameter}' ({InterpDuration})s";
}
}

7
Runtime/LevelScripting/Actions/AudioMixSnapshotAction.cs


public override void Execute(GameObject instigator = null)
{
Mixer.TransitionToSnapshots(new AudioMixerSnapshot[]{ Mixer.FindSnapshot(SnapshotName)}, new float[]{ 1.0f}, TimeToReach);
Mixer?.TransitionToSnapshots(new AudioMixerSnapshot[]{ Mixer.FindSnapshot(SnapshotName)}, new float[]{ 1.0f}, TimeToReach);
}
public override string GetDefaultName()
{
return $"Set Mixer Snapshot:'{SnapshotName}' ({TimeToReach})s";
}
}

9
Runtime/LevelScripting/Actions/AudioPlayClipAction.cs


public class AudioPlayClipAction : ActionBase
{
public AudioClip Clip;
[NonNullCheck]
public AudioSource Source;
public bool RandomizePitch = false;
[ShowIf("RandomizePitch")]

Source.Play();
}
}
public override string GetDefaultName()
{
if(Clip == null)
return $"Play Audio Source: '{Source?.name}'";
else
return $"Play Audio clip '{Clip.name}' on '{Source?.name}'";
}
}
}

4
Runtime/LevelScripting/Actions/CursorAction.cs


Cursor.lockState = LockState;
Cursor.visible = CursorVisible;
}
public override string GetDefaultName()
{
return $"{(CursorVisible ? "Show" : "Hide")} Cursor / Lock: {LockState}";
}
}
}

2
Runtime/LevelScripting/Actions/CycleResolutionsAction.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

{
[Obsolete]
public class CycleResolutionsAction : ActionBase
{
public Text ButtonLabel;

2
Runtime/LevelScripting/Actions/CycleWindowModeAction.cs


using System;
[Obsolete]
public class CycleWindowModeAction : ActionBase
{
public Text ButtonLabel;

4
Runtime/LevelScripting/Actions/DestroyObjectAction.cs


if(DestroyInstigator && instigator != null)
Destroy(instigator);
}
public override string GetDefaultName()
{
return $"Destroy {(DestroyInstigator?"instigator": "objects")}";
}
}
}

5
Runtime/LevelScripting/Actions/DirectorControlRigAction.cs


directorControlRig.timeline = TimelineAsset;
}
public override string GetDefaultName()
{
return $"Set DirectorControlRig:{(SetPlayMode? " "+PlayMode.ToString():"")}{(SetWrapMode ? " " + WrapMode.ToString() : "")}{(SetTime ? " Time: " + Time.ToString() : "")}{(SetStopTime ? " Stop Time: " + Time.ToString() : "")}{(SetTimeline ? " Timeline: " + TimelineAsset?.name : "")}";
}
}
}

4
Runtime/LevelScripting/Actions/FocusUIAction.cs


UIObjectToFocus.Select();
}
}
public override string GetDefaultName()
{
return $"Focus UI : '{UIObjectToFocus?.name}'";
}
}
}

6
Runtime/LevelScripting/Actions/FullScreenFadeAction.cs


[ReorderableList]
public Callable[] OnComplete;
}
public override string GetDefaultName()
{
return $"Full Screen Fade {Fading} {Duration}s ({fadeTimingMode})";
}
}

19
Runtime/LevelScripting/Actions/GameLevelLoadAction.cs


}
manager.SwitchLevel(index, ShowUI, OnComplete, SaveProgress);
}
public override string GetDefaultName()
{
string label = "";
switch (level)
{
case Target.MainMenu: label = "Main Menu"; break;
case Target.First: label = "First Level"; break;
case Target.Last: label = "Last Level"; break;
case Target.Current: label = "Current Level"; break;
case Target.Previous: label = "Previous Level"; break;
case Target.Next: label = "Next Level"; break;
case Target.SpecifiedLevel:
label = $"{specifiedLevel?.name}";
break;
case Target.FromGameSave: label = "From Game Save"; break;
}
return $"Game Manager Load : {label}";
}
}
}

5
Runtime/LevelScripting/Actions/GameManagerSendStartupMessageAction.cs


break;
}
}
public override string GetDefaultName()
{
return $"Game Manager Send : {messageType}";
}
}
}

5
Runtime/LevelScripting/Actions/GameSaveLoadSaveAction.cs


Manager.Get<GameSaveManager>().SaveUserSave(UserSaveIndex);
}
}
public override string GetDefaultName()
{
return $"{action} Game Save ({saveLocation}{(saveLocation == GameSaveManager.Location.User?UserSaveIndex.ToString():"")})";
}
}
}

13
Runtime/LevelScripting/Actions/GameSaveSetValueAction.cs


}
}
public override string GetDefaultName()
{
string value = "";
switch (valueType)
{
case GameSaveManager.ValueType.Bool: value = BoolValue.ToString(); break;
case GameSaveManager.ValueType.Int: value = IntValue.ToString(); break;
case GameSaveManager.ValueType.Float: value = FloatValue.ToString(); break;
case GameSaveManager.ValueType.String: value = StringValue.ToString(); break;
}
return $"Game Save Set {valueType} '{Key}' = {value}";
}
bool isString() { return valueType == GameSaveManager.ValueType.String; }
bool isBool() { return valueType == GameSaveManager.ValueType.Bool; }
bool isInt() { return valueType == GameSaveManager.ValueType.Int; }

5
Runtime/LevelScripting/Actions/LogAction.cs


return text;
}
public override string GetDefaultName()
{
return $"Log {type} : '{LogText}'";
}
}
}

5
Runtime/LevelScripting/Actions/RandomToggleGameObjectAction.cs


Targets[i] = transform.GetChild(i).gameObject;
}
}
public override string GetDefaultName()
{
return $"Toggle Random Object from List";
}
}
}

5
Runtime/LevelScripting/Actions/ReachPositionRigSetTargetAction.cs


Debug.LogWarning($"{gameObject.name}: ReachPositionRigSetTarget action could not set target : Target is null");
}
}
public override string GetDefaultName()
{
return $"ReachPositionRig Set Target : '{(UseInstigatorAsTarget?"instigator": target?.name)}'";
}
}
}

5
Runtime/LevelScripting/Actions/RigidbodyAction.cs


force = (actionType == RigidbodyActionType.Force || actionType == RigidbodyActionType.Torque);
explosion = (actionType == RigidbodyActionType.ExplosionForce);
}
public override string GetDefaultName()
{
return $"RigidBody {actionType} on {(ApplyOnInstigator?"instigator":m_Rigidbody?.gameObject.name)}";
}
}
}

5
Runtime/LevelScripting/Actions/SendMessageAction.cs


{
Messager.Send(MessageToSend, instigator);
}
public override string GetDefaultName()
{
return $"Send Message : '{MessageToSend}'";
}
}
}

24
Runtime/LevelScripting/Actions/SetAnimatorParameterAction.cs


showFloat = (parameterType == AnimatorParameterType.Float);
showInt = (parameterType == AnimatorParameterType.Int);
}
public override string GetDefaultName()
{
string value = "";
switch (parameterType)
{
case AnimatorParameterType.Bool:
value = boolValue.ToString();
break;
case AnimatorParameterType.Float:
value = floatValue.ToString();
break;
case AnimatorParameterType.Int:
value = intValue.ToString();
break;
case AnimatorParameterType.Trigger:
value = "Trigger";
break;
default:
break;
}
return $"Set Animator '{parameterName}' {parameterType} Parameter = '{value}' ({animator?.gameObject.name})";
}
}
}

5
Runtime/LevelScripting/Actions/SetRandomSeedAction.cs


randomManager.SetRandomSeed(newSeed);
}
}
public override string GetDefaultName()
{
return $"Set Random Seed :'{(newRandomSeed ? "New Seed at Random":newSeed.ToString())}'";
}
}
}

5
Runtime/LevelScripting/Actions/SetTimeScaleAction.cs


TimeScale = value;
Execute();
}
public override string GetDefaultName()
{
return $"Set Time Scale : {TimeScale}";
}
}
}

10
Runtime/LevelScripting/Actions/SpawnPrefabAction.cs


DontDestroyOnLoad(obj);
}
}
public override string GetDefaultName()
{
if (Prefabs == null || Prefabs.Length == 0)
return $"Spawn No Prefabs";