Files
taptap2024_GJ_chidouren/Packages/com.xfkj.xffsm@357f537fea/Editor/GUI/WindowGraphView/FSMNodeView.cs
2024-10-16 00:03:41 +08:00

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();
}
}
}
}
}