You've already forked taptap2024_GJ_chidouren
296 lines
9.1 KiB
C#
296 lines
9.1 KiB
C#
using System.Collections.Generic;
|
|
using UnityEditor;
|
|
using UnityEditor.Experimental.GraphView;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace XFFSM
|
|
{
|
|
|
|
public class FSMNodeView : Node
|
|
{
|
|
|
|
public FSMStateNodeData Data { get;private set; }
|
|
|
|
|
|
private FSMStateGraphView graphView = null;
|
|
|
|
private GUIStyle labelStyle = null;
|
|
|
|
private float runingTimer;
|
|
|
|
|
|
public FSMNodeView(FSMStateNodeData data, FSMStateGraphView graphView)
|
|
{
|
|
this.Data = data;
|
|
this.graphView = graphView;
|
|
Clear();
|
|
|
|
VisualElement image = new VisualElement();
|
|
image.style.width = 200;
|
|
image.style.height = 40;
|
|
IMGUIContainer container = new IMGUIContainer();
|
|
container.onGUIHandler += () =>
|
|
{
|
|
|
|
if (Context.Instance.RuntimeFSMController == null)
|
|
return;
|
|
|
|
if (labelStyle == null)
|
|
{
|
|
labelStyle = new GUIStyle(GUI.skin.label);
|
|
labelStyle.alignment = TextAnchor.MiddleCenter;
|
|
labelStyle.fontSize = 15;
|
|
labelStyle.padding.top = -5;
|
|
}
|
|
|
|
GUI.Label(container.layout,string.Empty, GetStateStyle(selected));
|
|
GUI.Label(container.layout, Data.DisplayName, labelStyle);
|
|
|
|
DrawRuning(container.layout);
|
|
};
|
|
|
|
container.StretchToParentSize();
|
|
|
|
//image.name = "node-border";
|
|
image.style.borderRightWidth = 0;
|
|
image.style.borderLeftWidth = 0;
|
|
image.style.borderTopWidth = 0;
|
|
image.style.borderBottomWidth = 0;
|
|
|
|
image.Add(container);
|
|
Add(image);
|
|
|
|
RegisterCallback<MouseDownEvent>(OnMouseDownEvent);
|
|
}
|
|
|
|
public override void SetPosition(Rect newPos)
|
|
{
|
|
|
|
if (Vector2.Distance(newPos.position, GetPosition().position) < 10)
|
|
return;
|
|
|
|
// 实际位置
|
|
newPos.Set((int)(newPos.x / 20) * 20 , (int)(newPos.y / 20) * 20,FSMConst.StateNodeWith, FSMConst.StateNodeHeight);
|
|
|
|
// 显示位置
|
|
base.SetPosition(new Rect(newPos.x - 2,newPos.y - 2 ,newPos.width,newPos.height));
|
|
|
|
Data.rect = newPos;
|
|
if (Context.Instance.RuntimeFSMController != null)
|
|
Context.Instance.RuntimeFSMController.Save();
|
|
|
|
}
|
|
|
|
|
|
public void ShowMenu(ContextualMenuPopulateEvent evt)
|
|
{
|
|
|
|
bool is_any = Data.IsAnyState;
|
|
bool is_entry = Data.IsEntryState;
|
|
|
|
if (!is_entry && !Data.IsUpState)
|
|
{
|
|
evt.menu.AppendAction( "Make Transition",(a) =>
|
|
{
|
|
graphView.StartMakeTransition(this);
|
|
});
|
|
}
|
|
else
|
|
{
|
|
evt.menu.AppendAction( "Make Transition", null, DropdownMenuAction.Status.Disabled);
|
|
}
|
|
|
|
if (!is_entry && !is_any && !Data.IsUpState)
|
|
{
|
|
|
|
if (Data.defaultState)
|
|
{
|
|
evt.menu.AppendAction("Set as Layer Default State",null, DropdownMenuAction.Status.Disabled);
|
|
}
|
|
else
|
|
{
|
|
evt.menu.AppendAction( "Set as Layer Default State", (a) =>
|
|
{
|
|
//SetDefaultState(node);
|
|
SetDefaultState();
|
|
graphView.RefreshNodes();
|
|
});
|
|
}
|
|
|
|
evt.menu.AppendAction( "Delete",(a) =>
|
|
{
|
|
DeleteStates();
|
|
});
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
private void DeleteStates()
|
|
{
|
|
|
|
RuntimeFSMController controller = Context.Instance.RuntimeFSMController;
|
|
if (controller == null)
|
|
return;
|
|
foreach (var item in graphView.StateNodes.Values)
|
|
{
|
|
if (item.selected)
|
|
FSMStateNodeFactory.DeleteState(controller, item.Data);
|
|
}
|
|
|
|
graphView.RefreshNodes();
|
|
}
|
|
|
|
private void SetDefaultState()
|
|
{
|
|
List<FSMStateNodeData> states = Context.Instance.GetCurrentShowStateNodeData();
|
|
if (states != null)
|
|
{
|
|
foreach (var item in states)
|
|
{
|
|
item.defaultState = false;
|
|
}
|
|
}
|
|
this.Data.defaultState = true;
|
|
Context.Instance.RuntimeFSMController.Save();
|
|
}
|
|
|
|
|
|
private GUIStyle GetStateStyle(bool selected)
|
|
{
|
|
if(Data.defaultState)
|
|
{
|
|
|
|
if (Data.isSubStateMachine)
|
|
return StateStyles.Get(selected ? Style.OrangeOnHEX : Style.OrangeHEX);
|
|
|
|
return StateStyles.Get(selected ? Style.OrangeOn : Style.Orange);
|
|
}
|
|
else if (Data.IsEntryState)
|
|
{
|
|
if (Data.isSubStateMachine)
|
|
return StateStyles.Get(selected ? Style.GreenOnHEX : Style.GreenHEX);
|
|
|
|
return StateStyles.Get(selected ? Style.GreenOn : Style.Green);
|
|
}
|
|
else if (Data.IsAnyState)
|
|
{
|
|
if (Data.isSubStateMachine)
|
|
return StateStyles.Get(selected ? Style.MintOnHEX : Style.MintHEX);
|
|
|
|
return StateStyles.Get(selected ? Style.MintOn : Style.Mint);
|
|
}
|
|
else if (Data.IsUpState)
|
|
{
|
|
return StateStyles.Get(selected ? Style.RedOnHEX : Style.RedHEX);
|
|
}
|
|
|
|
else
|
|
{
|
|
if (Data.isSubStateMachine)
|
|
return StateStyles.Get(selected ? Style.NormalOnHEX : Style.NormalHEX);
|
|
|
|
return StateStyles.Get(selected ? Style.NormalOn : Style.Normal);
|
|
}
|
|
|
|
}
|
|
|
|
public override void OnSelected()
|
|
{
|
|
base.OnSelected();
|
|
EditorApplication.delayCall -= DelayCallSelection;
|
|
EditorApplication.delayCall += DelayCallSelection;
|
|
}
|
|
|
|
private void DelayCallSelection() {
|
|
FSMStateInspectorHelper.Instance.Inspect(Context.Instance.RuntimeFSMController, Data, graphView);
|
|
}
|
|
|
|
public override void OnUnselected()
|
|
{
|
|
base.OnUnselected();
|
|
FSMStateInspectorHelper.Instance.Inspect(Context.Instance.RuntimeFSMController, null, graphView);
|
|
}
|
|
|
|
|
|
private void DrawRuning(Rect rect)
|
|
{
|
|
|
|
FSMStateNode currentState = GetCurrentState();
|
|
|
|
if (currentState == null) return;
|
|
|
|
if (Event.current.type != EventType.Repaint || (!(currentState.data.name == Data.name)))
|
|
return;
|
|
|
|
rect.Set(15, 28, rect.width - 30, 20);
|
|
|
|
runingTimer += Time.unscaledDeltaTime;
|
|
if (runingTimer >= 1)
|
|
runingTimer = 0;
|
|
|
|
GUIStyle gUIStyle = "MeLivePlayBackground";
|
|
GUIStyle gUIStyle2 = "MeLivePlayBar";
|
|
rect = gUIStyle.margin.Remove(rect);
|
|
Rect rect2 = gUIStyle.padding.Remove(rect);
|
|
|
|
rect2.width *= runingTimer;
|
|
|
|
gUIStyle2.Draw(rect2, isHover: false, isActive: false, on: false, hasKeyboardFocus: false);
|
|
gUIStyle.Draw(rect, isHover: false, isActive: false, on: false, hasKeyboardFocus: false);
|
|
}
|
|
|
|
private FSMStateNode GetCurrentState()
|
|
{
|
|
if (!Application.isPlaying)
|
|
return null;
|
|
|
|
if (Context.Instance.FSMController == null) return null;
|
|
if (Context.Instance.FSMController.RuntimeFSMController == null) return null;
|
|
if (Context.Instance.RuntimeFSMController == null) return null;
|
|
|
|
// 如果在运行时 正在运行的状态是orange
|
|
int index = Context.Instance.FSMController.RuntimeFSMController.IndexOf(Context.Instance.RuntimeFSMController);
|
|
FSMStateNode current_state_node = Context.Instance.FSMController.GetCurrentStateInfo(index, Context.Instance.LayerParent);
|
|
|
|
return current_state_node;
|
|
|
|
}
|
|
|
|
|
|
public void OnMouseDownEvent(MouseDownEvent evt)
|
|
{
|
|
if (evt != null && evt.pressedButtons == 1 && evt.clickCount == 1)
|
|
{
|
|
|
|
if (graphView.isMakeTransition)
|
|
graphView.StopMakeTransition(this);
|
|
|
|
//graphView.selector.DragStateNodeStart();
|
|
DelayCallSelection();
|
|
}
|
|
|
|
if (evt != null && evt.pressedButtons == 1 && evt.clickCount == 2)
|
|
{
|
|
if (Data.isSubStateMachine)
|
|
{
|
|
Context.Instance.AddLayer(Data.name);
|
|
graphView.RefreshNodes();
|
|
}
|
|
|
|
if (Data.IsUpState)
|
|
{
|
|
Context.Instance.RemoveLast(Data.Parent);
|
|
graphView.RefreshNodes();
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|