/// /// <summary>
        /// Switch the background music, fading in and out.
        /// </summary>
        /// <param name="soundClip"> clip to play. </param>
        /// <param name="fadeInTime"> time to fade in. </param>
        /// <param name="fadeOutTime"> time to fade out. </param>
        /// <param name="loop"> loop music? </param>
        public void SwitchBackgroundMusic(
            AudioClip soundClip,
            float fadeInTime,
            float fadeOutTime,
            bool loop = true)
        {
            if (mSwitchingBGM)
            {
                return;
            }

            /* Check if the audio clip good to play. */
            if (soundClip == null)
            {
                return;
            }

            /**
             *  Try to get the fade sound component.
             *
             *  Since we have multiple component have
             */
            if (mJCSFadeSound == null)
            {
                mJCSFadeSound = this.GetComponent <JCS_FadeSound>();

                if (mJCSFadeSound == null)
                {
                    mJCSFadeSound = this.gameObject.AddComponent <JCS_FadeSound>();
                }
            }


            // get the background music audio source.
            AudioSource bgmAudioSource = GetBGMAudioSource();

            // check if loop
            bgmAudioSource.loop = loop;

            // set the audio source.
            mJCSFadeSound.SetAudioSource(bgmAudioSource);

            // active the fade sound in effect.
            mJCSFadeSound.FadeOut(
                0,
                /* Fade in the sound base on the setting. */
                fadeInTime);

            this.mRealSoundFadeOutTime = fadeOutTime;

            this.mSwitchingBGM  = true;
            this.mDoneFadingOut = false;

            this.mCurrentBGM = soundClip;
        }
        private void Awake()
        {
            instance = this;

            // try to get component, this is not guarantee.
            this.mJCSFadeSound = this.GetComponent <JCS_FadeSound>();

            mSFXSounds    = new JCS_Vector <AudioSource>();
            mSkillsSounds = new JCS_Vector <AudioSource>();

            mGlobalSoundPlayer = this.GetComponent <JCS_SoundPlayer>();
        }
        /// <summary>
        /// Load scene with self-define fade in time.
        /// </summary>
        /// <param name="sceneName"> scene name to load </param>
        /// <param name="fadeInTime"> time to fade in </param>
        /// <param name="screenColor"> screen color </param>
        /// <param name="keepBGM"> keep background music playing? </param>
        public void LoadScene(string sceneName, float fadeInTime, Color screenColor, bool keepBGM)
        {
#if (UNITY_EDITOR)
            // only do this in Editor Mode,
            // this help level designer to do their job.
            if (!ReadSceneNames.CheckSceneAvailable(sceneName))
            {
                JCS_Debug.LogReminder("Scene [" + sceneName + "] you want to load is not in the Build Setting");
                return;
            }
#endif

            // if is loading already, dont load it agian
            if (mSwitchSceneEffect)
            {
                return;
            }

            // set the next scene name
            this.mNextSceneName = sceneName;

            var gs = JCS_GameSettings.instance;

            if (gs.SAVE_ON_SWITCH_SCENE && gs.SAVE_GAME_DATA_FUNC != null)
            {
                // do the saving.
                gs.SAVE_GAME_DATA_FUNC.Invoke();
            }

            // preload the scene
            mAsyncOperation = SceneManager.LoadSceneAsync(mNextSceneName);
            mAsyncOperation.allowSceneActivation = false;

            switch (mSwitchSceneType)
            {
            case JCS_SwitchSceneType.BLACK_SCREEN:
            {
                // move to the last child in order
                // to render the black screen in front of
                // any UI's GUI
                mBlackScreen.MoveToTheLastChild();

                // set the screen color.
                // NOTE(jenchieh): always start with opacity the same
                // as previous.
                screenColor.a           = mBlackScreen.LocalColor.a;
                mBlackScreen.LocalColor = screenColor;

                // record down the screen color.
                JCS_SceneSettings.instance.SCREEN_COLOR = screenColor;

                // start fading in (black screen)
                mBlackScreen.FadeIn(fadeInTime);
            }
            break;

            case JCS_SwitchSceneType.SLIDE_SCREEN:
            {
                mBlackSlideScreen.MoveToTheLastChild();

                mBlackSlideScreen.StartSlideIn(mAlign, fadeInTime);
            }
            break;
            }

            var ss = JCS_SoundSettings.instance;

            ss.KEEP_BGM_SWITCH_SCENE = keepBGM;

            if (!keepBGM)
            {
                // start fading sound
                if (ss.SMOOTH_SWITCH_SOUND_BETWEEN_SCENE)
                {
                    // get the component.
                    if (mJCSFadeSound == null)
                    {
                        mJCSFadeSound = this.gameObject.AddComponent <JCS_FadeSound>();
                    }

                    mJCSFadeSound.SetAudioSource(JCS_SoundManager.instance.GetBGMAudioSource());

                    // fade out sound to zero
                    mJCSFadeSound.FadeOut(0, fadeInTime);
                }
            }

            // start check to switch scene or not
            mSwitchSceneEffect = true;

            // Pause the game depends on setting...
            JCS_GameManager.instance.GAME_PAUSE = mPauseGameWhileLoadingScene;
        }
        private void Start()
        {
            var sceneS = JCS_SceneSettings.instance;

            // NOTE(jenchieh): get the fade out time base on  the scene setting
            // and scene manager specific.
            float fadeoutTime = sceneS.GetSceneFadeInTimeBaseOnSetting();

            switch (mSwitchSceneType)
            {
            case JCS_SwitchSceneType.BLACK_SCREEN:
            {
                // get the current screen color.
                mBlackScreen.LocalColor = sceneS.SCREEN_COLOR;

                mBlackScreen.FadeOut(fadeoutTime);
            }
            break;

            case JCS_SwitchSceneType.SLIDE_SCREEN:
            {
                mBlackSlideScreen.StartSlideOut(mAlign, fadeoutTime);
            }
            break;
            }

            // Only need to fade BGM when BGM is not switch between scene.
            var soundS = JCS_SoundSettings.instance;
            var soundM = JCS_SoundManager.instance;

            if (!soundS.KEEP_BGM_SWITCH_SCENE)
            {
                if (soundS.SMOOTH_SWITCH_SOUND_BETWEEN_SCENE)
                {
                    // get the component.
                    if (mJCSFadeSound == null)
                    {
                        mJCSFadeSound = this.gameObject.AddComponent <JCS_FadeSound>();
                    }

                    // set the background audio source.
                    mJCSFadeSound.SetAudioSource(
                        soundM.GetBGMAudioSource());

                    // active the fade sound in effect.
                    mJCSFadeSound.FadeIn(
                        soundS.GetBGM_Volume(),
                        /* Fade in the sound base on the setting. */
                        soundS.GetSoundFadeInTimeBaseOnSetting());
                }
            }
            else
            {
                // If the keep bgm is true, we disable it once  everytime a
                // scene is loaded.
                //
                // ATTENTION(jenchieh): This should be place for the last use
                // of the variable 'KEEP_BGM_SWITCH_SCENE'.
                soundS.KEEP_BGM_SWITCH_SCENE = false;
            }

            // the game is loaded start the game agian
            JCS_GameManager.instance.GAME_PAUSE = false;
        }