void stun() { posTimer = 30; posTimer2 = 25; stunTimer -= Time.deltaTime; if (stunTimer <= 0) { seen = false; seen = SeeObject(PlayerObject, LevelMask, home); foundFootprint = SeeFootprint(allNodes, LevelMask, home); if (seen) { State = TakaState.Chase; } else if (foundFootprint != null && awake == true) { nextFootprint = foundFootprint; State = TakaState.Follow; } else { State = TakaState.Idle; } } }
void idle() { posTimer = 30; posTimer2 = 25; if (FleeInu(LevelMask, home)) { State = TakaState.Flee; return; } seen = false; seen = SeeObject(PlayerObject, LevelMask, home); if (seen) { awake = true; State = TakaState.Chase; return; } foundFootprint = SeeFootprint(allNodes, LevelMask, home); if (foundFootprint != null) { nextFootprint = foundFootprint; State = TakaState.Follow; } else if (root != null) { State = TakaState.Patrol; } }
//function to be performed in idle state, containes transitions to other states void idle() { posTimer = 30; posTimer2 = 25; if (FleeInu(LevelMask, home)) { State = OniState.Flee; return; } seen = false; seen = SeeObject(PlayerObject, LevelMask, home); if (seen) { //if player has been seen chase awake = true; State = OniState.Chase; return; } foundFootprint = SeeFootprint(allNodes, LevelMask, home); if (foundFootprint != null) { //if footprints found follow nextFootprint = foundFootprint; State = OniState.Follow; return; } if (root != null) { //if neither and root exist, attempt to patrol State = OniState.Patrol; return; } }
//function to execute in stun state, containes transitions, and decrements stun timer void stun() { posTimer = 30; posTimer2 = 25; //decrement stun timer stunTimer -= Time.deltaTime; //if enough timer has passed transition to appropiate state if (stunTimer <= 0) { animState = OniAnim.Idle; seen = false; seen = SeeObject(PlayerObject, LevelMask, home); foundFootprint = SeeFootprint(allNodes, LevelMask, home); if (seen) { State = OniState.Chase; return; } else if (foundFootprint != null && awake == true) { nextFootprint = foundFootprint; State = OniState.Follow; return; } else { State = OniState.Idle; return; } } }
void chase() { if (FleeInu(LevelMask, home)) { State = TakaState.Flee; return; } if (Vector3.Distance(transform.position, home) < 2) { if (stuckBlocker <= 0) { if (IsStuck(newPosition, oldPosition, oldPosition2)) { posTimer = 0; posTimer = 5; if (TestDebug) { print("resetting path"); } agent.ResetPath(); previous2 = previous; previous = currentNode; currentNode = null; State = TakaState.Flee; return; } } } agent.ResetPath(); seen = false; seen = SeeObject(PlayerObject, LevelMask, home); if (!seen) { foundFootprint = SeeFootprint(allNodes, LevelMask, home); if (foundFootprint != null) { nextFootprint = foundFootprint; State = TakaState.Follow; } else { State = TakaState.Idle; } } agent.SetDestination(PlayerObject.transform.position); dest = PlayerObject.transform.position; if (Vector3.Distance(transform.position, dest) < 5) { //if taka close enough to player taunt them State = TakaState.Taunt; agent.SetDestination(transform.position); //gameObject.transform.rotation = startingRotation; } }
void follow() { //agent.ResetPath(); if (Vector3.Distance(transform.position, home) < 2) { if (stuckBlocker <= 0) { if (IsStuck(newPosition, oldPosition, oldPosition2)) { posTimer = 0; posTimer = 5; if (TestDebug) { print("resetting path"); } agent.ResetPath(); previous2 = previous; previous = currentNode; currentNode = null; State = InuState.Flee; return; } } } seen = false; seen = SeeObject(PlayerObject, LevelMask, home); if (seen) { State = InuState.Chase; nextFootprint = null; return; } if (nextFootprint == null) { foundFootprint = SeeFootprint(allNodes, LevelMask, home); if (foundFootprint == null) { nextFootprint = foundFootprint; State = InuState.Idle; } if (foundFootprint != null) { nextFootprint = foundFootprint; agent.SetDestination(foundFootprint.transform.position); } } else { if (Vector3.Distance(transform.position, nextFootprint.transform.position) < 2) { nextFootprint = nextFootprint.getNext(); } agent.SetDestination(nextFootprint.transform.position); } }
void look() { posTimer = 30; posTimer2 = 25; lookTimer -= Time.deltaTime; if (TestDebug) { print("lookTimer" + lookTimer); } if (FleeInu(LevelMask, home)) { State = OniState.Flee; return; } seen = false; seen = SeeObject(PlayerObject, LevelMask, home); if (seen) { //if player has been seen chase awake = true; State = OniState.Chase; return; } foundFootprint = SeeFootprint(allNodes, LevelMask, home); if (foundFootprint != null) { //if footprints found follow nextFootprint = foundFootprint; State = OniState.Follow; return; } transform.Rotate(Vector3.up * (360 * Time.deltaTime)); if (lookTimer <= 0) { if (root != null) { lookBlocker = 10; //old destination reached, update patrol path closest = null; closest = UpdateClosest(closest, nodes, currentNode, previous, previous2, rb); if (closest != null) { previous2 = previous; previous = currentNode; currentNode = closest; } State = OniState.Patrol; return; } } }
private void PlaceFootprint() { Vector3 footPosition = transform.position + (rightFootLast? transform.right * Radius / 2f : -transform.right * Radius / 2f); Ray ray = new Ray(footPosition, Vector3.down); RaycastHit rayHit; //print("placing footprint"); Debug.DrawRay(footPosition, Vector3.down, Color.green, 5.0F); if (Physics.Raycast(ray, out rayHit, controller.height, mask)) { Vector3 position = rayHit.point + rayHit.normal * 0.001f; GameObject prefab = NextPrefab(); previousFootprint = currentFootprint; // Spawn currentFootprint = Instantiate(prefab).GetComponent <FootprintList>(); currentFootprint.transform.position = position; currentFootprint.transform.rotation = transform.rotation; currentFootprint.transform.parent = footPrintParent.transform; currentFootprint.GetComponent <FootprintDecay>().SetLifeTime(FootprintLifetime); //print("pos " + currentFootprint.transform.position); if (rayHit.collider.gameObject.layer == dynamicObjectLayer) { // attach footprint to dynamic objects AttachTo a = currentFootprint.gameObject.AddComponent <AttachTo>(); a.To = rayHit.collider.gameObject; a.UseWorldSpace = true; } // Set Linked List if (previousFootprint != null) { previousFootprint.setNext(currentFootprint); } currentFootprint.setPrevious(previousFootprint); // Prep for next footprint distanceTraveled = 0f; rightFootLast = !rightFootLast; if (gameObject.CompareTag("Player")) { //print("attempting to add footprint to dictionary"); GameManager.Instance.AddFootprint(currentFootprint, footPosition); } } }
void chase() { if (Vector3.Distance(transform.position, home) < 2) { if (stuckBlocker <= 0) { if (IsStuck(newPosition, oldPosition, oldPosition2)) { posTimer = 0; posTimer = 5; if (TestDebug) { print("resetting path"); } agent.ResetPath(); previous2 = previous; previous = currentNode; currentNode = null; State = InuState.Flee; return; } } } seen = false; seen = SeeObject(PlayerObject, LevelMask, home); if (!seen) { foundFootprint = SeeFootprint(allNodes, LevelMask, home); if (foundFootprint != null) { nextFootprint = foundFootprint; State = InuState.Follow; } else { State = InuState.Idle; } } dest = playerTransform.position; agent.SetDestination(dest); if (Vector3.Distance(transform.position, dest) < 5) { //if close enough to player attempt to stalk player State = InuState.Stalk; agent.SetDestination(transform.position); } }
public void AddFootprint(FootprintList newFootprint, Vector3 fposition) { int key = 0; key = GetKey(fposition); //FootprintMap.Add(key, newFootprint); if (FootprintMap.ContainsKey(key)) { //print("updating key"); List <FootprintList> prints = new List <FootprintList>(); prints = FootprintMap[key]; prints.Add(newFootprint); FootprintMap[key] = prints; } else { //print("created key and added to dictionary"); List <FootprintList> prints = new List <FootprintList>(); prints.Add(newFootprint); FootprintMap.Add(key, prints); } }
//function to execute in follow state, contains transitions, and code to follow footprints towards player void follow() { //agent.ResetPath(); if (FleeInu(LevelMask, home)) { State = OniState.Flee; return; } if (Vector3.Distance(transform.position, home) < 2) { //if positions have not changed enough determine Oni to be stuck and change behavior pattern //reset timers to give chance to move before checking again if (stuckBlocker <= 0) { if (IsStuck(newPosition, oldPosition, oldPosition2)) { posTimer = 0; posTimer = 5; if (TestDebug) { print("resetting path in patrol"); } agent.ResetPath(); previous2 = previous; previous = currentNode; currentNode = null; State = OniState.Flee; stuckBlocker = 30; return; } } } seen = false; seen = SeeObject(PlayerObject, LevelMask, home); if (seen) { State = OniState.Chase; nextFootprint = null; return; } //if there is no next footprint try to find a new footprint to follow if (nextFootprint == null) { foundFootprint = SeeFootprint(allNodes, LevelMask, home); if (foundFootprint == null) { State = OniState.Idle; return; } if (foundFootprint != null) { nextFootprint = foundFootprint; agent.SetDestination(foundFootprint.transform.position); } } //else move towards next footprint else { if (Vector3.Distance(transform.position, nextFootprint.gameObject.transform.position) < 2) { //update next footprint to continue following the trail nextFootprint = nextFootprint.getNext(); if (nextFootprint == null) { //print("next dne"); } } if (nextFootprint != null) { //print("nextfootprint " + nextFootprint.gameObject.transform.position); agent.SetDestination(nextFootprint.gameObject.transform.position); } } }
//function to execute in stalk state, contains transitions, and code to maintain distance from player and attempt to avoid being cornered void stalk() { posTimer = 30; posTimer2 = 25; if (AttackTimer > 0) { AttackTimer -= Time.deltaTime; } //print(AttackTimer); //attack timer reachers 0 attack if (AttackTimer <= 0) { State = InuState.Cornered; return; } AnimState = InuAnim.Creep; //rayDirection = playerTransform.position - transform.position; //rayDirection.y = 0; playerCloseToEnemy = Vector3.Distance(playerTransform.position, transform.position) < StalkDistance; if (!playerCloseToEnemy) { beenTooClose = false; seen = false; seen = SeeObject(PlayerObject, LevelMask, home); if (seen) { State = InuState.Chase; return; } foundFootprint = SeeFootprint(allNodes, LevelMask, home); if (foundFootprint != null) { State = InuState.Follow; return; } else if (StartingNode != null) { State = InuState.Patrol; return; } else { State = InuState.Idle; return; } } //check to see if player is close enough to trigger cornered state playerTooCloseToEnemy = Vector3.Distance(playerTransform.position, transform.position) < StartCorneredDistance; if (playerTooCloseToEnemy) { //signify the player is too close to the inu //print("too close"); beenTooClose = true; //get the distance from player to inu newdir = transform.position - playerTransform.position; //create containers for attempted destinations destinationNode = null; secondDestNode = null; tertDestNode = null; //get current node based on location currentLocation = new Vector3(transform.position.x, home.y + 1.5F, transform.position.z); fromNode = MazeGenerator.getNodeBasedOnLocation(currentLocation); //print("current location " + new Vector3(transform.position.x, home.y + 1.5F, transform.position.z)); //print("from node " + new Vector3(fromNode.Col * 6 + 8, fromNode.Floor * 30, fromNode.Row * 6 + 8)); //get the player's current node playerNode = MazeGenerator.getNodeBasedOnLocation(playerTransform.position); //if the change in x is greater than the change in z try to move in the x direction first if (Math.Abs(newdir.x) > Math.Abs(newdir.z)) { //if the change in x is positive if (newdir.x > 0) { //set primary destination to be the node with the next higher value in the x direction destinationNode = MazeGenerator.getNodeBasedOnLocation(new Vector3((fromNode.Col + 1) * 6 + 8, fromNode.Floor * 30, fromNode.Row * 6 + 8)); //if change in z is positive if (newdir.z > 0) { //set secondary destination to be the node with the next higher value in the z direction secondDestNode = MazeGenerator.getNodeBasedOnLocation(new Vector3(fromNode.Col * 6 + 8, fromNode.Floor * 30, (fromNode.Row + 1) * 6 + 8)); } if (newdir.z < 0) { secondDestNode = MazeGenerator.getNodeBasedOnLocation(new Vector3(fromNode.Col * 6 + 8, fromNode.Floor * 30, (fromNode.Row - 1) * 6 + 8)); } } if (newdir.x < 0) { destinationNode = MazeGenerator.getNodeBasedOnLocation(new Vector3((fromNode.Col - 1) * 6 + 8, fromNode.Floor * 30, fromNode.Row * 6 + 8)); if (newdir.z > 0) { secondDestNode = MazeGenerator.getNodeBasedOnLocation(new Vector3(fromNode.Col * 6 + 8, fromNode.Floor * 30, (fromNode.Row + 1) * 6 + 8)); } if (newdir.z < 0) { secondDestNode = MazeGenerator.getNodeBasedOnLocation(new Vector3(fromNode.Col * 6 + 8, fromNode.Floor * 30, (fromNode.Row - 1) * 6 + 8)); } } } //if the change in x is the same as the change in the z direction, used rand with two possible values if (Math.Abs(newdir.x) == Math.Abs(newdir.z)) { rand = UnityEngine.Random.Range(0, 1); if (rand == 0) { if (newdir.x > 0) { destinationNode = MazeGenerator.getNodeBasedOnLocation(new Vector3((fromNode.Col + 1) * 6 + 8, fromNode.Floor * 30, fromNode.Row * 6 + 8)); if (newdir.z > 0) { secondDestNode = MazeGenerator.getNodeBasedOnLocation(new Vector3(fromNode.Col * 6 + 8, fromNode.Floor * 30, (fromNode.Row + 1) * 6 + 8)); } if (newdir.z < 0) { secondDestNode = MazeGenerator.getNodeBasedOnLocation(new Vector3(fromNode.Col * 6 + 8, fromNode.Floor * 30, (fromNode.Row - 1) * 6 + 8)); } } if (newdir.x < 0) { destinationNode = MazeGenerator.getNodeBasedOnLocation(new Vector3((fromNode.Col - 1) * 6 + 8, fromNode.Floor * 30, fromNode.Row * 6 + 8)); if (newdir.z > 0) { secondDestNode = MazeGenerator.getNodeBasedOnLocation(new Vector3(fromNode.Col * 6 + 8, fromNode.Floor * 30, (fromNode.Row + 1) * 6 + 8)); } if (newdir.z < 0) { secondDestNode = MazeGenerator.getNodeBasedOnLocation(new Vector3(fromNode.Col * 6 + 8, fromNode.Floor * 30, (fromNode.Row - 1) * 6 + 8)); } } } if (rand == 1) { if (newdir.z > 0) { destinationNode = MazeGenerator.getNodeBasedOnLocation(new Vector3(fromNode.Col * 6 + 8, fromNode.Floor * 30, (fromNode.Row + 1) * 6 + 8)); if (newdir.x > 0) { secondDestNode = MazeGenerator.getNodeBasedOnLocation(new Vector3((fromNode.Col + 1) * 6 + 8, fromNode.Floor * 30, fromNode.Row * 6 + 8)); } if (newdir.x < 0) { secondDestNode = MazeGenerator.getNodeBasedOnLocation(new Vector3((fromNode.Col - 1) * 6 + 8, fromNode.Floor * 30, fromNode.Row * 6 + 8)); } } if (newdir.z < 0) { destinationNode = MazeGenerator.getNodeBasedOnLocation(new Vector3(fromNode.Col * 6 + 8, fromNode.Floor * 30, (fromNode.Row - 1) * 6 + 8)); if (newdir.x > 0) { secondDestNode = MazeGenerator.getNodeBasedOnLocation(new Vector3((fromNode.Col + 1) * 6 + 8, fromNode.Floor * 30, fromNode.Row * 6 + 8)); } if (newdir.x < 0) { secondDestNode = MazeGenerator.getNodeBasedOnLocation(new Vector3((fromNode.Col - 1) * 6 + 8, fromNode.Floor * 30, fromNode.Row * 6 + 8)); } } } } //if the change in x is less than the change in z try to move in the z direction first if (Math.Abs(newdir.x) < Math.Abs(newdir.z)) { if (newdir.z > 0) { destinationNode = MazeGenerator.getNodeBasedOnLocation(new Vector3(fromNode.Col * 6 + 8, fromNode.Floor * 30, (fromNode.Row + 1) * 6 + 8)); if (newdir.x > 0) { secondDestNode = MazeGenerator.getNodeBasedOnLocation(new Vector3((fromNode.Col + 1) * 6 + 8, fromNode.Floor * 30, fromNode.Row * 6 + 8)); } if (newdir.x < 0) { secondDestNode = MazeGenerator.getNodeBasedOnLocation(new Vector3((fromNode.Col - 1) * 6 + 8, fromNode.Floor * 30, fromNode.Row * 6 + 8)); } } if (newdir.z < 0) { destinationNode = MazeGenerator.getNodeBasedOnLocation(new Vector3(fromNode.Col * 6 + 8, fromNode.Floor * 30, (fromNode.Row - 1) * 6 + 8)); if (newdir.x > 0) { secondDestNode = MazeGenerator.getNodeBasedOnLocation(new Vector3((fromNode.Col + 1) * 6 + 8, fromNode.Floor * 30, fromNode.Row * 6 + 8)); } if (newdir.x < 0) { secondDestNode = MazeGenerator.getNodeBasedOnLocation(new Vector3((fromNode.Col - 1) * 6 + 8, fromNode.Floor * 30, fromNode.Row * 6 + 8)); } } } //get the list of nodes adjacent to the inu's current node adjacent = fromNode.GetAdjacentNodes(); for (int iter = 0; iter < adjacent.Count; iter++) { //if new node, it is recored as tertiary destination if (adjacent[iter] != destinationNode && adjacent[iter] != secondDestNode && adjacent[iter] != playerNode) { tertDestNode = adjacent[iter]; //check to see if tertiary is behind player and thus not valid inuToPlayer = playerTransform.position - transform.position; inuToTert = new Vector3(tertDestNode.Col * 6 + 8, tertDestNode.Floor * 30, tertDestNode.Row * 6 + 8) - transform.position; if (inuToPlayer.x > 0 && inuToTert.x > 0) { if (inuToPlayer.z > 0 && inuToTert.z > 0) { tertDestNode = null; } if (inuToPlayer.z < 0 && inuToTert.z < 0) { tertDestNode = null; } } if (inuToPlayer.x < 0 && inuToTert.x < 0) { if (inuToPlayer.z > 0 && inuToTert.z > 0) { tertDestNode = null; } if (inuToPlayer.z < 0 && inuToTert.z < 0) { tertDestNode = null; } } } } //check if primary and secondary are valid nodes if (adjacent.Contains(destinationNode) == false) { if (destinationNode != null) { //print("primary not adjacent " + new Vector3(destinationNode.Col * 6 + 8, fromNode.Floor * 30, destinationNode.Row * 6 + 8)); destinationNode = null; } else { //print("no primary dest found"); } } if (adjacent.Contains(secondDestNode) == false) { if (secondDestNode != null) { //print("secondary not adjacent " + new Vector3(secondDestNode.Col * 6 + 8, fromNode.Floor * 30, secondDestNode.Row * 6 + 8)); secondDestNode = null; } else { //print("no secondary dest found"); } } //try nodes in order if (destinationNode == null) { //print("primary not valid"); if (secondDestNode == null) { //print("secondary not valid"); if (tertDestNode == null) { //print("tertiary not valid"); //try to move backwards anyways newdir.y = 0; //normalize to get direction only newdir.Normalize(); //create a scalar scalar = (float)Math.Sqrt(15); //scale direction vector to set distace to go newdir.Scale(new Vector3(scalar, 1, scalar)); //set inu to go from current direction to scalar distance in normalized direction goal = playerTransform.position + newdir; wallDistance = newdir.magnitude; ray = new Ray(playerTransform.position, newdir); //if wall in the way transition to cornered if (Physics.Raycast(ray, out rayHit, wallDistance, LevelMask)) { State = InuState.Cornered; return; } //else move backwards away from player else { agent.ResetPath(); agent.SetDestination(goal); retreating = true; return; } } //move to tertiary destination else { //print("trying to go to tert " + new Vector3(tertDestNode.Col * 6 + 8, fromNode.Floor * 30, tertDestNode.Row * 6 + 8)); agent.ResetPath(); agent.SetDestination(new Vector3(tertDestNode.Col * 6 + 8, fromNode.Floor * 30, tertDestNode.Row * 6 + 8)); retreating = true; return; } } //move to secondary destination else { //print("trying to go to second " + new Vector3(secondDestNode.Col * 6 + 8, fromNode.Floor * 30, secondDestNode.Row * 6 + 8)); agent.ResetPath(); agent.SetDestination(new Vector3(secondDestNode.Col * 6 + 8, fromNode.Floor * 30, secondDestNode.Row * 6 + 8)); retreating = true; return; } } //move to primary destination else { print("trying to go to primary " + new Vector3(destinationNode.Col * 6 + 8, fromNode.Floor * 30, destinationNode.Row * 6 + 8)); agent.ResetPath(); agent.SetDestination(new Vector3(destinationNode.Col * 6 + 8, fromNode.Floor * 30, destinationNode.Row * 6 + 8)); retreating = true; return; } } //if player is not close enough for cornered if (!playerTooCloseToEnemy && beenTooClose == true) { retreating = false; beenTooClose = false; } //if not retrreating maintain distance from player if (retreating != true) { agent.ResetPath(); dest = playerTransform.position; if (Vector3.Distance(transform.position, dest) < 5) { agent.ResetPath(); agent.SetDestination(transform.position); } else { //print("stalking towards player"); agent.SetDestination(dest); } } //if player has tripper kill them, trip not currently implemented if (hasPlayerTripped()) { if (UnityEngine.XR.XRDevice.isPresent) { player = PlayerObject.GetComponentInParent <Actor>(); GameManager.Instance.ActorKilled(actorID, player); } else { GameManager.Instance.ActorKilled(actorID, PlayerObject.GetComponent <Actor>()); } GameManager.Instance.GameOver(); PlayerObject.SetActive(false); print("GameOver"); } }
//function to execute in chase state, contains transitions, code to move towards player, and code to kill player void chase() { //ensure old path is cleared //agent.ResetPath(); if (FleeInu(LevelMask, home)) { State = OniState.Flee; return; } if (Vector3.Distance(transform.position, home) < 2) { //if positions have not changed enough determine Oni to be stuck and change behavior pattern //reset timers to give chance to move before checking again if (stuckBlocker <= 0) { if (IsStuck(newPosition, oldPosition, oldPosition2)) { posTimer = 0; posTimer = 5; if (TestDebug) { print("resetting path in patrol"); } agent.ResetPath(); previous2 = previous; previous = currentNode; currentNode = null; State = OniState.Flee; stuckBlocker = 30; return; } } } //check if oni can still see player seen = false; seen = SeeObject(PlayerObject, LevelMask, home); if (!seen) { foundFootprint = SeeFootprint(allNodes, LevelMask, home); if (foundFootprint != null) { nextFootprint = foundFootprint; State = OniState.Follow; return; } else { State = OniState.Idle; return; } } //rayDirection = playerTransform.position - transform.position; //rayDirection.y = 0; //check if player is within the kill distance playerCloseToEnemy = Vector3.Distance(playerTransform.position, transform.position) < KillDistance; if (playerCloseToEnemy) { //if VR device is present the player's actor component is in its parent if (UnityEngine.XR.XRDevice.isPresent) { player = PlayerObject.GetComponentInParent <Actor>(); GameManager.Instance.ActorKilled(actorID, player); } else { //otherwise the player's actor component is a part of the player object GameManager.Instance.ActorKilled(actorID, PlayerObject.GetComponent <Actor>()); } State = OniState.GameOver; //let game manager know that the game should end GameManager.Instance.GameOver(); if (TestDebug) { print("GameOver"); } } //have oni set the player's current position to be its destination agent.SetDestination(playerTransform.position); }
//function to execute in flee state, contains transitions, and code to return to spawn position void flee() { posTimer = 30; posTimer2 = 10; //if enough time has passed the oni may interrupt flee to chase player or follow footprints fleeTimer -= Time.deltaTime; if (fleeTimer <= 0) { seen = false; seen = SeeObject(PlayerObject, LevelMask, home); if (seen) { awake = true; State = OniState.Chase; return; } foundFootprint = SeeFootprint(allNodes, LevelMask, home); if (foundFootprint != null) { nextFootprint = foundFootprint; State = OniState.Follow; return; } } //return to home position agent.ResetPath(); foreach (MazeNode n in currentPath) { n.EnemyPathNode = false; } //make sure that all the current pathnodes are made not enemy path nodes //check iterate through to see if there is an obstacle in the way //if there is, set the new destination as the spot right before the obstacle //otherwise, set the home as destination //either way, set path to location as enemy path nodes targetPos = new Vector3(); if (fleeTarget == null) { presentNode = new MazeNode(); obstacle = false; column = homeNode.Col; row = homeNode.Row; foreach (MazeNode n in MazeGenerator.nodesInSection(root)) { if (n.Col == column && n.Row == row) { presentNode = n; } } possiblePath = MazeGenerator.GetPath2(presentNode, homeNode); prevCheckNode = presentNode; foreach (MazeNode n in possiblePath) { if (n.EnemyPathNode || GameManager.trapNode(n)) { if (homeNode.Col == 9 && homeNode.Row == 2) { print(column + " " + row); } fleeTarget = prevCheckNode; obstacle = true; break; } prevCheckNode = n; } if (!obstacle) { fleeTarget = homeNode; } fleePath = MazeGenerator.GetPath2(presentNode, fleeTarget); foreach (MazeNode n in fleePath) { n.EnemyPathNode = true; } } targetPos = new Vector3(fleeTarget.Col * 6 + 8, fleeTarget.Floor * 30, fleeTarget.Row * 6 + 8); if (homeNode.Col == 9 && homeNode.Row == 2) { print(fleeTarget.Col + " " + fleeTarget.Row); } agent.SetDestination(targetPos); if (Vector3.Distance(transform.position, targetPos) < 2) { //undo path nodes except the one she ends on foreach (MazeNode n in fleePath) { if (n.Col != fleeTarget.Col || n.Row != fleeTarget.Row) { n.EnemyPathNode = false; } } fleeTarget = null; State = OniState.Idle; gameObject.transform.rotation = startingRotation; return; } }
//function to execute in patrol state, contains transitions as well as code to navigate patrol nodes void patrol() { if (FleeInu(LevelMask, home)) { State = OniState.Flee; return; } if (Vector3.Distance(transform.position, home) < 2) { //if positions have not changed enough determine Oni to be stuck and change behavior pattern //reset timers to give chance to move before checking again if (stuckBlocker <= 0) { if (IsStuck(newPosition, oldPosition, oldPosition2)) { posTimer = 0; posTimer = 5; if (TestDebug) { print("resetting path in patrol"); } agent.ResetPath(); previous2 = previous; previous = currentNode; currentNode = null; State = OniState.Flee; stuckBlocker = 30; return; } } } seen = false; seen = SeeObject(PlayerObject, LevelMask, home); if (seen) { awake = true; State = OniState.Chase; return; } foundFootprint = SeeFootprint(allNodes, LevelMask, home); if (foundFootprint != null) { nextFootprint = foundFootprint; State = OniState.Follow; return; } //if nodes exist if (root != null) { //container for current node's position //bool to check if current was set and not updated bool setCurrent = false; if (currentNode == null) { //if current does not exist closest = null; //call set to start patrol path closest = SetClosest(closest, homeNode, nodes, rb); //update current currentNode = closest; //update previous if (previous == null) { previous = currentNode; previous2 = previous; } //indicate current was set setCurrent = true; } //if current exists if (currentNode != null) { //get current node's position currentNodePosition = new Vector3(currentNode.Col * 6 + 8, currentNode.Floor * 30, currentNode.Row * 6 + 8); //if current was not set this game loop, check to see if updating is necessary if (setCurrent == false) { if (Vector3.Distance(transform.position, currentNodePosition) < 2) { if (lookBlocker <= 0) { lookTimer = 4; agent.SetDestination(transform.position); state = OniState.LookAround; } else { MazeNode closest = null; closest = UpdateClosest(closest, nodes, currentNode, previous, previous2, rb); if (closest != null) { /*closest = null; * closest = UpdateClosest(closest, nodes, currentNode, previous, previous2, rb); * if (closest != null) * { * previous2 = previous; * previous = currentNode; * currentNode = closest; * }*/ previous2 = previous; previous = currentNode; currentNode = closest; } } } //update current node's postion if (currentNode != null) { currentNodePosition = new Vector3(currentNode.Col * 6 + 8, currentNode.Floor * 30, currentNode.Row * 6 + 8); } } //set A.I. to move to current node agent.SetDestination(currentNodePosition); } } }
public void setNext(FootprintList footprint) { NextFootprint = footprint; }
public FootprintList SeeFootprint(List <MazeNode> nodes, LayerMask levelMask, Vector3 home) { MazeNode findFootprintOrigin = new MazeNode(); List <MazeNode> nodesToCheck = new List <MazeNode>(); List <FootprintList> footprintsToFollow = new List <FootprintList>(); int column = Mathf.RoundToInt(((gameObject.transform.position.x - 8) / 6)); int row = Mathf.RoundToInt(((gameObject.transform.position.z - 8) / 6)); int floor = Mathf.RoundToInt((gameObject.transform.position.y / 30)); foreach (MazeNode n in nodes) { if (n.Col == column && n.Row == row) { findFootprintOrigin = n; } } int direction = (int)Mathf.Round(transform.rotation.eulerAngles.y / 90); //print("direction " + direction); if (findFootprintOrigin == null) { //print("origin dne"); } else { //print("origin found"); if (direction == 0 || direction == 4) { if (findFootprintOrigin.Forward != null) { //print("found node forward"); nodesToCheck.Add(findFootprintOrigin.Forward); for (int iter = 0; iter < 4; iter++) { int curIndex = nodesToCheck.Count - 1; if (nodesToCheck[curIndex].Forward != null) { nodesToCheck.Add(nodesToCheck[curIndex].Forward); } } } } if (direction == 1) { if (findFootprintOrigin.Right != null) { //print("found node right"); nodesToCheck.Add(findFootprintOrigin.Right); for (int iter = 0; iter < 4; iter++) { int curIndex = nodesToCheck.Count - 1; if (nodesToCheck[curIndex].Right != null) { nodesToCheck.Add(nodesToCheck[curIndex].Right); } } } } if (direction == 2) { if (findFootprintOrigin.Backward != null) { //print("found node backward"); nodesToCheck.Add(findFootprintOrigin.Backward); for (int iter = 0; iter < 4; iter++) { int curIndex = nodesToCheck.Count - 1; if (nodesToCheck[curIndex].Backward != null) { nodesToCheck.Add(nodesToCheck[curIndex].Backward); } } } } if (direction == 3) { if (findFootprintOrigin.Left != null) { //print("found node left"); nodesToCheck.Add(findFootprintOrigin.Left); for (int iter = 0; iter < 4; iter++) { int curIndex = nodesToCheck.Count - 1; if (nodesToCheck[curIndex].Left != null) { nodesToCheck.Add(nodesToCheck[curIndex].Left); } } } } for (int iterCheck = 0; iterCheck < nodesToCheck.Count; iterCheck++) { int key = GameManager.Instance.GetKeyFromNode(nodesToCheck[iterCheck]); if (GameManager.Instance.FootprintMap.ContainsKey(key)) { //print("key found"); footprintsToFollow.AddRange(GameManager.Instance.FootprintMap[key]); } else { //print("key not in dictionary"); } } //create function to iterate through footprints until found last that can be seen, //saves last seen and checks next until seeobject fails, returns last FootprintList mostRecent = null; if (footprintsToFollow.Count == 0) { //print("no footprints to follow"); } else { for (int printIter = 0; printIter < footprintsToFollow.Count; printIter++) { if (printIter == 0) { mostRecent = footprintsToFollow[printIter]; } if (footprintsToFollow[printIter].NextFootprint != null) { if (SeeObject(footprintsToFollow[printIter].NextFootprint.gameObject, levelMask, home)) { mostRecent = footprintsToFollow[printIter].NextFootprint; } } else { break; } } //print("found footprint"); return(mostRecent); } } //print("did not find footprint"); return(null); }
void flee() { posTimer = 30; posTimer2 = 25; fleeTimer -= Time.deltaTime; if (fleeTimer <= 0) { seen = false; seen = SeeObject(PlayerObject, LevelMask, home); if (seen) { awake = true; State = InuState.Chase; return; } foundFootprint = SeeFootprint(allNodes, LevelMask, home); if (foundFootprint != null) { nextFootprint = foundFootprint; State = InuState.Follow; return; } } agent.ResetPath(); Vector3 targetPos = new Vector3(); if (fleeTarget == null) { MazeNode presentNode = new MazeNode(); bool obstacle = false; int column = homeNode.Col; int row = homeNode.Row; foreach (MazeNode n in MazeGenerator.nodesInSection(root)) { if (n.Col == column && n.Row == row) { presentNode = n; } } LinkedList <MazeNode> possiblePath = MazeGenerator.GetPath2(presentNode, homeNode); MazeNode prevCheckNode = presentNode; foreach (MazeNode n in possiblePath) { if (n.EnemyPathNode || GameManager.trapNode(n)) { fleeTarget = prevCheckNode; obstacle = true; break; } prevCheckNode = n; } if (!obstacle) { fleeTarget = homeNode; } fleePath = MazeGenerator.GetPath2(presentNode, fleeTarget); foreach (MazeNode n in fleePath) { n.EnemyPathNode = true; } } targetPos = new Vector3(fleeTarget.Col * 6 + 8, fleeTarget.Floor * 30, fleeTarget.Row * 6 + 8); if (Vector3.Distance(transform.position, targetPos) < 2) { State = InuState.Idle; gameObject.transform.rotation = startingRotation; } /* * if (Vector3.Distance(transform.position, home) < 2) * { * State = InuState.Idle; * gameObject.transform.rotation = startingRotation; * } */ }
public void setPrevious(FootprintList footprint) { PreviousFootprint = footprint; }
void flee() { posTimer = 30; posTimer2 = 25; fleeTimer -= Time.deltaTime; if (fleeTimer <= 0) { seen = false; seen = SeeObject(PlayerObject, LevelMask, home); if (seen) { awake = true; State = TakaState.Chase; return; } foundFootprint = SeeFootprint(allNodes, LevelMask, home); if (foundFootprint != null) { nextFootprint = foundFootprint; State = TakaState.Follow; return; } } agent.ResetPath(); if (mr == null) { //mr = gameObject.GetComponentInChildren<MeshRenderer>(); mr = gameObject.GetComponentInChildren <Transform>(); } //if taka has grown, shrink it if (shrinkTimer > 0) { shrinkTimer -= Time.deltaTime; mr.transform.localScale -= new Vector3(0, 0.002F, 0); mr.transform.position -= new Vector3(0, 0.001F, 0); distanceToFloor -= 0.01F; } targetPos = new Vector3(); if (fleeTarget == null) { presentNode = new MazeNode(); obstacle = false; column = homeNode.Col; row = homeNode.Row; foreach (MazeNode n in MazeGenerator.nodesInSection(root)) { if (n.Col == column && n.Row == row) { presentNode = n; } } possiblePath = MazeGenerator.GetPath2(presentNode, homeNode); prevCheckNode = presentNode; foreach (MazeNode n in possiblePath) { if (n.EnemyPathNode || GameManager.trapNode(n)) { fleeTarget = prevCheckNode; obstacle = true; break; } prevCheckNode = n; } if (!obstacle) { fleeTarget = homeNode; } fleePath = MazeGenerator.GetPath2(presentNode, fleeTarget); foreach (MazeNode n in fleePath) { n.EnemyPathNode = true; } } targetPos = new Vector3(fleeTarget.Col * 6 + 8, fleeTarget.Floor * 30, fleeTarget.Row * 6 + 8); if (Vector3.Distance(transform.position, targetPos) < 2) { State = TakaState.Idle; gameObject.transform.rotation = startingRotation; } agent.SetDestination(targetPos); /* * if (transform.position.x < home.x + 2 && transform.position.x > home.x - 2) * { * if (transform.position.z < home.z + 2 && transform.position.z > home.z - 2) * { * State = TakaState.Idle; * gameObject.transform.rotation = startingRotation; * } * } * * agent.SetDestination(home); */ }
//function to execute in taunt state void taunt() { posTimer = 30; posTimer2 = 25; if (FleeInu(LevelMask, home)) { State = TakaState.Flee; return; } //rayDirection = playerTransform.position - transform.position; //rayDirection.y = 0; playerCloseToEnemy = Vector3.Distance(playerTransform.position, transform.position) < TauntDistance; if (!playerCloseToEnemy) { seen = false; seen = SeeObject(PlayerObject, LevelMask, home); if (seen) { State = TakaState.Chase; return; } foundFootprint = SeeFootprint(allNodes, LevelMask, home); if (foundFootprint != null) { nextFootprint = foundFootprint; State = TakaState.Follow; return; } else if (StartingNode != null) { State = TakaState.Patrol; return; } else { State = TakaState.Idle; return; } } //play taunt sounds if (mr == null) { //mr = gameObject.GetComponentInChildren<MeshRenderer>(); mr = gameObject.GetComponentInChildren <Transform>(); } //make the taka appear to grow taller if (growthTimer > 0) { growthTimer -= Time.deltaTime; mr.transform.localScale += new Vector3(0, 0.002F, 0); mr.transform.position += new Vector3(0, 0.001F, 0); distanceToFloor += 0.01F; } //if player has avoided looking up for a full taunt cycle the taka backs off else if (growthTimer <= 0) { State = TakaState.Flee; return; } //if player looks up while taunted, kill it if (playerLookingUp()) { if (UnityEngine.XR.XRDevice.isPresent) { player = PlayerObject.GetComponentInParent <Actor>(); GameManager.Instance.ActorKilled(actorID, player); } else { GameManager.Instance.ActorKilled(actorID, PlayerObject.GetComponent <Actor>()); } GameManager.Instance.GameOver(); PlayerObject.SetActive(false); if (TestDebug) { print("GameOver"); } } }
//function to execute in cornered state, contains transitions, and code to deal with player void cornered() { posTimer = 30; posTimer2 = 25; if (AttackTimer > 0) { AttackTimer -= Time.deltaTime; } //print(AttackTimer); //rayDirection = playerTransform.position - transform.position; //rayDirection.y = 0; playerKillDistance = Vector3.Distance(playerTransform.position, transform.position) < KillDistance; //attack timer reachers 0 attack if (AttackTimer <= 0) { goal = playerTransform.position; agent.ResetPath(); agent.SetDestination(goal); if (playerKillDistance) { if (UnityEngine.XR.XRDevice.isPresent) { player = PlayerObject.GetComponentInParent <Actor>(); GameManager.Instance.ActorKilled(actorID, player); } else { GameManager.Instance.ActorKilled(actorID, PlayerObject.GetComponent <Actor>()); } GameManager.Instance.GameOver(); } return; } playerCloseToEnemy = Vector3.Distance(playerTransform.position, transform.position) < StayCorneredDistance; if (!playerCloseToEnemy) { beenTooClose = false; seen = false; seen = SeeObject(PlayerObject, LevelMask, home); if (seen) { State = InuState.Chase; return; } foundFootprint = SeeFootprint(allNodes, LevelMask, home); if (foundFootprint != null) { nextFootprint = foundFootprint; State = InuState.Follow; return; } else if (StartingNode != null) { State = InuState.Patrol; return; } else { State = InuState.Idle; return; } } //play growl //if player gets to close inu should charge at player playerTooCloseToEnemy = Vector3.Distance(playerTransform.position, transform.position) < CorneredChaseDistance; if (playerTooCloseToEnemy && beenTooClose == true) { goal = playerTransform.position; agent.ResetPath(); agent.SetDestination(goal); } //if inu gets close enough to player kill the player if (playerKillDistance && beenTooClose == true) { if (UnityEngine.XR.XRDevice.isPresent) { player = PlayerObject.GetComponentInParent <Actor>(); GameManager.Instance.ActorKilled(actorID, player); } else { GameManager.Instance.ActorKilled(actorID, PlayerObject.GetComponent <Actor>()); } GameManager.Instance.GameOver(); } }
void patrol() { if (FleeInu(LevelMask, home)) { State = TakaState.Flee; return; } if (Vector3.Distance(transform.position, home) < 2) { if (stuckBlocker <= 0) { if (IsStuck(newPosition, oldPosition, oldPosition2)) { posTimer = 0; posTimer = 5; if (TestDebug) { print("resetting path"); } agent.ResetPath(); previous2 = previous; previous = currentNode; currentNode = null; State = TakaState.Flee; return; } } } seen = false; seen = SeeObject(PlayerObject, LevelMask, home); if (seen) { awake = true; State = TakaState.Chase; return; } foundFootprint = SeeFootprint(allNodes, LevelMask, home); if (foundFootprint != null) { nextFootprint = foundFootprint; State = TakaState.Follow; return; } if (root != null) { bool setCurrent = false; if (currentNode == null) { closest = null; closest = SetClosest(closest, homeNode, nodes, rb); currentNode = closest; if (previous == null) { previous = currentNode; previous2 = previous; } setCurrent = true; } if (currentNode != null) { currentNodePosition = new Vector3(currentNode.Col * 6 + 8, currentNode.Floor * 30, currentNode.Row * 6 + 8); if (setCurrent == false) { if (Vector3.Distance(transform.position, currentNodePosition) < 2) { lookTimer = 4; agent.SetDestination(transform.position); state = TakaState.LookAround; /*MazeNode closest = null; * closest = UpdateClosest(closest, nodes, currentNode, previous, previous2, rb); * if (closest != null) * { * previous2 = previous; * previous = currentNode; * currentNode = closest; * }*/ //lookTimer = 6; //agent.SetDestination(transform.position); //state = TakaState.LookAround; } if (currentNode != null) { currentNodePosition = new Vector3(currentNode.Col * 6 + 8, currentNode.Floor * 30, currentNode.Row * 6 + 8); } } agent.SetDestination(currentNodePosition); } } }