# Getting Started

**What's Included:**

* Demo Scene
* Sight Sense
* Sound Sense
* Sound Emitters
* Basic Finite State Machine Template
* Enemy Finite State Machine

## How To Use

In order to get started attach either a [`SightSensor` ](#undefined)and/or [`SoundSensor`](#undefined) MonoBehavior to your GameObject. Attaching Either Sensor will automatically attach a [`SensorController`](#sensor-controller) MonoBehavior that cannot be removed while Sensors are attached.

<figure><img src="https://1956285839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F5KzDi9VYw2z224biwf7L%2Fuploads%2F67kjxecACvGQwkjHy9vr%2FSightSensor.png?alt=media&#x26;token=92f2646e-634b-46e3-8405-c4b2f5d18c00" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1956285839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F5KzDi9VYw2z224biwf7L%2Fuploads%2FUUlr1SucOs8JfSPl986s%2FSoundSensor.png?alt=media&#x26;token=6e3d81ef-df03-405c-bb7e-d77e987f4da6" alt=""><figcaption></figcaption></figure>

## Sensor Controller

The `SensorController.cs` has two properties. You can easily enable or disable senses with the toggle or in code.  `SensorController` runs on the LateUpdate gameloop. On `Awake` the SenseController finds any attached behaviors that implement `SensorBase`. It iterates over each sense and reports back the highest rated [detection event](#detection-typespublic-enum-detectionstatus).&#x20;

<figure><img src="https://1956285839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F5KzDi9VYw2z224biwf7L%2Fuploads%2F6ZKl4VG7ycjxZyGByOTX%2FSensorController.png?alt=media&#x26;token=39926307-1140-480c-87d5-a6ff079bcb74" alt=""><figcaption></figcaption></figure>

```csharp
var controller = GetComponent<SensorController>();
controller.EnableSenses = false; // stops running code in the LateUpdate 
controller.EnableSenses = true; // run the sensor code
```

Notifications can be enabled through the UI as well. This will invoke the below action anytime there is a detection update.

```csharp
public static event Action<SensedObject> OnDetectionStatusChanged;
```

## Detection Types

Noting that the highest rated detection event is `TargetDetected`&#x20;

```csharp
public enum DetectionStatus {
        TargetNotDetected = 0,
        TargetDetectedCaution = 1,
        TargetDetected = 2,
}
```

## Sensors

Each Sensor Inherits from `SensorBase`. Adding New Sensors can be added by extending creating a new csharp script and inheriting from `SensorBase`.

### Sight Sensor

The SightSensor has a Warning and Detection radius, angle, and layer masking for both detection and possible obstruction layers.

{% hint style="info" %}
The Warning Radius must be larger than the Detection radius. To Disable the Warning radius altogether set the value to 0.
{% endhint %}

Likewise, the origin of the radius can be shifted by adding a GameObject reference into the **Optional Line Of Sight property**. Radiuses and detection angles can be viewed in Scene mode.

<figure><img src="https://1956285839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F5KzDi9VYw2z224biwf7L%2Fuploads%2FVmgr1pcIaCD20IMqlCyM%2Fsightgui.png?alt=media&#x26;token=a9fbc83b-90a8-42a8-b0ff-ea643b5db53d" alt=""><figcaption></figcaption></figure>

Anything within the viewing Angle that is not obstructed and withing the yellow circle will trigger a TargetDetectedCaution event. Anything within the red circle will trigger a TargetDetected event.

### Sound Sensor

The SoundSensor has a Warning and Detection radius just like the SightSensor with the same use cases.  Additionally There are property settings that dampen sounds if line of site is blocked by obstructions. Sound is detected in 3D space and the Sensor can be configured to listen to events by Tag or Layer. In order for the Sound Sensor to pick up sounds, sounds must be emitted by a [SoundEmitter](#undefined).

## Emitters

New Emitters can be created by any csharp script that implements the `EmitterBase`&#x20;

New Emitter Types should be added to the Emitter enum

```csharp
[Flags]
public enum Emitter {
    Sound = (1 << 0)
}
```

### Sound Emitters

Provided are two versions of SoundEmitters. `SoundEmitter.cs` and `SoundEmitterWithAttachedAudioSource.cs`. Both MonoBehaviors are functionally identical. `SoundEmitterWithAttachedAudioSource.cs` automatically attached an AudioSource to the GameObject and uses that AudioSource. `SoundEmitter.cs` Allows for AudioSources to be passed into it's methods.

Provided in the Demo Folder is a script that emits sounds on trigger without a sound clip

```csharp
namespace Demo.Scripts {
    [RequireComponent(typeof(SoundEmitter))]
    [RequireComponent(typeof(ParticleSystem))]
    public class EmitSoundTrigger : MonoBehaviour {
        private SoundEmitter _emitter;
        private ParticleSystem _particleSystem;

        private void Awake() {
            _emitter = GetComponent<SoundEmitter>();
            _particleSystem = GetComponent<ParticleSystem>();
        }

        private void OnTriggerEnter(Collider other) {
            if (other.gameObject.layer != LayerMask.NameToLayer("Player")) return;
            _emitter.Emit();
            _particleSystem.Emit(1);
            Burst(1);
            // if there was a an audio emits could also play a sound
            // _emitter.Play(audioSource);
            // _emitter.PlayOneShot(audioSource, clip);
            // _emitter.PlayOneShot(audioSource, clip, volume);
        }

        private void Burst(int amount) {
            var param = new ParticleSystem.EmitParams {
                // position = pos + spawnOffset,
                applyShapeToPosition = true,
            };
            _particleSystem.Emit(param, amount);
        }
    }
}

```

As shown in the example above, if you should to play a sound and emit a sound for the sound sensor to register, AudioSources must be played from the SoundEmitter exposed methods.

```csharp
_emitter.Play(audioSource);
_emitter.PlayOneShot(audioSource, clip);
_emitter.PlayOneShot(audioSource, clip, volume);
```

## Basic Finite State Machine

In order to demonstrate how Senses could work in your project I'm also include a very basic implementation of a FSM. Please look at the FSM/Enemy folder for how to create your own StateMachineControllers and individual states.
