private static void BuildResultPath(int path_cell, NavType path_nav_type, ref Path path) { if (path_cell != InvalidCell) { bool is_cell_in_range = false; Cell cell = PathGrid.GetCell(path_cell, path_nav_type, out is_cell_in_range); path.Clear(); path.cost = cell.cost; while (path_cell != InvalidCell) { path.AddNode(new Path.Node { cell = path_cell, navType = cell.navType, transitionId = cell.transitionId }); path_cell = cell.parent; if (path_cell != InvalidCell) { cell = PathGrid.GetCell(path_cell, cell.parentNavType, out is_cell_in_range); } } if (path.nodes != null) { for (int i = 0; i < path.nodes.Count / 2; i++) { Path.Node value = path.nodes[i]; path.nodes[i] = path.nodes[path.nodes.Count - i - 1]; path.nodes[path.nodes.Count - i - 1] = value; } } } }
/// <summary> /// Checks all edges between nodes, if the distance of pos towards such an /// edge is smaller than 10, then return the number of the first node in that /// edge /// </summary> private int FindPath(Vector pos, ref Vector pointOnEdge) { int bestNode = -1; float bestDistance = 10; for (int i = 0; i < path.Nodes.Count - 1; ++i) { Path.Node n0 = path.Nodes[i]; Path.Node n1 = path.Nodes[i + 1]; Vector n0_n1 = n1.Pos - n0.Pos; float edgeLen = n0_n1.Norm(); Vector dir = n0_n1 / edgeLen; float s = (pos - n0.Pos) * dir; if (s <= 0 || s >= edgeLen) { continue; } Vector projPoint = n0.Pos + dir * s; float distance = (projPoint - pos).Norm(); if (distance < bestDistance) { bestNode = i; bestDistance = distance; pointOnEdge = projPoint; } } return(bestNode); }
protected void OnToolPath(object o, EventArgs args) { if (!ToolPath.Active || iPathToEdit == null) { ToolPath.Sensitive = false; } else { PrintStatus("Tool: Path editor"); ToolSelectProps.Visible = false; ToolTilesProps.Visible = false; ToolObjectsProps.Visible = false; ToolBrushProps.Visible = false; if (level == null) { return; } if (iPathToEdit.Path == null) // Create new path if we have invalid one { Path path = new Path(); Path.Node pathNode = new Path.Node(); if (iPathToEdit is IObject) // Move it to object => preserve it's position (if applicable). { pathNode.Pos = new Vector(((IObject)iPathToEdit).Area.Left, ((IObject)iPathToEdit).Area.Top); } path.Nodes.Add(pathNode); iPathToEdit.Path = path; } SetTool(new PathTool(this, iPathToEdit.Path)); } }
public void SetOwner(IOwner owner) { this.owner = owner; ai.owner = owner; owner.GetUnitsCommanding().Add(this); if (owner as AirCarrier || owner as GroundCarrier) { // GET THE DRONES TO MOVE ai.setMode(AirCraftAI.AIMode.Path); var path = ScriptableObject.CreateInstance <Path>(); path.waypoints = new List <Path.Node>(); var vec = Vector2.zero; if (owner as AirCarrier) { foreach (var ent in BattleZoneManager.getTargets()) { if (ent && ent is ICarrier && !FactionManager.IsAllied(ent.faction, owner.GetFaction()) && ent.transform) { vec = ent.transform.position; } } } // otherwise this is a ground carrier, drones are defensive for them so set a path to the drone position currently else { var angle = Random.Range(0F, 360); vec = owner.GetTransform().position + new Vector3(5 * Mathf.Sin(angle), 5 * Mathf.Cos(angle)); } // TODO: jank, fix this eventually var node = new Path.Node(); node.position = vec; node.ID = 0; node.children = new List <int>(); if (vec != Vector2.zero) { path.waypoints.Add(node); } if (owner as AirCarrier) { ai.setPath(path); } else { NodeEditorFramework.Standard.PathData data = new NodeEditorFramework.Standard.PathData(); data.waypoints = new List <NodeEditorFramework.Standard.PathData.Node>(); // TODO: LOL THESE TWO ARE DIFFERENT, unify them foreach (var point in path.waypoints) { var node2 = new NodeEditorFramework.Standard.PathData.Node(); node2.ID = point.ID; node2.children = point.children; node2.position = point.position; data.waypoints.Add(node2); } ai.setPath(data, null, true); } } }
public bool Execute(Personage personage) { if (currentPath == null) { return(false); } if (currentNode == null) { if (!currentPath.NextNode(out currentNode)) { return(false); } } if (personage.Near(currentNode)) { currentNode = null; return(true); } var tempVector = currentNode.Point - personage.GetGameObject().transform.position; tempVector.y = 0; if (tempVector != Vector3.zero) { personage.GetGameObject().transform.rotation = Quaternion.Slerp(personage.GetGameObject().transform.rotation, Quaternion.LookRotation(tempVector), Time.deltaTime * 10f); } //personage.MoveForward(); personage.AnimationGroup.MoveForwardBack = 1f; return(true); }
public void Run(Manipulator manipulator, CancellationToken cancellationToken = default) { try { // start measuring execution time Timer.Restart(); // turn the controller on State = ControllerState.Running; // start motion control if a path has been found if (manipulator.Path != null) { using (var manipulatorCopy = manipulator.DeepCopy()) { // execute motion control Path.Node gripperPos = manipulator.Path.Current; while (gripperPos.Child != null) { cancellationToken.ThrowIfCancellationRequested(); var current = gripperPos.Child; while (current.Child != null) // last point may not be deformed, since it is a goal point { for (int j = current.Points.Length - 1; j > 0; j--) { if (ObstacleHandler.ContainmentTest(current.Points[j], out Obstacle obstacle)) { //Deform(manipulatorCopy, obstacle, current, j); } } current = current.Child; } //Discretize(manipulatorCopy, gripperPos); gripperPos = manipulator.Path.Current; } } } // turn the controller off State = ControllerState.Idle; } catch (OperationCanceledException oce) { // indicate that the process has been aborted State = ControllerState.Aborted; } finally { // stop measuring execution time Timer.Stop(); } }
protected override void GetReachedToPoint(Node node) { if (node.Id == positionToGo) { currentNode = 0; GoalReachedNode (node); } else TryFindOtherPoint (); }
protected override void GetReachedToPoint(Node node) { if (node.Id == positionToGo) { lastDirection = Vector3.zero; GoalReachedNode (node); } else GoToOtherNode (); }
private void OnDelete(object o, EventArgs args) { Command command = new SortedListRemoveCommand <Path.Node>("Added Path node", path, field, selectedNode); command.Do(); UndoManager.AddCommand(command); selectedNode = null; dragging = false; Redraw(); }
protected override void Update() { base.Update (); if (cachedNode != CurrentNode) { cachedNode = CurrentNode; canRotate = IsInStartPoint; arrow.SetActive (IsInStartPoint); } if(CanRotate) myTransform.DORotate ((myTransform.rotation.eulerAngles.y - 90) * Vector3.up, 0.3F); }
private void OnDelete(object o, EventArgs args) { if (path.Nodes.Count > 1) { Command command = new SortedListRemoveCommand <Path.Node>("Deleted Path node", path, field, selectedNode); command.Do(); UndoManager.AddCommand(command); selectedNode = null; dragging = false; Redraw(); } else { Application.EditorApplication.DeleteCurrentPath(); } }
public void OnMouseMotion(Vector mousePos, ModifierType Modifiers) { if (dragging) { Vector spos = originalPos + (mousePos - pressPoint); // snap to 32pixel? if ((Modifiers & ModifierType.ShiftMask) != 0 || application.SnapToGrid) { spos = new Vector((float)((int)spos.X / 32) * 32, (float)((int)spos.Y / 32) * 32); } if (selectedNode.Pos != spos) { selectedNode.Pos = spos; Redraw(); } } else { Path.Node node = FindNodeAt(mousePos); Vector dummy = new Vector(0, 0); if (node != null) { /* * Cursor cursor = new Cursor(); * Pixmap pixmap = new Pixmap(GetType().Assembly.GetManifestResourceAsStream("modifier-move.png")); */ CursorChange(new Cursor(CursorType.Tcross)); } else if ((Modifiers & ModifierType.ControlMask) != 0 && FindPath(mousePos, ref dummy) >= 0) { CursorChange(new Cursor(CursorType.Boat)); } else { CursorChange(new Cursor(CursorType.Arrow)); } } }
public void AddPoint(Vector2 point) { int closest = GetClosestNodeIndex(point); int ID = pathNodes.Count == 0 ? 0 : IDCount++; pathNodes.Add(new Path.Node() { ID = ID, position = point, children = new List <int>() }); dragging = true; selectedNode = pathNodes[GetNodeIndex(ID)]; // add child if (closest >= 0) { pathNodes[closest].children.Add(ID); } UpdateMesh(); }
public static bool ValidatePath(NavGrid nav_grid, PathFinderAbilities abilities, ref Path path) { if (!path.IsValid()) { return(false); } for (int i = 0; i < path.nodes.Count; i++) { Path.Node node = path.nodes[i]; if (i < path.nodes.Count - 1) { Path.Node node2 = path.nodes[i + 1]; int num = node.cell * nav_grid.maxLinksPerCell; bool flag = false; NavGrid.Link link = nav_grid.Links[num]; while (link.link != InvalidHandle) { if (link.link == node2.cell && node2.navType == link.endNavType && node.navType == link.startNavType) { PotentialPath path2 = new PotentialPath(node.cell, node.navType, PotentialPath.Flags.None); flag = abilities.TraversePath(ref path2, node.cell, node.navType, 0, link.transitionId, 0); if (flag) { break; } } num++; link = nav_grid.Links[num]; } if (!flag) { return(false); } } } return(true); }
protected void OnToolPath(object o, EventArgs args) { if (!ToolPath.Active || iPathToEdit == null){ ToolPath.Sensitive = false; } else { PrintStatus("Tool: Path editor"); ToolSelectProps.Visible = false; ToolTilesProps.Visible = false; ToolObjectsProps.Visible = false; ToolBrushProps.Visible = false; if (level == null) return; if (iPathToEdit.Path == null) { // Create new path if we have invalid one Path path = new Path(); Path.Node pathNode = new Path.Node(); if (iPathToEdit is IObject) // Move it to object => preserve it's position (if applicable). pathNode.Pos = new Vector(((IObject)iPathToEdit).Area.Left, ((IObject)iPathToEdit).Area.Top); path.Nodes.Add(pathNode); iPathToEdit.Path = path; } SetTool(new PathTool(this, iPathToEdit.Path)); } }
private void OnDelete(object o, EventArgs args) { application.TakeUndoSnapshot("Deleted Path node"); path.Nodes.Remove(selectedNode); selectedNode = null; dragging = false; Redraw(); }
public void OnMouseButtonPress(Vector pos, int button, ModifierType Modifiers) { if(button == 1) { Path.Node node = FindNodeAt(pos); if(node == null) { if((Modifiers & ModifierType.ControlMask) != 0) { Vector pointOnEdge = new Vector(0, 0); int addNode = FindPath(pos, ref pointOnEdge); if(addNode >= 0) { application.TakeUndoSnapshot("Added Path node"); node = new Path.Node(); node.Pos = pointOnEdge; path.Nodes.Insert(addNode+1, node); } } else if(selectedNode == path.Nodes[path.Nodes.Count - 1]) { application.TakeUndoSnapshot("Added Path node"); node = new Path.Node(); //Snap? if( application.SnapToGrid ) { pos = new Vector((float) ((int)pos.X / 32) * 32, (float) ((int)pos.Y / 32) * 32); } node.Pos = pos; path.Nodes.Add(node); } else if(selectedNode == path.Nodes[0]) { application.TakeUndoSnapshot("Added Path node"); node = new Path.Node(); node.Pos = pos; path.Nodes.Insert(0, node); } } if(node != selectedNode) { selectedNode = node; Redraw(); } if(selectedNode != null) { application.EditProperties(selectedNode, "Path Node"); dragging = true; pressPoint = pos; originalPos = selectedNode.Pos; } } else if(button == 3) { PopupMenu(button); } }
private void TransformCurve() { Event currentEvent = Event.current; bool showingDeleteInput = currentEvent.control; bool freeMoveNodeInput = !currentEvent.alt; bool snapInput = currentEvent.shift; Vector3 position = SelectedPath.transform.position; Quaternion rotation = SelectedPath.transform.rotation; Vector3 scale = SelectedPath.transform.localScale; #region Display Path // Display curves if (!showingDeleteInput) { Handles.color = linePreviewColor; } else { Handles.color = deleteColor; } Vector3[] curvePreviewPoints = SelectedPath.CurvePoints(true, true, true); // Render a few times for thickness - setting a width looks like shit Handles.DrawAAPolyLine(curvePreviewPoints); Handles.DrawAAPolyLine(curvePreviewPoints); Handles.DrawAAPolyLine(curvePreviewPoints); Handles.DrawAAPolyLine(curvePreviewPoints); Handles.DrawAAPolyLine(curvePreviewPoints); #endregion for (int i = 0; i < SelectedPath.Nodes.Count; i++) { // Define node for editing Path.Node node = SelectedPath.Nodes[i]; #region Node Adjustment Handle // Adjust node Handles.color = nodeColor; Vector3 nodePositionScale = Vector3.Scale(node.Position, scale) + position; Vector3 nodePosition = nodePositionScale .RotateAround(position, rotation); // Directional movement Quaternion directionalMovementRotation = Quaternion.identity; if (Tools.pivotRotation == PivotRotation.Local) { directionalMovementRotation = rotation; } // Modify node position in world space if (!showingDeleteInput) { if (freeMoveNodeInput) { nodePosition = Handles.FreeMoveHandle(nodePositionScale.RotateAround(position, rotation), Quaternion.identity, nodeSize, Vector3.zero, Handles.DotCap); } else { nodePosition = Handles.PositionHandle(nodePositionScale.RotateAround(position, rotation), directionalMovementRotation); } } // Convert modified node back to local space Vector3 nodePositionStored = ((nodePosition).RotateAround(position, Quaternion.Inverse(rotation)) - position).Divide(scale); if (nodePositionStored != node.Position) { lastModifiedNode = node; // Apply node adjustments EditorGUI.BeginChangeCheck(); Undo.RecordObject(SelectedPath, "Adjust Path Node"); if (SelectedPath.Flat) { nodePositionStored.z = 0; } if (snapInput) { if (i > 0) { Path.Node previousNode = SelectedPath.Nodes[i - 1]; float axisDistanceX = Mathf.Abs(nodePositionStored.x - previousNode.Position.x); float axisDistanceY = Mathf.Abs(nodePositionStored.y - previousNode.Position.y); float axisDistanceZ = Mathf.Abs(nodePositionStored.z - previousNode.Position.z); if (axisDistanceX < snapDistance) { nodePositionStored.x = previousNode.Position.x; } if (axisDistanceY < snapDistance) { nodePositionStored.y = previousNode.Position.y; } if (axisDistanceZ < snapDistance) { nodePositionStored.z = previousNode.Position.z; } } if (i < SelectedPath.Nodes.Count - 1) { Path.Node nextNode = SelectedPath.Nodes[i + 1]; float axisDistanceX = Mathf.Abs(nodePositionStored.x - nextNode.Position.x); float axisDistanceY = Mathf.Abs(nodePositionStored.y - nextNode.Position.y); float axisDistanceZ = Mathf.Abs(nodePositionStored.z - nextNode.Position.z); if (axisDistanceX < snapDistance) { nodePositionStored.x = nextNode.Position.x; } if (axisDistanceY < snapDistance) { nodePositionStored.y = nextNode.Position.y; } if (axisDistanceZ < snapDistance) { nodePositionStored.z = nextNode.Position.z; } } } // Current fix for math loss if (currentEvent.button == 0) { node.Position = nodePositionStored; } EditorGUI.EndChangeCheck(); } #endregion if (!showingDeleteInput) { #region Adjust Tangents Handles.color = handleColor; Vector3 newTangentA = node.TangentA.RotateAround(Vector3.zero, rotation); Vector3 newTangentB = node.TangentB.RotateAround(Vector3.zero, rotation); Vector3 directionAToB = ((newTangentA + nodePosition) - (-newTangentB + nodePosition)).normalized; Vector3 directionToCenterA = ((newTangentA + nodePosition) - nodePosition).normalized; Vector3 directionToCenterB = ((-newTangentB + nodePosition) - nodePosition).normalized; // Adjust curve tangent based on type, show handles for adjustment switch (node.TangentType) { // Handles mirror eachother case Path.Node.Type.Auto: newTangentA = freeMoveNodeInput ? Handles.FreeMoveHandle((directionAToB * newTangentB.magnitude) + nodePosition, Quaternion.identity, handleSize, Vector3.zero, Handles.CircleCap) - nodePosition : Handles.PositionHandle((directionAToB * newTangentB.magnitude) + nodePosition, directionalMovementRotation) - nodePosition; newTangentB = freeMoveNodeInput ? -(Handles.FreeMoveHandle((-directionAToB * newTangentA.magnitude) + nodePosition, Quaternion.identity, handleSize, Vector3.zero, Handles.CircleCap) - nodePosition) : -(Handles.PositionHandle((-directionAToB * newTangentA.magnitude) + nodePosition, directionalMovementRotation) - nodePosition); break; // Handles tilt is aligned, but distance is isolated case Path.Node.Type.Aligned: newTangentA = freeMoveNodeInput ? Handles.FreeMoveHandle((directionAToB * newTangentA.magnitude) + nodePosition, Quaternion.identity, handleSize, Vector3.zero, Handles.CircleCap) - nodePosition : Handles.PositionHandle((directionAToB * newTangentA.magnitude) + nodePosition, directionalMovementRotation) - nodePosition; newTangentB = freeMoveNodeInput ? -(Handles.FreeMoveHandle((-directionAToB * newTangentB.magnitude) + nodePosition, Quaternion.identity, handleSize, Vector3.zero, Handles.CircleCap) - nodePosition) : -(Handles.PositionHandle((-directionAToB * newTangentB.magnitude) + nodePosition, directionalMovementRotation) - nodePosition); break; // Each handle moves independently case Path.Node.Type.Free: newTangentA = freeMoveNodeInput ? Handles.FreeMoveHandle((directionToCenterA * newTangentA.magnitude) + nodePosition, Quaternion.identity, handleSize, Vector3.zero, Handles.CircleCap) - nodePosition : Handles.PositionHandle((directionToCenterA * newTangentA.magnitude), directionalMovementRotation) - nodePosition; newTangentB = freeMoveNodeInput ? -(Handles.FreeMoveHandle((directionToCenterB * newTangentB.magnitude) + nodePosition, Quaternion.identity, handleSize, Vector3.zero, Handles.CircleCap) - nodePosition) : -(Handles.PositionHandle((directionToCenterB * newTangentB.magnitude), directionalMovementRotation) - nodePosition); break; // The node represents a line rather than a curve case Path.Node.Type.Vector: newTangentA = Vector3.zero; newTangentB = Vector3.zero; break; } // Snap tangent if in range of snap distance if (snapInput && node.TangentType != Path.Node.Type.Aligned) { // Snap before tangent adjustment application if (Mathf.Abs(newTangentB.x) < snapDistance) { newTangentB.x = 0; } if (Mathf.Abs(newTangentB.y) < snapDistance) { newTangentB.y = 0; } if (Mathf.Abs(newTangentB.z) < snapDistance) { newTangentB.z = 0; } if (Mathf.Abs(newTangentA.x) < snapDistance) { newTangentA.x = 0; } if (Mathf.Abs(newTangentA.y) < snapDistance) { newTangentA.y = 0; } if (Mathf.Abs(newTangentA.z) < snapDistance) { newTangentA.z = 0; } } // Show Tangent Handle Visual Additions // Get direction to handle minus the handles radius so that its flush with the edge of the circle Vector3 handleADistanceToEdge = handleSize * ((newTangentA + nodePosition) - (-newTangentA + nodePosition)).normalized; Vector3 handleBDistanceToEdge = handleSize * ((newTangentB + nodePosition) - (-newTangentB + nodePosition)).normalized; Handles.color = handleLineColor; Handles.DrawLine((newTangentA + nodePosition) - handleADistanceToEdge, nodePosition); Handles.DrawLine((-newTangentB + nodePosition) + handleBDistanceToEdge, nodePosition); newTangentA = newTangentA.RotateAround(Vector3.zero, Quaternion.Inverse(rotation)); newTangentB = newTangentB.RotateAround(Vector3.zero, Quaternion.Inverse(rotation)); // Mark this node as the last modified if (newTangentA != node.TangentA || newTangentB != node.TangentB) { lastModifiedNode = node; if (SelectedPath.Flat) { if (newTangentA.z != node.TangentA.z) { newTangentA.z = 0; } if (newTangentB.z != node.TangentB.z) { newTangentB.z = 0; } } // Apply tangent adjustment // Current fix for math loss if (currentEvent.button == 0) { // Apply node adjustments EditorGUI.BeginChangeCheck(); Undo.RecordObject(SelectedPath, "Adjust Path Tangent"); node.TangentA = newTangentA; node.TangentB = newTangentB; EditorGUI.EndChangeCheck(); } } #endregion #region Add new node Handles.color = addNodeColor; if (i < SelectedPath.Nodes.Count - 1) { if (Handles.Button((Path.CurvePoint(SelectedPath.Nodes[i], SelectedPath.Nodes[i + 1], 0.5f, scale) + position).RotateAround(position, rotation), Quaternion.identity, addNodeSize, addNodeSize, Handles.DotCap)) { EditorGUI.BeginChangeCheck(); Undo.RecordObject(SelectedPath, "Add Path Node"); SelectedPath.Add(i, 0.5f); lastModifiedNode = SelectedPath.Nodes[i + 1]; EditorGUI.EndChangeCheck(); } } #endregion } #region Remove node if (showingDeleteInput) { Handles.color = deleteColor; if (Handles.Button(nodePosition, Quaternion.identity, deleteSize, deleteSize, Handles.DotCap)) { EditorGUI.BeginChangeCheck(); Undo.RecordObject(SelectedPath, "Remove Path Node"); // Remove node SelectedPath.Remove(node); EditorGUI.EndChangeCheck(); } } #endregion } if (!showingDeleteInput) { // Show add button for closing int lastNode = SelectedPath.Nodes.Count - 1; Handles.color = addNodeColor; if (SelectedPath.Closed) { if (Handles.Button((Path.CurvePoint(SelectedPath.Nodes[SelectedPath.Nodes.Count - 1], SelectedPath.Nodes[0], 0.5f, scale) + position).RotateAround(position, rotation), Quaternion.identity, addNodeSize, addNodeSize, Handles.DotCap)) { SelectedPath.Add(lastNode, 0.5f); } } } }
public override void OnInspectorGUI() { SelectedPath.Closed = EditorGUILayout.Toggle("Closed", SelectedPath.Closed); SelectedPath.Flat = EditorGUILayout.Toggle("Flat", SelectedPath.Flat); if (SelectedPath.Flat && !previousInspectorPassFlat) { for (int i = 0; i < SelectedPath.Nodes.Count; i++) { SelectedPath.Nodes[i].TangentA.z = 0; SelectedPath.Nodes[i].TangentB.z = 0; } } previousInspectorPassFlat = SelectedPath.Flat; SelectedPath.Resolution = EditorGUILayout.IntSlider("Curve Resolution", SelectedPath.Resolution, 2, 120); inspectorCurvesExpanded = EditorGUILayout.Foldout(inspectorCurvesExpanded, "Path Curves"); if (inspectorCurvesExpanded) { for (int i = 0; i < SelectedPath.Nodes.Count; i++) { Path.Node node = SelectedPath.Nodes[i]; GUILayout.BeginHorizontal(); GUILayout.Space(10); bool selectedNode = EditorGUILayout.Foldout(lastModifiedNode == node, "Curve " + i); GUILayout.EndHorizontal(); if (selectedNode) { node.TangentType = (Path.Node.Type)EditorGUILayout.EnumPopup("Type", node.TangentType); node.Position = EditorGUILayout.Vector3Field("Postion", node.Position); node.TangentA = EditorGUILayout.Vector3Field("Tangent A", node.TangentA); node.TangentB = EditorGUILayout.Vector3Field("Tangent B", node.TangentB); GUILayout.BeginHorizontal(); if (GUILayout.Button("+", GUILayout.Width(30))) { EditorGUI.BeginChangeCheck(); Undo.RecordObject(SelectedPath, "Add Path Node"); // Remove node SelectedPath.Add(i, 0.5f); EditorGUI.EndChangeCheck(); } if (SelectedPath.Nodes.Count > 2) { if (GUILayout.Button("X", GUILayout.Width(30))) { EditorGUI.BeginChangeCheck(); Undo.RecordObject(SelectedPath, "Remove Path Node"); // Remove node SelectedPath.Remove(node); EditorGUI.EndChangeCheck(); } if (node != SelectedPath.Nodes[SelectedPath.Nodes.Count - 1]) { if (GUILayout.Button(@"\/")) { SelectedPath.Remove(node); SelectedPath.Nodes.Insert(i + 1, node); } } if (node != SelectedPath.Nodes[0]) { if (GUILayout.Button(@"/\")) { SelectedPath.Remove(node); SelectedPath.Nodes.Insert(i - 1, node); } } } GUILayout.EndHorizontal(); } } } }
protected void GoToNode(Node node, float speed) { myTransform.DOMove (node.transform.position, speed).SetEase(Ease.Linear).OnComplete (() => GetReachedToPoint(node)); }
public void PollPathDrawing() { Vector2 pos = WorldCreatorCursor.GetMousePos(); if (pathNodes == null) { pathNodes = new List <Path.Node>(); } if (Input.GetMouseButton(0)) { if (dragging) { selectedNode.position = pos; UpdateMesh(); } } if (Input.GetMouseButtonDown(0)) { int closest = GetClosestNodeIndex(pos); bool grabbed = false; if (closest >= 0) { float d = (pathNodes[closest].position - pos).sqrMagnitude; if (d < maxClickDistance * maxClickDistance) { Debug.Log("grabbed"); grabbed = true; dragging = true; selectedNode = pathNodes[closest]; selectedNode.position = pos; UpdateMesh(); } } if (!grabbed) { AddPoint(pos); } } else if (Input.GetMouseButtonUp(0)) { int closest = GetClosestNodeIndex(pos, selectedNode != null ? selectedNode.ID : -1); if (closest >= 0) { float d = (pathNodes[closest].position - pos).sqrMagnitude; if (d < maxClickDistance * maxClickDistance && dragging) { Path.Node from = selectedNode; Path.Node to = pathNodes[closest]; for (int i = 0; i < pathNodes.Count; i++) { for (int j = 0; j < pathNodes[i].children.Count; j++) { if (pathNodes[i].children[j] == from.ID) { pathNodes[i].children[j] = to.ID; } } } to.children.AddRange(from.children); for (int i = 0; i < to.children.Count; i++) { if (to.children[i] == to.ID) { to.children.RemoveAt(i--); continue; } for (int j = 0; j < to.children.Count; j++) { if (i != j && to.children[i] == to.children[j]) { to.children.RemoveAt(j--); } } } pathNodes.Remove(from); Debug.Log($"Combined {from.ID} to {to.ID}"); CleanPath(); UpdateMesh(); } } dragging = false; selectedNode = null; } if (Input.GetMouseButtonUp(1)) { int closest = GetClosestNodeID(pos); if (closest >= 0) { RemoveNode(closest); UpdateMesh(); Debug.Log($"Node {closest} removed!"); } } if (Input.GetKeyDown(KeyCode.Return)) { var pathData = new NodeEditorFramework.Standard.PathData(); pathData.waypoints = new List <NodeEditorFramework.Standard.PathData.Node>(); for (int i = 0; i < pathNodes.Count; i++) { pathData.waypoints.Add(new NodeEditorFramework.Standard.PathData.Node() { ID = pathNodes[i].ID, position = pathNodes[i].position, children = pathNodes[i].children }); } WorldCreatorCursor.finishPath.Invoke(pathData); WorldCreatorCursor.instance.SetMode(WorldCreatorCursor.originalCursorMode); Clear(); } }
public WalkToPointTask(Path.Node node) { currentNode = node; }
protected void GoalReachedNode(Node node) { if (node.Id == positionToGo) { myAnimator.SetTrigger("Land"); GameManagerForStates.Goal(); } if(totem.SoundToGetReach != null) SoundManager.Instance.Play (totem.SoundToGetReach); }
public void OnMouseButtonPress(Vector mousePos, int button, ModifierType Modifiers) { if (button == 1) { Path.Node node = FindNodeAt(mousePos); if (node == null) { if ((Modifiers & ModifierType.ControlMask) != 0) { Vector pointOnEdge = new Vector(0, 0); int addNode = FindPath(mousePos, ref pointOnEdge); if (addNode >= 0) { node = new Path.Node(); node.Pos = pointOnEdge; Command command = new SortedListAddCommand <Path.Node>("Added Path node", path, field, node, addNode + 1); command.Do(); UndoManager.AddCommand(command); } } else if (selectedNode == path.Nodes[path.Nodes.Count - 1]) { node = new Path.Node(); // Snap? if (application.SnapToGrid) { mousePos = new Vector((float)((int)mousePos.X / 32) * 32, (float)((int)mousePos.Y / 32) * 32); } node.Pos = mousePos; Command command = new SortedListAddCommand <Path.Node>("Added Path node", path, field, node); command.Do(); UndoManager.AddCommand(command); } else if (selectedNode == path.Nodes[0]) { node = new Path.Node(); node.Pos = mousePos; Command command = new SortedListAddCommand <Path.Node>("Added Path node", path, field, node, 0); command.Do(); UndoManager.AddCommand(command); } } if (node != selectedNode) { selectedNode = node; Redraw(); } if (selectedNode != null) { application.EditProperties(selectedNode, "Path Node"); dragging = true; pressPoint = mousePos; originalPos = selectedNode.Pos; } } else if (button == 3) { if (dragging) { dragging = false; selectedNode.Pos = originalPos; Redraw(); } else { Path.Node node = FindNodeAt(mousePos); if (node != null) //if we have clicked on a node.. { selectedNode = node; //..make that node active } PopupMenu(button); } } }
private void UpdateNearestNode() { Node lastNode = currentNode; Node nearestNode = PathBuilder.Instance.GetNearsetNode(myTransform.position); if (nearestNode != null && Math.Abs(Vector3.Distance(nearestNode.transform.position, myTransform.position)) < NODE_TOLERANCE && currentNode != nearestNode) { currentNode = nearestNode; if (OnNodeUpdated != null && lastNode != null) OnNodeUpdated(); } }
public void SetCurrentNode(Vector3 position) { currentNode = PathBuilder.Instance.GetNearsetNode(position); }
void createPath() { var constructs = new List <AirConstruct>(); constructs.AddRange(Object.FindObjectsOfType <AirConstruct>()); var nodes = new List <AutoNode>(); // Get end target for (int i = 0; i < constructs.Count; i++) { //TODO: find carrier (Add to blackboard) if (!FactionManager.IsAllied(constructs[i].faction, craft.faction)) { nodes.Add(new AutoNode() { construct = constructs[i], index = 0 }); constructs.RemoveAt(i); } } if (nodes.Count == 0) { ai.setMode(AirCraftAI.AIMode.Inactive); return; } int index = 0; while (constructs.Count > 0) { for (int i = 0; i < nodes.Count; i++) { if (nodes[i].index != index) { continue; } Vector3 zero = nodes[i].construct.spawnPoint; AirConstruct nearest = null; float minD = float.MaxValue; for (int j = 0; j < constructs.Count; j++) { float d = (constructs[j].spawnPoint - zero).sqrMagnitude; if (d < minD) { nearest = constructs[j]; minD = d; } } float trueDistance = Mathf.Sqrt(minD); for (int j = 0; j < constructs.Count; j++) { float d = (constructs[j].spawnPoint - zero).magnitude; if (d < trueDistance + 1f) { nodes.Add(new AutoNode() { construct = constructs[j], index = index + 1 }); constructs.RemoveAt(j); j--; } } } index++; } path = ScriptableObject.CreateInstance <Path>(); path.waypoints = new List <Path.Node>(); for (int i = 0; i < nodes.Count; i++) { var node = new Path.Node(); node.ID = nodes.Count - i - 1; node.position = nodes[i].construct.spawnPoint; List <int> children = new List <int>(); for (int j = 0; j < nodes.Count; j++) { if (nodes[j].index == nodes[i].index - 1) { children.Add(nodes.Count - j - 1); //Debug.Log("ID " + (nodes.Count - i - 1) + "'s child: " + (nodes.Count - j - 1)); } } node.children = children; path.waypoints.Add(node); //Debug.Log("Created a node (index " + nodes[i].index + ") @ " + node.position + " with ID " + node.ID + " and " + children.Count + "children."); } waypointID = 0; }
void Update() { #if UNITY_EDITOR if (Input.GetKeyDown(KeyCode.K)) { playing = false; if (NodeEditorFramework.Standard.WinSiegeCondition.OnSiegeWin != null) { NodeEditorFramework.Standard.WinSiegeCondition.OnSiegeWin.Invoke(sectorName); } Debug.Log("Victory!"); return; } #endif if (playing && enabled) { timer += Time.deltaTime; entitiesToRemove.Clear(); entitiesRemainingToRemove.Clear(); if ((current == null || (current.entities.Count == 0 && entitiesRemaining.Count == 0))) { if (waves.Count > 0) { entitiesRemaining.Clear(); current = waves.Dequeue(); waveCount++; AlertPlayers($"WAVE {waveCount}/{(waves.Count + waveCount)}"); timer = 0; } else if ((current.entities.Count == 0 && entitiesRemaining.Count == 0)) { playing = false; if (NodeEditorFramework.Standard.WinSiegeCondition.OnSiegeWin != null) { NodeEditorFramework.Standard.WinSiegeCondition.OnSiegeWin.Invoke(sectorName); } Debug.Log("Victory!"); return; } } // Debug.Log(current.entities.Count + " - " + entitiesRemaining.Count); foreach (var ent in current.entities) { if (timer >= ent.timeSinceWaveStartToSpawn) { if (!AIData.flags.Exists((f) => f.name == ent.flagName)) { Debug.LogError("<SiegeZoneManager> Invalid flag name."); continue; } ent.entity.position = AIData.flags.Find((f) => f.name == ent.flagName).transform.position; var sectorEntity = SectorManager.instance.SpawnEntity(SectorManager.GetBlueprintOfLevelEntity(ent.entity), ent.entity); if (sectorEntity as Drone || sectorEntity as ShellCore) { Path path = ScriptableObject.CreateInstance <Path>(); path.waypoints = new List <Path.Node>(); Path.Node node = new Path.Node(); var currentTargets = targets.FindAll(targ => targ && !FactionManager.IsAllied(sectorEntity.faction, targ.faction)); if (currentTargets.Count > 0) { node.position = currentTargets[Random.Range(0, currentTargets.Count)].transform.position; } else if (players.Count > 0) { node.position = players[Random.Range(0, players.Count)].transform.position; } node.children = new List <int>(); path.waypoints.Add(node); (sectorEntity as AirCraft).GetAI().setPath(path); } entitiesToRemove.Add(ent); if (!FactionManager.IsAllied(sectorEntity.faction, players[0].faction)) { entitiesRemaining.Add(sectorEntity); } } } foreach (var ent in entitiesToRemove) { current.entities.Remove(ent); } foreach (var ent in entitiesRemaining) { if (ent.GetIsDead()) { entitiesRemainingToRemove.Add(ent); } } foreach (var ent in entitiesRemainingToRemove) { entitiesRemaining.Remove(ent); } } }
private void ObstacleProperties(Obstacle obstacle) { ImGui.Checkbox("Show collider", ref obstacle.ShowCollider); ImGui.InputFloat3("Orientation", ref obstacle.Orientation); ImGui.InputFloat3("Position", ref obstacle.InitialPosition); ImGui.Separator(); if (ImGui.BeginTabBar("ObstacleTabs")) { if (ImGui.BeginTabItem("Shape")) { ImGui.Text($"Shape type: {obstacle.Shape}"); ImGui.Separator(); if (obstacle.Collider is BoxCollider box) // TODO: handle zero cases; when the dimensions are zeroed, objects disappear!!! { ImGui.InputFloat3("Half extents", ref box.Size); } else if (obstacle.Collider is SphereCollider sphere) { ImGui.InputFloat("Radius", ref sphere.Radius); } else if (obstacle.Collider is CylinderCollider cylinder) { ImGui.InputFloat("Radius", ref cylinder.Radius); ImGui.InputFloat("Half length", ref cylinder.HalfLength); } else if (obstacle.Collider is ConeCollider cone) { ImGui.InputFloat("Radius", ref cone.Radius); ImGui.InputFloat("Height", ref cone.Height); } ImGui.EndTabItem(); } if (ImGui.BeginTabItem("Physics")) { int type = (int)obstacle.Type; ImGui.Combo("Type", ref type, PhysicsHandler.RigidBodyTypes, PhysicsHandler.RigidBodyTypes.Length); obstacle.Type = (RigidBodyType)type; if (obstacle.Type == RigidBodyType.Dynamic) { ImGui.InputFloat("Mass", ref obstacle.Mass); } else { ImGui.PushStyleVar(ImGuiStyleVar.Alpha, 0.5f); ImGui.InputFloat("Mass", ref obstacle.Mass, 0, 0, null, ImGuiInputTextFlags.ReadOnly); ImGui.PopStyleVar(); } ImGui.EndTabItem(); } if (ImGui.BeginTabItem("Path")) { if (obstacle.Type == RigidBodyType.Kinematic) { var quarterWidth = 0.25f * ImGui.GetWindowContentRegionWidth(); Path.Node current = obstacle.Path.First.Child; int selectedIndex = -1; ImGui.PushStyleVar(ImGuiStyleVar.ChildRounding, 5); if (ImGui.BeginChild("ObstaclePath", new System.Numerics.Vector2(quarterWidth, ImGui.GetContentRegionAvail().Y), true, ImGuiWindowFlags.HorizontalScrollbar)) { while (current != null) { if (ImGui.Selectable($"Point {++selectedIndex}")) { _selectedPoint = current; _selectedPathIndex = selectedIndex; } current = current.Child; } if (selectedIndex == -1) { ImGui.TextWrapped("Path is empty."); } ImGui.EndChild(); } ImGui.SameLine(); ImGui.BeginGroup(); if (ImGui.Button("Add point")) { obstacle.Path.AddLast(new System.Numerics.Vector3[] { obstacle.Path.Last.Points[0] + System.Numerics.Vector3.UnitX }, null); } ImGui.Separator(); if (_selectedPoint != null) { ImGui.Text($"Point {_selectedPathIndex}"); var point = _selectedPoint.Points[0]; ImGui.InputFloat3("", ref point); obstacle.Path.ChangeNode(_selectedPoint, new System.Numerics.Vector3[] { point }, null); } ImGui.EndGroup(); } else { ImGui.TextWrapped("A path can be set only for Kinematic obstacles (see Physics tab)."); } ImGui.EndTabItem(); } ImGui.EndTabBar(); } }
protected abstract void GetReachedToPoint(Node node);
private void MoveToNextNode(Node leftNode, Node rightNode, Vector3 currentEulers, Vector3 turn90Dregrees) { if (leftNode != null) { lastDirection = Vector3.left; myTransform.DORotate (currentEulers - turn90Dregrees, 0.0F).OnComplete (() => Move ()); } else if (rightNode != null) { lastDirection = Vector3.right; myTransform.DORotate (currentEulers + turn90Dregrees, 0.0F).OnComplete (() => Move ()); } else EndGame ("Totem : " + totem.name+ " could not found a path to follow"); }
public void OnMouseButtonPress(Vector mousePos, int button, ModifierType Modifiers) { if(button == 1) { Path.Node node = FindNodeAt(mousePos); if(node == null) { if((Modifiers & ModifierType.ControlMask) != 0) { Vector pointOnEdge = new Vector(0, 0); int addNode = FindPath(mousePos, ref pointOnEdge); if(addNode >= 0) { node = new Path.Node(); node.Pos = pointOnEdge; Command command = new SortedListAddCommand<Path.Node>("Added Path node", path, field, node, addNode+1); command.Do(); UndoManager.AddCommand(command); } } else if(selectedNode == path.Nodes[path.Nodes.Count - 1]) { node = new Path.Node(); // Snap? if( application.SnapToGrid ) { mousePos = new Vector((float) ((int)mousePos.X / 32) * 32, (float) ((int)mousePos.Y / 32) * 32); } node.Pos = mousePos; Command command = new SortedListAddCommand<Path.Node>("Added Path node", path, field, node); command.Do(); UndoManager.AddCommand(command); } else if(selectedNode == path.Nodes[0]) { node = new Path.Node(); node.Pos = mousePos; Command command = new SortedListAddCommand<Path.Node>("Added Path node", path, field, node, 0); command.Do(); UndoManager.AddCommand(command); } } if(node != selectedNode) { selectedNode = node; Redraw(); } if(selectedNode != null) { application.EditProperties(selectedNode, "Path Node"); dragging = true; pressPoint = mousePos; originalPos = selectedNode.Pos; } } else if(button == 3) { if(dragging) { dragging = false; selectedNode.Pos = originalPos; Redraw(); } else { Path.Node node = FindNodeAt(mousePos); if (node != null) //if we have clicked on a node.. selectedNode = node; //..make that node active PopupMenu(button); } } }
void CleanPath() { if (pathNodes.Count == 0) { return; } // make sure there's a node 0 int zeroIndex = -1; for (int i = 0; i < pathNodes.Count; i++) { if (pathNodes[i].ID == 0) { zeroIndex = i; break; } } if (zeroIndex == -1) { int minID = int.MaxValue; for (int i = 0; i < pathNodes.Count; i++) { if (pathNodes[i].ID < minID) { minID = pathNodes[i].ID; } } pathNodes[GetNodeIndex(minID)].ID = 0; for (int i = 0; i < pathNodes.Count; i++) { for (int j = 0; j < pathNodes[i].children.Count; j++) { if (pathNodes[i].children[j] == minID) { pathNodes[i].children[j] = 0; } } } } // remove unconnected nodes var closedList = new List <int>(); var openList = new List <int>(); openList.Add(0); while (openList.Count > 0) { Path.Node current = pathNodes[GetNodeIndex(openList[0])]; for (int i = 0; i < current.children.Count; i++) { if (!closedList.Contains(current.ID)) { openList.Add(current.children[i]); } } closedList.Add(current.ID); openList.Remove(current.ID); } for (int i = 0; i < pathNodes.Count; i++) { bool found = false; for (int j = 0; j < closedList.Count; j++) { if (pathNodes[i].ID == closedList[j]) { found = true; break; } } if (!found) { Debug.Log($"Node {pathNodes[i].ID} removed!"); pathNodes.RemoveAt(i--); } } }
public WalkToPointTask(float x, float y, float z, float radius = 1f) { currentNode = Path.Node.Create(x, y, z, radius); }
public WalkToPointTask(Vector3 position, float radius = 1f) { currentNode = Path.Node.Create(position, radius); }
private void OnDelete(object o, EventArgs args) { if (path.Nodes.Count > 1) { Command command = new SortedListRemoveCommand<Path.Node>("Deleted Path node", path, field, selectedNode); command.Do(); UndoManager.AddCommand(command); selectedNode = null; dragging = false; Redraw(); } else { Application.EditorApplication.DeleteCurrentPath(); } }
public void AddNode(Node node) { nodes.Add (node); }