public override void OnEnter()
        {
            var hasSighting = controller.LastSighting.HasSighting();

            if (hasSighting)
            {
                // Start moving to the last know sighting of the player
                controller.Agent.Resume();
                controller.Agent.Destination = controller.LastSighting.Position;
            }
            else
            {
                // Should not happen
                // Move to the patrol state if it does
                var patrol = new AIStatePatrol(controller);
                stateMachine.MoveTo(patrol);
            }
        }
        protected override void Initialize()
        {
            capsule      = GetComponent <CapsuleCollider>();
            patrol       = GetComponent <PatrolPath>();
            agent        = GetComponent <DungeonNavAgent>();
            lastSighting = GetComponent <LastPlayerSighting>();

            State startState = null;

            if (hasPatrolling)
            {
                startState = new AIStatePatrol(this);
            }
            else
            {
                startState = new AIStateIdle(this);
            }

            stateMachine.MoveTo(startState);
        }
        protected override void HandleFrameUpdate(float elapsedTime)
        {
            base.HandleFrameUpdate(elapsedTime);

            Collider playerCollider = null;

            if (IsWithinPlayerProximity(ref playerCollider, controller.playerProximityRadius))
            {
                // close to the player.  Move to the attack state
            }
            else
            {
                // Move to the player
                controller.Agent.Destination = followTarget.position;
            }

            if (!IsPlayerVisible())
            {
                // Move to the last know position
                if (controller.LastSighting.HasSighting())
                {
                    var moveToLastKnown = new AIStateMoveToLastKnownPosition(controller);
                    stateMachine.MoveTo(moveToLastKnown);
                }
                else
                {
                    // We don't have a last know position. Resume patroling
                    var patrol = new AIStatePatrol(controller);
                    stateMachine.MoveTo(patrol);
                }
                return;
            }
            else
            {
                // Player is visible.  Update the last sighting
                controller.LastSighting.Position = followTarget.position;
            }
        }
        protected override void HandleFrameUpdate(float elapsedTime)
        {
            base.HandleFrameUpdate(elapsedTime);

            // Check if the player is visible
            if (IsPlayerVisible())
            {
                // Start persuit of the player
                var persuit = new AIStatePersuit(controller);
                stateMachine.MoveTo(persuit);
            }

            timeSinceStart += elapsedTime;
            if (timeSinceStart >= controller.searchWaitTime)
            {
                // The player is not found and is lost. Clear the last sighting variable
                controller.LastSighting.ClearSighting();

                // Return back to the patrol state
                var patrol = new AIStatePatrol(controller);
                stateMachine.MoveTo(patrol);
            }
        }