1
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NodeCanvas.StateMachines
|
||||
{
|
||||
|
||||
|
||||
///<summary> Super base class for FSM nodes that live within an FSM Graph.</summary>
|
||||
public abstract class FSMNode : Node
|
||||
{
|
||||
|
||||
public override bool allowAsPrime { get { return false; } }
|
||||
public override bool canSelfConnect { get { return false; } }
|
||||
public override int maxInConnections { get { return -1; } }
|
||||
public override int maxOutConnections { get { return -1; } }
|
||||
sealed public override System.Type outConnectionType { get { return typeof(FSMConnection); } }
|
||||
sealed public override Alignment2x2 commentsAlignment { get { return Alignment2x2.Bottom; } }
|
||||
sealed public override Alignment2x2 iconAlignment { get { return Alignment2x2.Bottom; } }
|
||||
|
||||
///<summary>The FSM this state belongs to</summary>
|
||||
public FSM FSM { get { return (FSM)graph; } }
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
private static GUIPort clickedPort { get; set; }
|
||||
private static int dragDropMisses { get; set; }
|
||||
|
||||
class GUIPort
|
||||
{
|
||||
public FSMNode parent { get; private set; }
|
||||
public Vector2 pos { get; private set; }
|
||||
public GUIPort(FSMNode parent, Vector2 pos) {
|
||||
this.parent = parent;
|
||||
this.pos = pos;
|
||||
}
|
||||
}
|
||||
|
||||
//Draw the ports and connections
|
||||
sealed protected override void DrawNodeConnections(Rect drawCanvas, bool fullDrawPass, Vector2 canvasMousePos, float zoomFactor) {
|
||||
|
||||
var e = Event.current;
|
||||
|
||||
//Receive connections first
|
||||
if ( clickedPort != null && e.type == EventType.MouseUp && e.button == 0 ) {
|
||||
|
||||
if ( rect.Contains(e.mousePosition) ) {
|
||||
graph.ConnectNodes(clickedPort.parent, this);
|
||||
clickedPort = null;
|
||||
e.Use();
|
||||
|
||||
} else {
|
||||
|
||||
dragDropMisses++;
|
||||
|
||||
if ( dragDropMisses == graph.allNodes.Count && clickedPort != null ) {
|
||||
var source = clickedPort.parent;
|
||||
var pos = Event.current.mousePosition;
|
||||
var menu = new UnityEditor.GenericMenu();
|
||||
clickedPort = null;
|
||||
|
||||
menu.AddItem(new GUIContent("Add Action State"), false, () =>
|
||||
{
|
||||
var newState = graph.AddNode<ActionState>(pos);
|
||||
graph.ConnectNodes(source, newState);
|
||||
});
|
||||
|
||||
//PostGUI cause of zoom factors
|
||||
Editor.GraphEditorUtility.PostGUI += () => { menu.ShowAsContext(); };
|
||||
Event.current.Use();
|
||||
e.Use();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var portRectLeft = new Rect(0, 0, 20, 20);
|
||||
var portRectRight = new Rect(0, 0, 20, 20);
|
||||
var portRectBottom = new Rect(0, 0, 20, 20);
|
||||
|
||||
portRectLeft.center = new Vector2(rect.x - 11, rect.center.y);
|
||||
portRectRight.center = new Vector2(rect.xMax + 11, rect.center.y);
|
||||
portRectBottom.center = new Vector2(rect.center.x, rect.yMax + 11);
|
||||
|
||||
if ( maxOutConnections != 0 ) {
|
||||
if ( fullDrawPass || drawCanvas.Overlaps(rect) ) {
|
||||
UnityEditor.EditorGUIUtility.AddCursorRect(portRectLeft, UnityEditor.MouseCursor.ArrowPlus);
|
||||
UnityEditor.EditorGUIUtility.AddCursorRect(portRectRight, UnityEditor.MouseCursor.ArrowPlus);
|
||||
UnityEditor.EditorGUIUtility.AddCursorRect(portRectBottom, UnityEditor.MouseCursor.ArrowPlus);
|
||||
|
||||
GUI.color = new Color(1, 1, 1, 0.3f);
|
||||
GUI.DrawTexture(portRectLeft, Editor.StyleSheet.arrowLeft);
|
||||
GUI.DrawTexture(portRectRight, Editor.StyleSheet.arrowRight);
|
||||
if ( maxInConnections == 0 ) {
|
||||
GUI.DrawTexture(portRectBottom, Editor.StyleSheet.arrowBottom);
|
||||
}
|
||||
GUI.color = Color.white;
|
||||
|
||||
if ( Editor.GraphEditorUtility.allowClick && e.type == EventType.MouseDown && e.button == 0 ) {
|
||||
|
||||
if ( portRectLeft.Contains(e.mousePosition) ) {
|
||||
clickedPort = new GUIPort(this, portRectLeft.center);
|
||||
dragDropMisses = 0;
|
||||
e.Use();
|
||||
}
|
||||
|
||||
if ( portRectRight.Contains(e.mousePosition) ) {
|
||||
clickedPort = new GUIPort(this, portRectRight.center);
|
||||
dragDropMisses = 0;
|
||||
e.Use();
|
||||
}
|
||||
|
||||
if ( maxInConnections == 0 && portRectBottom.Contains(e.mousePosition) ) {
|
||||
clickedPort = new GUIPort(this, portRectBottom.center);
|
||||
dragDropMisses = 0;
|
||||
e.Use();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//draw new linking
|
||||
if ( clickedPort != null && clickedPort.parent == this ) {
|
||||
UnityEditor.Handles.DrawBezier(clickedPort.pos, e.mousePosition, clickedPort.pos, e.mousePosition, new Color(0.5f, 0.5f, 0.8f, 0.8f), Editor.StyleSheet.bezierTexture, 2);
|
||||
}
|
||||
|
||||
//draw out connections
|
||||
for ( var i = 0; i < outConnections.Count; i++ ) {
|
||||
|
||||
var connection = outConnections[i] as FSMConnection;
|
||||
var targetState = connection.targetNode as FSMNode;
|
||||
if ( targetState == null ) { //In case of MissingNode type
|
||||
continue;
|
||||
}
|
||||
|
||||
var targetPos = targetState.GetConnectedInPortPosition(connection);
|
||||
var sourcePos = Vector2.zero;
|
||||
|
||||
if ( rect.center.x <= targetPos.x ) {
|
||||
sourcePos = portRectRight.center;
|
||||
}
|
||||
|
||||
if ( rect.center.x > targetPos.x ) {
|
||||
sourcePos = portRectLeft.center;
|
||||
}
|
||||
|
||||
if ( maxInConnections == 0 && rect.center.y < targetPos.y - 50 && Mathf.Abs(rect.center.x - targetPos.x) < 200 ) {
|
||||
sourcePos = portRectBottom.center;
|
||||
}
|
||||
|
||||
var boundRect = RectUtils.GetBoundRect(sourcePos, targetPos);
|
||||
if ( fullDrawPass || drawCanvas.Overlaps(boundRect) ) {
|
||||
connection.DrawConnectionGUI(sourcePos, targetPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//...
|
||||
Vector2 GetConnectedInPortPosition(Connection connection) {
|
||||
|
||||
var sourcePos = connection.sourceNode.rect.center;
|
||||
var thisPos = rect.center;
|
||||
|
||||
var style = 0;
|
||||
|
||||
if ( style == 0 ) {
|
||||
if ( sourcePos.x <= thisPos.x ) {
|
||||
if ( sourcePos.y <= thisPos.y ) {
|
||||
return new Vector2(rect.center.x - 15, rect.yMin - ( this == graph.primeNode ? 20 : 0 ));
|
||||
} else {
|
||||
return new Vector2(rect.center.x - 15, rect.yMax + 2);
|
||||
}
|
||||
}
|
||||
|
||||
if ( sourcePos.x > thisPos.x ) {
|
||||
if ( sourcePos.y <= thisPos.y ) {
|
||||
return new Vector2(rect.center.x + 15, rect.yMin - ( this == graph.primeNode ? 20 : 0 ));
|
||||
} else {
|
||||
return new Vector2(rect.center.x + 15, rect.yMax + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// //Another idea
|
||||
// if (style == 1){
|
||||
// if (sourcePos.x <= thisPos.x){
|
||||
// if (sourcePos.y >= thisPos.y){
|
||||
// return new Vector2(rect.xMin - 3, rect.yMax - 10);
|
||||
// } else {
|
||||
// return new Vector2(rect.xMin - 3, rect.yMin + 10);
|
||||
// }
|
||||
// }
|
||||
// if (sourcePos.x > thisPos.x){
|
||||
// if (sourcePos.y >= thisPos.y){
|
||||
// return new Vector2(rect.center.x, rect.yMax + 2);
|
||||
// } else {
|
||||
// return new Vector2(rect.center.x, rect.yMin - (this == graph.primeNode? 20 : 0 ));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// //YET Another idea
|
||||
// if (style >= 2){
|
||||
// if (sourcePos.x <= thisPos.x){
|
||||
// if (sourcePos.y >= thisPos.y){
|
||||
// return new Vector2(rect.xMin - 3, rect.yMax - 10);
|
||||
// } else {
|
||||
// return new Vector2(rect.xMin - 3, rect.yMin + 10);
|
||||
// }
|
||||
// }
|
||||
// if (sourcePos.x > thisPos.x){
|
||||
// if (sourcePos.y >= thisPos.y){
|
||||
// return new Vector2(rect.xMax + 3, rect.yMax - 10);
|
||||
// } else {
|
||||
// return new Vector2(rect.xMax + 3, rect.yMin + 10);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
return thisPos;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user