public static void CmdLunge(NPCDriver guard, Vector3 direction) { if (guard.ControlledByAI) { guard.Instance.GetComponent<Rigidbody>().AddForce(direction * 100f * Time.deltaTime, ForceMode.Impulse); } else { // dont know why we need to increase the force here guard.Instance.GetComponent<Rigidbody>().AddForce(direction * 1000f * Time.deltaTime, ForceMode.Impulse); } }
/// <summary> /// Moves a NPC towards a target, uses the pathfinding algorithm if the target is far /// or uses Steering arrive if the target is close. /// </summary> /// <param name="npc">The moving NPC's NPCDriver</param> /// <param name="target">The target game object</param> /// <param name="directMoveDistance">The distance at which the NPC should start using /// steering arrive to move towards its target</param> public static void MoveTo(NPCDriver npc, GameObject target, float directMoveDistance) { float distanceToTarget = GetShortestPathDistance(npc.Instance, target); Node startNode = FindClosestNode(npc.Instance); Node endNode = FindClosestNode(target); if (distanceToTarget > directMoveDistance) { npc.MovementDriver.ChangePath(endNode); } else if(distanceToTarget <= directMoveDistance || startNode == endNode) { float npcYPosition = npc.gameObject.transform.position.y; Vector3 targetPosition = new Vector3(target.transform.position.x, npcYPosition, target.transform.position.z); npc.MovementDriver.NPCMovement.Steering_Arrive(targetPosition); } }
/// <summary> /// Calculate heuristic for flanking /// </summary> /// <param name="currentNode"></param> /// <param name="targetNode"></param> /// <param name="npc"></param> /// <returns></returns> private static float CalculateEuclideanDistanceHeuristic(Node currentNode, Node targetNode, NPCDriver npc) { float result = 0.0f; result += Vector3.Distance(currentNode.position, targetNode.position); result += 200 - Vector3.Distance(currentNode.position, npc.Instance.transform.position); return result; }
public static List<Node> AStarFlank(Node start, Node finish, NPCDriver otherGuard) { List<Node> openList = new List<Node>(); List<Node> closedList = new List<Node>(); Dictionary<Node, Node> previous = new Dictionary<Node, Node>(); Dictionary<Node, float> costSoFar = new Dictionary<Node, float>(); Dictionary<Node, float> totalCost = new Dictionary<Node, float>(); foreach (Node node in vertices.Keys) { previous[node] = null; costSoFar[node] = float.MaxValue; totalCost[node] = float.MaxValue; } openList.Add(start); costSoFar[start] = 0.0f; totalCost[start] = CalculateEuclideanDistanceHeuristic(start, finish, otherGuard); while (openList.Count > 0) { Node currentNode = FindNodeWithMinCost(openList, totalCost); currentNode.SetMaterialColor(Color.blue); if (currentNode == finish) return StackToList(GetPath(start, finish, previous)); openList.Remove(currentNode); closedList.Add(currentNode); foreach (Node neighbor in vertices[currentNode].Keys) { if (closedList.Contains(neighbor)) continue; float newCostSoFar = costSoFar[currentNode] + vertices[currentNode][neighbor]; if (!openList.Contains(neighbor)) { openList.Add(neighbor); neighbor.SetMaterialColor(Color.yellow); } if (newCostSoFar >= costSoFar[neighbor]) continue; previous[neighbor] = currentNode; costSoFar[neighbor] = newCostSoFar; totalCost[neighbor] = costSoFar[neighbor] + CalculateEuclideanDistanceHeuristic(neighbor, finish, otherGuard); } } return null; }
public virtual void Setup(NPCDriver npc) { this.npc = npc; this.stateStack = new Stack<NPCState>(); this.TreesFound = new List<GameObject>(); }
public static NPCDriver FindClosestNPC(NPCDriver mainNPC, List<NPCDriver> npcs) { NPCDriver result = null; for (int i = 0; i < npcs.Count; i++) { if (i == 0) { result = npcs[i]; } if (Vector3.Distance(mainNPC.transform.position, npcs[i].transform.position) < Vector3.Distance(mainNPC.transform.position, result.transform.position)) { result = npcs[i]; } } return result; }
// Note: Can't seem to make this method generic using System.Type as a parameter // Thus, the repetition here public static List<GameObject> FindVisibleTrees(NPCDriver npc) { List<GameObject> visibleTrees = new List<GameObject>(); SoulTree[] allTrees = GameObject.FindObjectsOfType(typeof(SoulTree)) as SoulTree[]; foreach (SoulTree tree in allTrees) { Vector3 viewPortPosition = npc.CameraDriver.Camera.WorldToViewportPoint(tree.gameObject.transform.position); if (viewPortPosition.x >= 0.0f && viewPortPosition.x <= 1.0f && viewPortPosition.y >= 0.0f && viewPortPosition.y <= 1.0f && viewPortPosition.z >= 0.0f) { visibleTrees.Add(tree.gameObject); } } return visibleTrees; }
public override void Setup(NPCDriver npc) { base.Setup(npc); this.currentState = new CollectorSearchSoulsState(this); }
public static bool IsColliding(NPCDriver npc, GameObject collisionTarget) { Collider[] collisions = npc.CollisionArray; foreach (Collider collider in collisions) { if (collider.gameObject == collisionTarget) { return true; } } return false; }
public override void Setup(NPCDriver npc) { base.Setup(npc); this.TargetNPC = null; this.currentState = new GuardSearchState(this); }
public void Setup(NPCDriver npc) { this.npc = npc; }
public void ChangePathToFlank(Node endNode, NPCDriver otherGuard) { this.startNode = FindClosestNode(); this.endNode = endNode; this.pathList = Graph.AStarFlank(startNode, endNode, otherGuard); this.AttainedFinalNode = false; this.pathCounter = 0; }
public static GameObject FindClosestFullTreeButton(NPCDriver npc, int treeType) { List<GameObject> visibleTrees = NPCStateHelper.FindVisibleTrees(npc); List<SoulTree> filteredTrees = new List<SoulTree>(); List<GameObject> filteredTreeObjects = new List<GameObject>(); SoulTree targetTree = null; // Default just to assign variable GameObject targetbuttonObject; // Filter tree list by desired tree type and whether or not it has souls foreach (GameObject tree in visibleTrees) { SoulTree treeScript = tree.GetComponent<SoulTree>(); if (treeScript.TreeType == treeType && treeScript.IsFull && !treeScript.CheckIfTreeIsTargetted()) { filteredTrees.Add(treeScript); filteredTreeObjects.Add(tree); } } // If there is more than one tree, find the closest tree if (filteredTrees.Count > 1) { GameObject closestTreeObj = NPCStateHelper.FindClosestGameObjectByPath(npc.gameObject, filteredTreeObjects); targetTree = closestTreeObj.GetComponent<SoulTree>(); } else if (filteredTrees.Count == 1) { // There is only one tree targetTree = filteredTrees[0]; } // If the tree is multibutton, get closest button of tree if (targetTree) { List<GameObject> treeButtons = targetTree.TreeButtons; if (treeButtons.Count > 1) { GameObject closestButtonOfTree = NPCStateHelper.FindClosestGameObject(npc.gameObject, treeButtons); if (closestButtonOfTree) return closestButtonOfTree; } else { // Tree has only one button, return it return targetTree.TreeButtons[0]; } } return null; }
public static bool HasVisibleSouls(NPCDriver npc) { List<GameObject> visibleSouls = FindVisibleSouls(npc); if (visibleSouls.Count > 0) return true; return false; }