private void ReorderConnections() { // Rearrange connections into numerical order to make them easier to find and edit GraphwayNode graphwayNodeData = (GraphwayNode)target; Graphway graphway = GraphwayEditor.FindGraphwayParent(graphwayNodeData.transform); Transform connections = graphway.transform.Find("Connections").transform; // Create list of connections List <string> connectionNames = new List <string>(); foreach (Transform connection in connections) { connectionNames.Add(connection.name); } // Sort list connectionNames.Sort(); // Reorder gameobjects for (int i = 0; i < connectionNames.Count; i++) { string connectionName = connectionNames[i]; connections.Find(connectionName).SetSiblingIndex(i); } }
private bool NodesAreConnected(int nodeIDA, int nodeIDB) { GraphwayNode graphwayNodeData = (GraphwayNode)target; Graphway graphway = GraphwayEditor.FindGraphwayParent(graphwayNodeData.transform); return(graphway.transform.Find("Connections/" + nodeIDA.ToString() + "->" + nodeIDB.ToString())); }
void Update() { // Handle mouse click if (Input.GetMouseButtonDown(0)) { // Check if an object in the scene was targeted RaycastHit hit; Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out hit)) { // Object hit // Use Graphway to try and find a path to hit position Graphway.FindPath(transform.position, hit.point, FindPathCallback, true, debugMode); } } // Move towards waypoints (if has waypoints) if (waypoints != null && waypoints.Length > 0) { // Increase speed speed = Mathf.Lerp(speed, MAX_SPEED, Time.deltaTime * ACCELERATION); speed = Mathf.Clamp(speed, 0, MAX_SPEED); // Look at next waypoint transform.LookAt(waypoints[0].position); // Move toward next waypoint transform.position = Vector3.MoveTowards(transform.position, waypoints[0].position, Time.deltaTime * waypoints[0].speed * speed); // Check if reach waypoint target if (Vector3.Distance(transform.position, waypoints[0].position) < 0.1f) { // Move on to next waypoint NextWaypoint(); } } else { // Reset speed speed = 0; } // Draw Path if (debugMode && waypoints != null && waypoints.Length > 0) { Vector3 startingPoint = transform.position; for (int i = 0; i < waypoints.Length; i++) { Debug.DrawLine(startingPoint, waypoints[i].position, Color.green); startingPoint = waypoints[i].position; } } }
void OnDisable() { // Hide Graph Graphway graphway = (Graphway)target; if (graphway != null) { DisableRenderers(graphway.transform); } }
private void RemoveConnectedNodeObj(int nodeIDA, int nodeIDB) { if (NodesAreConnected(nodeIDA, nodeIDB)) { GraphwayNode graphwayNodeData = (GraphwayNode)target; Graphway graphway = GraphwayEditor.FindGraphwayParent(graphwayNodeData.transform); DestroyImmediate(graphway.transform.Find("Connections/" + nodeIDA.ToString() + "->" + nodeIDB.ToString()).gameObject); } }
private void CreateNodeObject(Vector3 nodePosition) { Graphway graphway = (Graphway)target; // Create new node object GameObject nodeObject = Instantiate(Resources.Load("Prefabs/GraphwayNode")) as GameObject; nodeObject.name = graphway.editorNodeCounter.ToString(); nodeObject.transform.position = nodePosition; nodeObject.transform.parent = graphway.transform.Find("Nodes").transform; nodeObject.gameObject.AddComponent <GraphwayNode>().SetNodeID(graphway.editorNodeCounter); // Register undo operation Undo.RegisterCreatedObjectUndo(nodeObject, "Created Node"); graphway.editorNodeCounter++; }
void OnSceneGUI() { Graphway graphway = (Graphway)target; if (nodePlacementEnabled) { // Disable left click selection on other game objects HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive)); // Handle mouse click event if (Event.current.type == EventType.MouseDown && Event.current.button == 0) { Debug.Log("On mouse down."); // Raycast to find hit position // NOTE - objects must have colliders attached! Ray worldRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); RaycastHit hit; if (Physics.Raycast(worldRay, out hit)) { Debug.Log("Physics.Raycast"); // Add new node at position CreateNodeObject(hit.point); // Mark scene as dirty to trigger 'Save Changes' prompt EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); } // Use up event Event.current.Use(); } } else { // Re-enable left click selection on other game objects HandleUtility.Repaint(); } // Update graph display DrawGraph(graphway.transform); }
private void CreateConnectedNodeObj(int nodeIDA, int nodeIDB, GraphwayConnectionTypes connectionType) { if (!NodesAreConnected(nodeIDA, nodeIDB)) { GraphwayNode graphwayNodeData = (GraphwayNode)target; Graphway graphway = GraphwayEditor.FindGraphwayParent(graphwayNodeData.transform); GameObject newConnection = new GameObject(); newConnection.name = nodeIDA.ToString() + "->" + nodeIDB.ToString(); newConnection.transform.parent = graphway.transform.Find("Connections").transform; newConnection.AddComponent <GraphwayConnection>().SetConnectionData(nodeIDA, nodeIDB, connectionType); // Register undo operation Undo.RegisterCreatedObjectUndo(newConnection, "Graphway Connection"); // Reorder connection hierarchy to keep things tidy ReorderConnections(); } }
private static void CheckHierarchyIntegrity(Graphway graphway) { // Create a list of node IDs List <int> nodeIDs = new List <int>(); foreach (Transform node in graphway.transform.Find("Nodes").transform) { nodeIDs.Add(int.Parse(node.name)); } // Check connection nodes exist foreach (Transform connection in graphway.transform.Find("Connections").transform) { int nodeIDA = connection.GetComponent <GraphwayConnection>().nodeIDA; int nodeIDB = connection.GetComponent <GraphwayConnection>().nodeIDB; if (nodeIDs.Contains(nodeIDA) == false || nodeIDs.Contains(nodeIDB) == false) { DestroyImmediate(connection.gameObject); } } }
public static void DisableRenderers(Transform transform) { Graphway graphway = FindGraphwayParent(transform); SetRenderers(graphway.transform, false); }
public static void DrawGraph(Transform transform) { Graphway graphway = FindGraphwayParent(transform); if (graphway != null) { // Check integrity of Graphway structure CheckHierarchyIntegrity(graphway); // Enable node renderers EnableRenderers(graphway.transform); // Draw NODES foreach (Transform node in graphway.transform.Find("Nodes").transform) { node.GetComponent <Renderer>().sharedMaterial.color = graphway.nodeColor; node.localScale = new Vector3(graphway.nodeSize, graphway.nodeSize, graphway.nodeSize); CreateLabel(node.position, graphway.nodeSize, NODE_FONT_SIZE, graphway.nodeColor, node.name); } // Draw CONNECTION & SUBNODES foreach (Transform connection in graphway.transform.Find("Connections").transform) { // Get node IDs of connected nodes int nodeIDA = connection.GetComponent <GraphwayConnection>().nodeIDA; int nodeIDB = connection.GetComponent <GraphwayConnection>().nodeIDB; bool isDisabled = connection.GetComponent <GraphwayConnection>().disabled; GraphwayConnectionTypes connectionType = connection.GetComponent <GraphwayConnection>().connectionType; // Set positions of connected nodes Vector3 nodeAPosition = graphway.transform.Find("Nodes/" + nodeIDA).position; Vector3 nodeBPosition = graphway.transform.Find("Nodes/" + nodeIDB).position; Vector3 lastPosition = nodeAPosition; // Check if connection uses subnodes if (connection.childCount > 0) { foreach (Transform subnode in connection.transform) { // Create subnode subnode.GetComponent <Renderer>().sharedMaterial.color = graphway.subnodeColor; subnode.localScale = new Vector3(graphway.subnodeSize, graphway.subnodeSize, graphway.subnodeSize); CreateLabel(subnode.position, graphway.subnodeSize, SUBNODE_FONT_SIZE, graphway.subnodeColor, subnode.name); // Draw connection to first node or previous subnode Handles.color = (subnode.GetSiblingIndex() == 0 ? graphway.nodeColor : graphway.subnodeColor ); // Check if connection is unidirectional // If so draw an arrow to indicate direction of allowed movement if (connectionType == GraphwayConnectionTypes.UnidirectionalAToB) { Vector3 arrowPosition = (subnode.position + lastPosition) / 2; Vector3 relativePos = subnode.position - lastPosition; Quaternion rotation = Quaternion.LookRotation(relativePos, Vector3.up); Handles.ConeHandleCap(0, arrowPosition, rotation, graphway.arrowSize, EventType.Repaint); } else if (connectionType == GraphwayConnectionTypes.UnidirectionalBToA) { Vector3 arrowPosition = (subnode.position + lastPosition) / 2; Vector3 relativePos = lastPosition - subnode.position; Quaternion rotation = Quaternion.LookRotation(relativePos, Vector3.up); Handles.ConeHandleCap(0, arrowPosition, rotation, graphway.arrowSize, EventType.Repaint); } // Draw a line to complete the connection if (isDisabled) { Handles.DrawDottedLine(lastPosition, subnode.position, 4); } else { Handles.DrawLine(lastPosition, subnode.position); } // Step forward to next subnode/node lastPosition = subnode.position; } } // Draw connection to remaining node Handles.color = graphway.nodeColor; // Check if connection is unidirectional // If so display arrow showing which direction if (connectionType == GraphwayConnectionTypes.UnidirectionalAToB) { Vector3 arrowPosition = (nodeBPosition + lastPosition) / 2; Vector3 relativePos = nodeBPosition - lastPosition; Quaternion rotation = Quaternion.LookRotation(relativePos, Vector3.up); Handles.ConeHandleCap(0, arrowPosition, rotation, graphway.arrowSize, EventType.Repaint); } else if (connectionType == GraphwayConnectionTypes.UnidirectionalBToA) { Vector3 arrowPosition = (nodeBPosition + lastPosition) / 2; Vector3 relativePos = lastPosition - nodeBPosition; Quaternion rotation = Quaternion.LookRotation(relativePos, Vector3.up); Handles.ConeHandleCap(0, arrowPosition, rotation, graphway.arrowSize, EventType.Repaint); } // Draw a line to complete the connection if (isDisabled) { Handles.DrawDottedLine(lastPosition, nodeBPosition, 4); } else { Handles.DrawLine(lastPosition, nodeBPosition); } } } }
void Awake() { instance = this; }
public void SetAgentTarget(Vector2 point) { target = point; Graphway.FindPath(transform.position, target, FindPathCallback, true, false); }