/// <summary> /// Handles the case where the current Audio AiTarget contains a current Audio Threat. /// </summary> /// <returns>A new state or NONE if nothing needed to be handled</returns> private AiStateType HandleAudioThreat() { AiStateType state = AiStateType.None; AiThreatManager manager = zombieStateMachine.ThreatManager; AiTarget audioThreat = zombieStateMachine.ThreatManager.CurrentAudioThreat; if (manager.IsTargeting(AiTargetType.Visual_Food)) { state = AiStateType.Alerted; } else if (manager.IsTargeting(AiTargetType.Audio)) { // Get unique ID of the collider of our target int currentID = zombieStateMachine.ThreatManager.CurrentTarget.GetColliderID(); // If this is the same light if (currentID == zombieStateMachine.ThreatManager.CurrentAudioThreat.GetColliderID()) { RepathToThreatIfNecessary(audioThreat); state = AiStateType.Pursuit; } else { state = AiStateType.Alerted; } } manager.TrackTarget(audioThreat); return(state); }
/// <summary> /// Handles the case where the current visual threat is a Visual_light. /// </summary> /// <returns>A new state or NONE if nothing needed to be handled</returns> private AiStateType HandleVisualLightThreats() { AiStateType state = AiStateType.None; AiThreatManager manager = zombieStateMachine.ThreatManager; AiTarget visualThreat = zombieStateMachine.ThreatManager.CurrentVisualThreat; // and we currently have a lower priority target then drop into alerted // mode and try to find source of light if (manager.IsTargeting(AiTargetType.Audio) || manager.IsTargeting(AiTargetType.Visual_Food)) { state = AiStateType.Alerted; } else if (manager.IsTargeting(AiTargetType.Visual_Light)) { // Get unique ID of the collider of our target int currentID = zombieStateMachine.ThreatManager.CurrentTarget.GetColliderID(); // If this is the same light if (currentID == visualThreat.GetColliderID()) { RepathToThreatIfNecessary(visualThreat); state = AiStateType.Pursuit; } else { state = AiStateType.Alerted; } } manager.TrackTarget(visualThreat); return(state); }
/// <summary> /// Actions to take whenever a player threat is detected. /// </summary> /// <param name="playerCollider">The player collider that triggered the collision</param> private void HandlePlayerThreat(Collider playerCollider) { AiThreatManager manager = zombieStateMachine.ThreatManager; float distanceToThreat = Vector3.Distance(zombieStateMachine.Sensor.WorldPosition, playerCollider.transform.position); // if the currently stored threat is not the player or it is the player and it's closer than what was last stored if (!manager.DoesPlayerThreatExist() || (manager.DoesPlayerThreatExist() && IsCloserThanLastThreat(manager.CurrentVisualThreat, distanceToThreat))) { RaycastHit hitInfo; if (IsColliderVisible(playerCollider, out hitInfo, playerLayerMask)) { // it's close and in our FOV so store as the current most dangerous threat this.zombieStateMachine.ThreatManager.TrackVisualThreat( AiTargetType.Visual_Player, playerCollider, distanceToThreat ); } } }
/// <summary> /// Called by the state machine each frame. /// </summary> /// <returns>Either Idle or a new state based upon the threats that were processed</returns> public override AiStateType OnUpdate() { IncrementTimer(); AiStateType state = GetDefaultStateType(); // if we got to this state, but its not hungry, go back to alert state if (!zombieStateMachine.IsHungery()) { zombieStateMachine.WaypointManager.TrackWayPoint(); state = AiStateType.Alerted; } else { AiThreatManager manager = zombieStateMachine.ThreatManager; if (manager.DoesPlayerThreatExist() || manager.DoesLightThreatExist()) { manager.TrackTarget(zombieStateMachine.ThreatManager.CurrentVisualThreat); state = AiStateType.Alerted; } else if (manager.DoesAudioThreatExist()) { manager.TrackTarget(zombieStateMachine.ThreatManager.CurrentAudioThreat); state = AiStateType.Alerted; } else if (manager.IsTargeting(AiTargetType.Visual_Food)) { if (IsZombieCurrentlyEating()) { ReplenishSatisfaction(); } } FaceTargetGradually(this.slerpSpeed); } return(state); }
/// <summary> /// Initializes all of the threats/targets. /// </summary> private void InitializeThreatManager() { this.threatManager = new AiThreatManager(this.targetTrigger, this); }
/// <summary> /// Indicates whether or not the distance to the given threat is smaller then anything we may have /// previously stored /// </summary> /// <param name="threat">The threat to test</param> /// <param name="distanceToThreat">The pre-computed distance to the given threat</param> /// <returns>true if a previous threat existed and zombie is now closer to it.</returns> private bool IsCloserThanLastThreat(AiTarget threat, float distanceToThreat) { AiThreatManager manager = zombieStateMachine.ThreatManager; return(threat.Type == AiTargetType.None || distanceToThreat < threat.Distance); }