void LateUpdate()
    {
        if (!m_FollowTarget)
        {
            return;
        }

        if (!m_AutoMove)
        {
            return;
        }

        // Update target position.

        {
            m_TargetPosition = m_OriginalPositon;

            bool enableCameraMovement;
            GameSettings.TryGetBoolMain(Settings.s_CameraMovementSetting, out enableCameraMovement);

            if (enableCameraMovement)
            {
                float offsetX;
                float offsetY;

                ComputeTargetOffsetX(out offsetX);
                ComputeTargetOffsetY(out offsetY);

                m_TargetPosition += new Vector3(offsetX, offsetY, 0f);
            }
        }

        // Step.

        {
            m_FilterX.Step(m_TargetPosition.x, Time.deltaTime);
            m_FilterY.Step(m_TargetPosition.y, Time.deltaTime);
        }

        // Update current position.

        {
            float currentPositionX = m_FilterX.position;
            float currentPositionY = m_FilterY.position;

            m_CurrentPosition = new Vector3(currentPositionX, currentPositionY, position.z);
        }

        // Move camera.

        {
            Vector3 newPosition = new Vector3(m_CurrentPosition.x, m_CurrentPosition.y, m_CurrentPosition.z);
            transform.position = newPosition;
        }
    }
    // tnInputFiller's INTERFACE

    public override void Fill(float i_FrameTime, tnInputData i_Data)
    {
        if (m_PlayerInput == null)
        {
            return;
        }

        float horizontalAxisRaw = m_PlayerInput.GetAxis("MoveHorizontal");
        float verticalAxisRaw   = m_PlayerInput.GetAxis("MoveVertical");

        m_HorizontalFilter.Step(horizontalAxisRaw, i_FrameTime);
        m_VerticalFilter.Step(verticalAxisRaw, i_FrameTime);

        i_Data.SetAxis(InputActions.s_HorizontalAxis, m_HorizontalFilter.position);
        i_Data.SetAxis(InputActions.s_VerticalAxis, m_VerticalFilter.position);

        i_Data.SetButton(InputActions.s_ShotButton, m_PlayerInput.GetButton("Shot"));
        i_Data.SetButton(InputActions.s_PassButton, m_PlayerInput.GetButton("Pass"));
        i_Data.SetButton(InputActions.s_AttractButton, m_PlayerInput.GetButton("Attract"));

        i_Data.SetButton(InputActions.s_TauntButton, m_PlayerInput.GetButton("Taunt"));
    }
    private IEnumerator InternalSetHighlighted(int i_Id, Action i_OnCompleted = null)
    {
        if (m_GameCamera != null && m_MatchController != null)
        {
            GameObject character = m_MatchController.GetCharacterById(i_Id);
            if (character != null)
            {
                // Hide all characters' hud.

                for (int characterIndex = 0; characterIndex < m_MatchController.charactersCount; ++characterIndex)
                {
                    GameObject characterGo = m_MatchController.GetCharacterByIndex(characterIndex);

                    tnCharacterViewController controller = characterGo.GetComponent <tnCharacterViewController>();
                    if (controller != null)
                    {
                        controller.SetPlayerNameVisible(false);
                        controller.SetEnergyBarVisible(false);

                        controller.SetArrowVisible(false);
                        controller.SetChargingForceBarVisible(false);
                    }
                }

                // Animate camera.

                Vector3 originalPosition = m_GameCamera.position;
                float   originalSize     = m_GameCamera.size;

                m_FilterX = new FilteredFloat(m_StepFactorPosition, m_StepFactorPosition);
                m_FilterY = new FilteredFloat(m_StepFactorPosition, m_StepFactorPosition);

                m_FilterSize = new FilteredFloat(m_StepFactorSize, m_StepFactorSize);

                m_FilterX.position = originalPosition.x;
                m_FilterY.position = originalPosition.y;

                m_FilterSize.position = originalSize;

                m_GameCamera.SetAutoMove(false);

                float timer = 0f;

                while (timer < m_Duration)
                {
                    Transform characterTransform = character.transform;

                    Vector3 targetPosition = characterTransform.position;
                    targetPosition += new Vector3(m_Offset.x, m_Offset.y, 0f);

                    float newX = m_FilterX.Step(targetPosition.x, Time.deltaTime);
                    float newY = m_FilterY.Step(targetPosition.y, Time.deltaTime);

                    Vector3 newPosition = new Vector3(newX, newY, originalPosition.z);
                    float   newSize     = m_FilterSize.Step(m_MinSize, Time.deltaTime);

                    m_GameCamera.SetPosition(newPosition);
                    m_GameCamera.SetSize(newSize);

                    timer += Time.deltaTime;

                    yield return(null);
                }

                m_GameCamera.SetPosition(originalPosition);
                m_GameCamera.SetSize(originalSize);

                m_GameCamera.SetAutoMove(true);

                // Restore hud visibily.

                for (int characterIndex = 0; characterIndex < m_MatchController.charactersCount; ++characterIndex)
                {
                    GameObject characterGo = m_MatchController.GetCharacterByIndex(characterIndex);

                    tnCharacterViewController controller = characterGo.GetComponent <tnCharacterViewController>();
                    if (controller != null)
                    {
                        controller.SetPlayerNameVisible(true);
                        controller.SetEnergyBarVisible(true);

                        controller.SetArrowVisible(true);
                        controller.SetChargingForceBarVisible(true);
                    }
                }
            }
        }

        // Notify caller.

        if (i_OnCompleted != null)
        {
            i_OnCompleted();
        }
    }