private void Scan() { bool suspiciousActorSeen = false; // Check each player: foreach (PlayerController actor in AlarmSingleton.SuspiciousActors) { Vector3 actorDirection = AlarmSingleton.GetActorTorso(actor) - transform.position; // Check to see if the actor is in the field of view and range of the camera. if (Vector3.Angle(actorDirection, transform.forward) < fieldOfView / 2f && Vector3.Project(actorDirection, transform.forward).magnitude < maxViewDistance) { // Trigger event if this is the first actor seen // and the alarm is not already in a triggered state. if (audioSource.isPlaying == false) { audioSource.PlayOneShot(cameraAlarm); } suspiciousActorSeen = true; if (!isCurrentlyAlarmed) { isCurrentlyAlarmed = true; OnTriggered?.Invoke(actor); } break; } } isCurrentlyAlarmed = suspiciousActorSeen; }
private void Update() { // Reorient the text to face the main camera. // TODO this behavior should be abstracted into // another script. stateText.transform.parent.LookAt(Camera.main.transform.position); stateText.transform.parent.forward *= -1f; // Do the update behavior specific to the current state. switch (Behavior) { case AIBehaviorState.Stationary: StationaryUpdate(); break; case AIBehaviorState.Patrolling: PatrollingUpdate(); break; case AIBehaviorState.Investigating: InvestigatingUpdate(); break; case AIBehaviorState.Chasing: ChasingUpdate(); break; } // If not chasing, check to see if any // players are inside the field of view. if (Behavior != AIBehaviorState.Chasing) { foreach (PlayerController actor in AlarmSingleton.SuspiciousActors) { // Get the direction vector from the AI to the actor. Vector3 actorDirection = AlarmSingleton.GetActorTorso(actor) - transform.position; audioSource.volume = 4f; if (audioSource.isPlaying == false) { audioSource.PlayOneShot(guardFootsteps[Random.Range(0, guardFootsteps.Length)]); } // Ignore elevation. actorDirection.y = 0f; // Check to see if the actor is within the personal space, // or if they are within the field of view. if (actorDirection.magnitude < personalSpaceRadius || (actorDirection.magnitude < viewDistance && Vector3.Angle(actorDirection, transform.forward) < fieldOfView / 2)) { // Run a linecast to make sure there isn't a // wall between the guard and actor. if (IsSightLineClear(AlarmSingleton.GetActorTorso(actor))) { // If the player is seen switch to chasing. transformCurrentlyChasing = actor.transform; Behavior = AIBehaviorState.Chasing; // Play the whistle sound effect. whistleSource.Play(); break; } } } } }