//public void OnAnimatorMove() //{ // // we implement this function to override the default root motion. // // this allows us to modify the positional speed before it's applied. // if (Time.deltaTime > 0) // { // Vector3 v = (m_Animator.deltaPosition * 1f) / Time.deltaTime; // // we preserve the existing y part of the current velocity. // v.y = m_Rigidbody.velocity.y; // m_Rigidbody.velocity = v; // } //} private void OnCollisionEnter(Collision collision) { if (collision.gameObject.tag == "Item" && collision.gameObject.GetComponent <ItemController>().hasBeenThrown == true) { //m_Animator.SetBool("hit", true); //Set values for the item controller //currentScareValue += (collision.gameObject.GetComponent<ItemController>().baseScariness * 2); //Used in Retreat state when we are hit by an item, runs away from this world pos - item is deleted next frame collidedItemPos = collision.transform.position; GameObject smoke = Instantiate(GameObject.Find("PrefabController").GetComponent <PrefabController>().smokeEffect, collision.gameObject.transform.position, collision.gameObject.transform.rotation); Destroy(smoke, 2.0f); if (TRIGGERED_hit == false) { ItemScaryRating = collision.gameObject.GetComponent <ItemController>().ItemScaryRating; TRIGGERED_hit = true; //This needs to be set to update the code in CIV_Retreat } //Calculate new direction away from the hit object so we can "Avoid" it //Vector3 direction = collision.contacts[0].point - transform.position; //direction = -direction.normalized; //CIV_Retreat.dirAwayFromObject = direction; //Pass into CIV_Retreat //Change into Retreat State m_stateMachine.ChangeState(this, new CIV_Retreat()); civIconStateScript.myState = script_civilianIconState.gameState.retreat;// 19-12-2017 Added by Mark } }
private void Update() { //Forward raycast checking for a possible blocked agent inside the avoid radius //Makes this agent a stationary obstacle if they have been blocked for a certain time if (Physics.Raycast(new Vector3(transform.position.x, 1f, transform.position.z), transform.forward, out hit, navAgent.radius + .5f) && navAgent.isOnNavMesh && !initialSpawn) { if (hit.transform.tag == "Civillian" && hit.transform != this.transform) { stuckTimer += Time.deltaTime; if (hit.transform.GetComponent <CivillianController>().isStationary == false && stuckTimer >= 2f) { //Stop this agent and wait until the other one repaths around you stuckTimer = 0; m_Animator.SetBool("idle", true); navAgent.isStopped = true; currentDest = navAgent.destination; navAgent.ResetPath(); navAgent.enabled = false; isStationary = true; //Create nav obstacle if (gameObject.GetComponent <NavMeshObstacle>() == null) { NavMeshObstacle obstacle = gameObject.AddComponent <NavMeshObstacle>(); obstacle.shape = NavMeshObstacleShape.Capsule; obstacle.radius = 0.3f; obstacle.center = new Vector3(0, 1, 0); obstacle.carving = true; } else //Obstacle has already been added first time around so enable from here on out { gameObject.GetComponent <NavMeshObstacle>().enabled = true; } //Storing the hit agent otherAgent = hit.transform; } } if (hit.transform.tag == "GPatrol" && hit.transform != this.transform) { stuckTimer += Time.deltaTime; if (this.transform.GetComponent <CivillianController>().isStationary == false && stuckTimer >= 2f) { //Stop this agent and wait until the other one repaths around you stuckTimer = 0; m_Animator.SetBool("idle", true); navAgent.isStopped = true; currentDest = navAgent.destination; navAgent.ResetPath(); navAgent.enabled = false; isStationary = true; //Create nav obstacle if (gameObject.GetComponent <NavMeshObstacle>() == null) { NavMeshObstacle obstacle = gameObject.AddComponent <NavMeshObstacle>(); obstacle.shape = NavMeshObstacleShape.Capsule; obstacle.radius = 0.3f; obstacle.center = new Vector3(0, 1, 0); obstacle.carving = true; } else //Obstacle has already been added first time around so enable from here on out { gameObject.GetComponent <NavMeshObstacle>().enabled = true; } //Storing the hit agent otherAgent = hit.transform; } } } else { stuckTimer = 0; } //Turns on Wander once initial destination has been hit otherwise resample the location and continue moving there if (initialSpawn && navAgent.enabled) { //distance check? test if we have reached near the firstspawn dest? //What if its no longer reachable? possible error //if we have reached our destination (hopefully on the same path) then enable wander and disable this block if (navAgent.hasPath) { if (Vector3.Distance(transform.position, firstSpawnDest) <= 1.0f) { initialSpawn = false; enableWander = true; } } else //Check incase one of the items update the navmesh and breaks the current agents pathing { //Debug.Log("Else called initialSpawn"); NavMeshHit navHit; NavMesh.SamplePosition(firstSpawnDest, out navHit, wanderRadius, -1); navAgent.SetDestination(navHit.position); //No error checking so possible error if SamplePosition fails } } //If otherAgent was found we wait until its out of the way before we repath if (otherAgent != null) { Vector3 dirToOther = otherAgent.position - transform.position; if (dirToOther.magnitude >= 2f) { //Re-enable the stationary agent - Prevents agent not being placed on navmesh error if (isStationary) { stationaryTimer += Time.deltaTime; if (stationaryTimer >= .5f) { stationaryTimer = 0; gameObject.GetComponent <NavMeshObstacle>().enabled = false; isStationary = false; } } else //Turn the nav agent back on in the next update frame { otherAgent = null; navAgent.enabled = true; navAgent.ResetPath(); //Clear any paths somehow created during the time navagent was turned off navAgent.isStopped = false; //Calculate a new path to the same destination from when the agent was stopped navAgent.SetDestination(currentDest); //Destroy(gameObject); //NavMeshPath path = new NavMeshPath(); //navAgent.CalculatePath(currentDest, path); //navAgent.SetPath(path); m_Animator.SetBool("idle", false); } } } else { if (isStationary) { Debug.Log("stationaryNull"); } } //Reset the path if we have arrived //Maybe check the distance between current corner we are on and last corner in the path to check if we have arrived? if (navAgent.hasPath && navAgent.remainingDistance <= navAgent.stoppingDistance) { //Debug.Log(name + " Reset Called"); navAgent.ResetPath(); } //Timing estimation, Reset path if the time it took to reach path end point is greater than the estimated time give or take 4 seconds for avoidance? //Distance / Speed = Time //if(currentState == State.State_Wander) //{ if (navAgent.hasPath) //Added retreat state check to turn off repathing causing issues atm { if (!estimTimeSet) { estimationTime = Vector3.Distance(transform.position, navAgent.pathEndPosition) / navAgent.speed; estimationTime = estimationTime + 2.0f; //Adding a little leway estimTimeSet = true; } currTimeOnPath += Time.deltaTime; if (currTimeOnPath >= estimationTime) { navAgent.ResetPath(); } } else { currTimeOnPath = 0; estimationTime = 0; estimTimeSet = false; } //} isOnNavMesh = navAgent.isOnNavMesh; //if(navAgent.pathStatus == NavMeshPathStatus.PathInvalid) //{ // Debug.Log(name + " invalid path."); //} //Debug.Log(Vector3.Distance(navAgent.transform.position, currentDest)); //Update the animator //if (navAgent.enabled) //{ // if (navAgent.remainingDistance > navAgent.stoppingDistance) // Move(navAgent.desiredVelocity, false, false); // else // Move(Vector3.zero, false, false); //} //State changing to Retreat because we have spotted an item and is spooked if (sid.GetComponent <playerPossession>().IsPossessed() == true && TRIGGERED_floating == false && sid.GetComponent <playerPossession>().IsHidden() == false && currentState != State.State_Retreat) { if (isInLineOfSight() == true) { //Debug.Log("In sight!"); ItemScaryRating = sid.GetComponent <playerPossession>().PossessedItem.GetComponent <ItemController>().ItemScaryRating; TRIGGERED_floating = true; //This needs to be set to update the code in CIV_Retreat //Debug.Log("TRIGGERED FLOATING"); FMODUnity.RuntimeManager.PlayOneShot(GameManager.Instance.audioCivSpotted, transform.position); m_stateMachine.ChangeState(this, new CIV_Retreat()); } } //State changing to INTRIGUED if an itemPosition has been set, that means the ai has been in range of a recent lure mechanic used by the player if (alertedByItem && currentScareValue != scareThreshHoldMax) { alertedByItem = false; m_stateMachine.ChangeState(this, new CIV_Alert()); } //State changing to Retreat, because the repel mechanic was used in playerPosession if (TRIGGERED_repel && currentScareValue != scareThreshHoldMax && currentState != State.State_Retreat) { ItemScaryRating = target.GetComponent <ItemController>().ItemScaryRating; //Target at this point is the object we are HIDING in - Set in playerPossesion m_stateMachine.ChangeState(this, new CIV_Retreat()); } //Call update from this agents FSM if (m_stateMachine != null) { m_stateMachine.Update(this, Time.deltaTime); } //this.transform.rotation = Quaternion.Lerp(this.transform.rotation, Quaternion.LookRotation(new Vector3(this.velocity_.x, 0.0f, this.velocity_.y), Vector3.up), Time.deltaTime * 10f); //Debug.DrawLine(transform.position, transform.position + transform.forward, Color.green); //transform.Translate(Vector3.forward * Time.deltaTime); }