Exemplo n.º 1
0
        private List<string> SetDefaults(LipSyncMode mode)
        {
            List<string> phonemes = new List<string>();

            if (mode == LipSyncMode.ReadPamelaFile)
            {
                phonemes.Add ("B/M/P/ ");
                phonemes.Add ("EH0/EH1/EH2/ER0/ER1/ER2/EY0/EY1/EY2/IY0/IY1/IY2");
                phonemes.Add ("CH/G/HH/IH0/IH1/IH2/JH/K/R/S/SH/Y/Z/ZH");
                phonemes.Add ("F/V");
                phonemes.Add ("D/DH/L/N/NG");
                phonemes.Add ("AA0/AA1/AA2/AE0/AE1/AE2/AH0/AH1/AH2/AY0/AY1/AY2");
                phonemes.Add ("AO0/AO1/AO2/AW0/AW1/AW2/OW0/OW1/OW2");
                phonemes.Add ("T/TH");
                phonemes.Add ("OY0/OY1/OY2/UH0/UH1/UH2/UW0/UW1/UW2/W");
            }
            else if (mode == LipSyncMode.FromSpeechText || mode == LipSyncMode.ReadSapiFile || mode == LipSyncMode.ReadPapagayoFile)
            {
                phonemes.Add ("B/M/P/MBP/ ");
                phonemes.Add ("AY/AH/IH/EY/ER");
                phonemes.Add ("G/O/OO/OH/W");
                phonemes.Add ("SH/R/Z/SF/D/L/F/TN/K/N/NG/H/X/FV");
                phonemes.Add ("UH/EH/DH/AE/IY");
            }

            return phonemes;
        }
Exemplo n.º 2
0
        private List <string> SetDefaults(LipSyncMode mode)
        {
            List <string> phonemes = new List <string>();

            if (mode == LipSyncMode.ReadPamelaFile)
            {
                phonemes.Add("B/M/P/ ");
                phonemes.Add("EH0/EH1/EH2/ER0/ER1/ER2/EY0/EY1/EY2/IY0/IY1/IY2");
                phonemes.Add("CH/G/HH/IH0/IH1/IH2/JH/K/R/S/SH/Y/Z/ZH");
                phonemes.Add("F/V");
                phonemes.Add("D/DH/L/N/NG");
                phonemes.Add("AA0/AA1/AA2/AE0/AE1/AE2/AH0/AH1/AH2/AY0/AY1/AY2");
                phonemes.Add("AO0/AO1/AO2/AW0/AW1/AW2/OW0/OW1/OW2");
                phonemes.Add("T/TH");
                phonemes.Add("OY0/OY1/OY2/UH0/UH1/UH2/UW0/UW1/UW2/W");
            }
            else if (mode == LipSyncMode.FromSpeechText || mode == LipSyncMode.ReadSapiFile || mode == LipSyncMode.ReadPapagayoFile)
            {
                phonemes.Add("B/M/P/MBP/ ");
                phonemes.Add("AY/AH/IH/EY/ER");
                phonemes.Add("G/O/OO/OH/W");
                phonemes.Add("SH/R/Z/SF/D/L/F/TN/K/N/NG/H/X/FV");
                phonemes.Add("UH/EH/DH/AE/IY");
            }

            return(phonemes);
        }
Exemplo n.º 3
0
        private List <string> ShowPhonemesGUI(List <string> phonemes, LipSyncMode mode)
        {
            EditorGUILayout.HelpBox("Sort letters or phoneme sounds into groups below, with each group representing a different animation frame.  Separate sounds with a forward slash (/).\nThe first frame will be considered the default.", MessageType.Info);
            EditorGUILayout.Space();

            scrollPos = EditorGUILayout.BeginScrollView(scrollPos);

            for (int i = 0; i < phonemes.Count; i++)
            {
                EditorGUILayout.BeginHorizontal();
                phonemes [i] = EditorGUILayout.TextField("Frame #" + i.ToString() + ":", phonemes [i]);
                if (GUILayout.Button(Resource.CogIcon, GUILayout.Width(20f), GUILayout.Height(15f)))
                {
                    PhonemeSideMenu(i);
                }
                EditorGUILayout.EndHorizontal();
            }

            EditorGUILayout.Space();
            EditorGUILayout.EndScrollView();

            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Create new frame"))
            {
                phonemes.Add(string.Empty);
            }
            if (GUILayout.Button("Revert to defaults"))
            {
                Undo.RecordObject(speechManager, "Revert phonemes");
                phonemes = SetDefaults(mode);
            }
            EditorGUILayout.EndHorizontal();

            return(phonemes);
        }
Exemplo n.º 4
0
        private List <string> ShowPhonemesGUI(List <string> phonemes, LipSyncMode mode)
        {
            EditorGUILayout.HelpBox("Sort letters or phoneme sounds into groups below, with each group representing a different animation frame.  Separate sounds with a forward slash (/).\nThe first frame will be considered the default.", MessageType.Info);
            EditorGUILayout.Space();

            /*int numOptions = phonemes.Count;
             * numOptions = EditorGUILayout.IntField ("Number of frames:", phonemes.Count);
             * if (phonemes.Count < 0)
             * {
             *      phonemes = SetDefaults (mode);
             *      numOptions = phonemes.Count;
             * }
             * if (numOptions < 1)
             * {
             *      numOptions = 1;
             * }
             *
             * if (numOptions < phonemes.Count)
             * {
             *      phonemes.RemoveRange (numOptions, phonemes.Count - numOptions);
             * }
             * else if (numOptions > phonemes.Count)
             * {
             *      if (numOptions > phonemes.Capacity)
             *      {
             *              phonemes.Capacity = numOptions;
             *      }
             *      for (int i=phonemes.Count; i<numOptions; i++)
             *      {
             *              phonemes.Add ("");
             *      }
             * }*/

            for (int i = 0; i < phonemes.Count; i++)
            {
                EditorGUILayout.BeginHorizontal();
                phonemes [i] = EditorGUILayout.TextField("Frame #" + i.ToString() + ":", phonemes [i]);
                if (GUILayout.Button(Resource.CogIcon, GUILayout.Width(20f), GUILayout.Height(15f)))
                {
                    PhonemeSideMenu(i);
                }
                EditorGUILayout.EndHorizontal();
            }

            EditorGUILayout.Space();
            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Create new frame"))
            {
                phonemes.Add("");
            }
            if (GUILayout.Button("Revert to defaults"))
            {
                Undo.RecordObject(speechManager, "Revert phonemes");
                phonemes = SetDefaults(mode);
            }
            EditorGUILayout.EndHorizontal();

            return(phonemes);
        }
Exemplo n.º 5
0
        private List <string> ShowPhonemesGUI(List <string> phonemes, LipSyncMode mode)
        {
            EditorGUILayout.HelpBox("Sort letters or phoneme sounds into groups below, with each group representing a different animation frame.  Separate sounds with a forward slash (/).\nThe first frame will be considered the default.", MessageType.Info);

            int numOptions = phonemes.Count;

            numOptions = EditorGUILayout.IntField("Number of frames:", phonemes.Count);
            if (phonemes.Count < 0)
            {
                phonemes   = SetDefaults(mode);
                numOptions = phonemes.Count;
            }
            if (numOptions < 1)
            {
                numOptions = 1;
            }

            if (numOptions < phonemes.Count)
            {
                phonemes.RemoveRange(numOptions, phonemes.Count - numOptions);
            }
            else if (numOptions > phonemes.Count)
            {
                if (numOptions > phonemes.Capacity)
                {
                    phonemes.Capacity = numOptions;
                }
                for (int i = phonemes.Count; i < numOptions; i++)
                {
                    phonemes.Add("");
                }
            }

            for (int i = 0; i < phonemes.Count; i++)
            {
                phonemes [i] = EditorGUILayout.TextField("Frame #" + i.ToString() + ":", phonemes [i]);
            }

            if (GUILayout.Button("Revert to defaults"))
            {
                phonemes = SetDefaults(mode);
            }

            return(phonemes);
        }
Exemplo n.º 6
0
        private List<string> ShowPhonemesGUI(List<string> phonemes, LipSyncMode mode)
        {
            EditorGUILayout.HelpBox ("Sort letters or phoneme sounds into groups below, with each group representing a different animation frame.  Separate sounds with a forward slash (/).\nThe first frame will be considered the default.", MessageType.Info);

            int numOptions = phonemes.Count;
            numOptions = EditorGUILayout.IntField ("Number of frames:", phonemes.Count);
            if (phonemes.Count < 0)
            {
                phonemes = SetDefaults (mode);
                numOptions = phonemes.Count;
            }
            if (numOptions < 1)
            {
                numOptions = 1;
            }

            if (numOptions < phonemes.Count)
            {
                phonemes.RemoveRange (numOptions, phonemes.Count - numOptions);
            }
            else if (numOptions > phonemes.Count)
            {
                if(numOptions > phonemes.Capacity)
                {
                    phonemes.Capacity = numOptions;
                }
                for (int i=phonemes.Count; i<numOptions; i++)
                {
                    phonemes.Add ("");
                }
            }

            for (int i=0; i<phonemes.Count; i++)
            {
                phonemes [i] = EditorGUILayout.TextField ("Frame #" + i.ToString () + ":", phonemes [i]);
            }

            if (GUILayout.Button ("Revert to defaults"))
            {
                phonemes = SetDefaults (mode);
            }

            return phonemes;
        }
Exemplo n.º 7
0
        /**
         * <summary>Generates the animation data for lipsyncing a given Speech line.</summary>
         * <param name = "_lipSyncMode">The chosen method of lipsyncing (Off, FromSpeechText, ReadPamelaFile, ReadSapiFile, ReadPapagayoFile, FaceFX, Salsa2D)</param>
         * <param name = "lineNumber">The speech line's ID number</param>
         * <param name = "speakerName">The filename of the speaking character</param>
         * <param name = "language">The name of the current language</param>
         * <param name = "_message">The speech text</param<
         * <returns>A List of LipSyncShape structs that contain the lipsync animation data</returns>
         */
        public List <LipSyncShape> GenerateLipSyncShapes(LipSyncMode _lipSyncMode, int lineNumber, string speakerName, string language = "", string _message = "")
        {
            List <LipSyncShape> lipSyncShapes = new List <LipSyncShape>();

            lipSyncShapes.Add(new LipSyncShape(0, 0f, KickStarter.speechManager.lipSyncSpeed));
            TextAsset textFile = null;

            if (_lipSyncMode == LipSyncMode.Salsa2D)
            {
                return(lipSyncShapes);
            }

            if (lineNumber > -1 && speakerName != "" && KickStarter.speechManager.searchAudioFiles && KickStarter.speechManager.UseFileBasedLipSyncing())
            {
                if (KickStarter.speechManager.autoNameSpeechFiles)
                {
                    string filename = "Lipsync/";
                    if (language != "" && KickStarter.speechManager.translateAudio)
                    {
                        // Not in original language
                        filename += language + "/";
                    }
                    if (KickStarter.speechManager.placeAudioInSubfolders)
                    {
                        filename += speakerName + "/";
                    }
                    filename += speakerName + lineNumber;

                    textFile = Resources.Load(filename) as TextAsset;

                    if (textFile == null && KickStarter.speechManager.fallbackAudio && Options.GetLanguage() > 0)
                    {
                        filename = "Lipsync/";
                        if (KickStarter.speechManager.placeAudioInSubfolders)
                        {
                            filename += "/" + speakerName + "/";
                        }
                        filename += speakerName + lineNumber;
                        textFile  = Resources.Load(filename) as TextAsset;
                    }

                    if (textFile == null)
                    {
                        ACDebug.LogWarning("Lipsync file '/Resources/" + filename + ".txt' not found.");
                    }
                }
                else
                {
                    UnityEngine.Object _object = KickStarter.runtimeLanguages.GetLineCustomLipsyncFile(lineNumber, Options.GetLanguage());

                    if (_object == null && KickStarter.speechManager.fallbackAudio && Options.GetLanguage() > 0)
                    {
                        _object = KickStarter.runtimeLanguages.GetLineCustomLipsyncFile(lineNumber, 0);
                    }

                    if (_object is TextAsset)
                    {
                        textFile = (TextAsset)KickStarter.runtimeLanguages.GetLineCustomLipsyncFile(lineNumber, Options.GetLanguage());
                    }
                }
            }

            if (_lipSyncMode == LipSyncMode.ReadPamelaFile && textFile != null)
            {
                var splitFile = new string[] { "\r\n", "\r", "\n" };
                var pamLines  = textFile.text.Split(splitFile, System.StringSplitOptions.None);

                bool  foundSpeech = false;
                float fps         = 24f;
                foreach (string pamLine in pamLines)
                {
                    if (!foundSpeech)
                    {
                        if (pamLine.Contains("framespersecond:"))
                        {
                            string[] pamLineArray = pamLine.Split(':');
                            float.TryParse(pamLineArray[1], out fps);
                        }
                        else if (pamLine.Contains("[Speech]"))
                        {
                            foundSpeech = true;
                        }
                    }
                    else if (pamLine.Contains(":"))
                    {
                        string[] pamLineArray = pamLine.Split(':');

                        float timeIndex = 0f;
                        float.TryParse(pamLineArray[0], out timeIndex);
                        string searchText = pamLineArray[1].ToLower().Substring(0, pamLineArray[1].Length - 1);

                        bool found = false;
                        foreach (string phoneme in KickStarter.speechManager.phonemes)
                        {
                            string[] shapesArray = phoneme.ToLower().Split("/"[0]);
                            if (!found)
                            {
                                foreach (string shape in shapesArray)
                                {
                                    //if (shape == searchText)
                                    if (searchText.Contains(shape) && searchText.Length == shape.Length)
                                    {
                                        int frame = KickStarter.speechManager.phonemes.IndexOf(phoneme);
                                        lipSyncShapes.Add(new LipSyncShape(frame, timeIndex, KickStarter.speechManager.lipSyncSpeed, fps));
                                        found = true;
                                    }
                                }
                            }
                        }
                        if (!found)
                        {
                            lipSyncShapes.Add(new LipSyncShape(0, timeIndex, KickStarter.speechManager.lipSyncSpeed, fps));
                        }
                    }
                }
            }
            else if (_lipSyncMode == LipSyncMode.ReadSapiFile && textFile != null)
            {
                var splitFile = new string[] { "\r\n", "\r", "\n" };
                var sapiLines = textFile.text.Split(splitFile, System.StringSplitOptions.None);

                foreach (string sapiLine in sapiLines)
                {
                    if (sapiLine.StartsWith("phn "))
                    {
                        string[] sapiLineArray = sapiLine.Split(' ');

                        float timeIndex = 0f;
                        float.TryParse(sapiLineArray[1], out timeIndex);
                        string searchText = sapiLineArray[4].ToLower().Substring(0, sapiLineArray[4].Length - 1);
                        bool   found      = false;
                        foreach (string phoneme in KickStarter.speechManager.phonemes)
                        {
                            string[] shapesArray = phoneme.ToLower().Split("/"[0]);
                            if (!found)
                            {
                                foreach (string shape in shapesArray)
                                {
                                    if (shape == searchText)
                                    {
                                        int frame = KickStarter.speechManager.phonemes.IndexOf(phoneme);
                                        lipSyncShapes.Add(new LipSyncShape(frame, timeIndex, KickStarter.speechManager.lipSyncSpeed, 60f));
                                        found = true;
                                    }
                                }
                            }
                        }
                        if (!found)
                        {
                            lipSyncShapes.Add(new LipSyncShape(0, timeIndex, KickStarter.speechManager.lipSyncSpeed, 60f));
                        }
                    }
                }
            }
            else if (_lipSyncMode == LipSyncMode.ReadPapagayoFile && textFile != null)
            {
                var splitFile     = new string[] { "\r\n", "\r", "\n" };
                var papagoyoLines = textFile.text.Split(splitFile, System.StringSplitOptions.None);

                foreach (string papagoyoLine in papagoyoLines)
                {
                    if (papagoyoLine != "" && !papagoyoLine.Contains("MohoSwitch"))
                    {
                        string[] papagoyoLineArray = papagoyoLine.Split(' ');
                        if (papagoyoLineArray.Length == 2)
                        {
                            float timeIndex = 0f;
                            if (float.TryParse(papagoyoLineArray[0], out timeIndex))
                            {
                                string searchText = papagoyoLineArray[1].ToLower().Substring(0, papagoyoLineArray[1].Length);

                                bool found = false;
                                if (!searchText.Contains("rest") && !searchText.Contains("etc"))
                                {
                                    foreach (string phoneme in KickStarter.speechManager.phonemes)
                                    {
                                        string[] shapesArray = phoneme.ToLower().Split("/"[0]);
                                        if (!found)
                                        {
                                            foreach (string shape in shapesArray)
                                            {
                                                if (shape == searchText)
                                                {
                                                    int frame = KickStarter.speechManager.phonemes.IndexOf(phoneme);
                                                    lipSyncShapes.Add(new LipSyncShape(frame, timeIndex, KickStarter.speechManager.lipSyncSpeed, 24f));
                                                    found = true;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    if (!found)
                                    {
                                        lipSyncShapes.Add(new LipSyncShape(0, timeIndex, KickStarter.speechManager.lipSyncSpeed, 24f));                                           // was 240
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else if (_lipSyncMode == LipSyncMode.FromSpeechText)
            {
                for (int i = 0; i < _message.Length; i++)
                {
                    int maxSearch = Mathf.Min(5, _message.Length - i);
                    for (int n = maxSearch; n > 0; n--)
                    {
                        string searchText = _message.Substring(i, n);
                        searchText = searchText.ToLower();

                        foreach (string phoneme in KickStarter.speechManager.phonemes)
                        {
                            string[] shapesArray = phoneme.ToLower().Split("/"[0]);
                            foreach (string shape in shapesArray)
                            {
                                if (shape == searchText)
                                {
                                    int frame = KickStarter.speechManager.phonemes.IndexOf(phoneme);
                                    lipSyncShapes.Add(new LipSyncShape(frame, (float)i, KickStarter.speechManager.lipSyncSpeed));
                                    i += n;
                                    n  = Mathf.Min(5, _message.Length - i);
                                    break;
                                }
                            }
                        }
                    }
                    lipSyncShapes.Add(new LipSyncShape(0, (float)i, KickStarter.speechManager.lipSyncSpeed));
                }
            }

            if (lipSyncShapes.Count > 1)
            {
                lipSyncShapes.Sort(delegate(LipSyncShape a, LipSyncShape b) { return(a.timeIndex.CompareTo(b.timeIndex)); });
            }

            return(lipSyncShapes);
        }
Exemplo n.º 8
0
        /**
         * <summary>Generates the animation data for lipsyncing a given Speech line.</summary>
         * <param name = "_lipSyncMode">The chosen method of lipsyncing (Off, FromSpeechText, ReadPamelaFile, ReadSapiFile, ReadPapagayoFile, FaceFX, Salsa2D)</param>
         * <param name = "lineNumber">The speech line's ID number</param>
         * <param name = "speakerName">The filename of the speaking character</param>
         * <param name = "language">The name of the current language</param>
         * <param name = "_message">The speech text</param<
         * <returns>A List of LipSyncShape structs that contain the lipsync animation data</returns>
         */
        public List<LipSyncShape> GenerateLipSyncShapes(LipSyncMode _lipSyncMode, int lineNumber, string speakerName, string language = "", string _message = "")
        {
            List<LipSyncShape> lipSyncShapes = new List<LipSyncShape>();
            lipSyncShapes.Add (new LipSyncShape (0, 0f, KickStarter.speechManager.lipSyncSpeed));
            TextAsset textFile = null;

            if (_lipSyncMode == LipSyncMode.Salsa2D)
            {
                return lipSyncShapes;
            }

            if (lineNumber > -1 && speakerName != "" && KickStarter.speechManager.searchAudioFiles)
            {
                string filename = "Lipsync/";
                if (KickStarter.speechManager.placeAudioInSubfolders)
                {
                    filename += "/" + speakerName + "/";
                }
                if (language != "" && KickStarter.speechManager.translateAudio)
                {
                    // Not in original language
                    filename += language + "/";
                }
                filename += speakerName + lineNumber;
                textFile = Resources.Load (filename) as TextAsset;
            }

            if (_lipSyncMode == LipSyncMode.ReadPamelaFile && textFile != null)
            {
                string[] pamLines = textFile.text.Split('\n');
                bool foundSpeech = false;
                float fps = 24f;
                foreach (string pamLine in pamLines)
                {
                    if (!foundSpeech)
                    {
                        if (pamLine.Contains ("framespersecond:"))
                        {
                            string[] pamLineArray = pamLine.Split(':');
                            float.TryParse (pamLineArray[1], out fps);
                        }
                        else if (pamLine.Contains ("[Speech]"))
                        {
                            foundSpeech = true;
                        }
                    }
                    else if (pamLine.Contains (":"))
                    {
                        string[] pamLineArray = pamLine.Split(':');

                        float timeIndex = 0f;
                        float.TryParse (pamLineArray[0], out timeIndex);
                        string searchText = pamLineArray[1].ToLower ().Substring (0, pamLineArray[1].Length-1);

                        bool found = false;
                        foreach (string phoneme in KickStarter.speechManager.phonemes)
                        {
                            string[] shapesArray = phoneme.ToLower ().Split ("/"[0]);
                            if (!found)
                            {
                                foreach (string shape in shapesArray)
                                {
                                    if (shape == searchText)
                                    {
                                        int frame = KickStarter.speechManager.phonemes.IndexOf (phoneme);
                                        lipSyncShapes.Add (new LipSyncShape (frame, timeIndex, KickStarter.speechManager.lipSyncSpeed, fps));
                                        found = true;
                                    }
                                }
                            }
                        }
                        if (!found)
                        {
                            lipSyncShapes.Add (new LipSyncShape (0, timeIndex, KickStarter.speechManager.lipSyncSpeed, fps));
                        }
                    }
                }
            }
            else if (_lipSyncMode == LipSyncMode.ReadSapiFile && textFile != null)
            {
                string[] sapiLines = textFile.text.Split('\n');
                foreach (string sapiLine in sapiLines)
                {
                    if (sapiLine.StartsWith ("phn "))
                    {
                        string[] sapiLineArray = sapiLine.Split(' ');

                        float timeIndex = 0f;
                        float.TryParse (sapiLineArray[1], out timeIndex);
                        string searchText = sapiLineArray[4].ToLower ().Substring (0, sapiLineArray[4].Length-1);
                        bool found = false;
                        foreach (string phoneme in KickStarter.speechManager.phonemes)
                        {
                            string[] shapesArray = phoneme.ToLower ().Split ("/"[0]);
                            if (!found)
                            {
                                foreach (string shape in shapesArray)
                                {
                                    if (shape == searchText)
                                    {
                                        int frame = KickStarter.speechManager.phonemes.IndexOf (phoneme);
                                        lipSyncShapes.Add (new LipSyncShape (frame, timeIndex, KickStarter.speechManager.lipSyncSpeed, 60f));
                                        found = true;
                                    }
                                }
                            }
                        }
                        if (!found)
                        {
                            lipSyncShapes.Add (new LipSyncShape (0, timeIndex, KickStarter.speechManager.lipSyncSpeed, 60f));
                        }
                    }
                }
            }
            else if (_lipSyncMode == LipSyncMode.ReadPapagayoFile && textFile != null)
            {
                string[] papagoyoLines = textFile.text.Split('\n');
                foreach (string papagoyoLine in papagoyoLines)
                {
                    if (papagoyoLine != "" && !papagoyoLine.Contains ("MohoSwitch"))
                    {
                        string[] papagoyoLineArray = papagoyoLine.Split(' ');

                        float timeIndex = 0f;
                        float.TryParse (papagoyoLineArray[0], out timeIndex);
                        string searchText = papagoyoLineArray[1].ToLower ().Substring (0, papagoyoLineArray[1].Length);

                        bool found = false;
                        if (!searchText.Contains ("rest") && !searchText.Contains ("etc"))
                        {
                            foreach (string phoneme in KickStarter.speechManager.phonemes)
                            {
                                string[] shapesArray = phoneme.ToLower ().Split ("/"[0]);
                                if (!found)
                                {
                                    foreach (string shape in shapesArray)
                                    {
                                        if (shape == searchText)
                                        {
                                            int frame = KickStarter.speechManager.phonemes.IndexOf (phoneme);
                                            lipSyncShapes.Add (new LipSyncShape (frame, timeIndex, KickStarter.speechManager.lipSyncSpeed, 24f));

                                            found = true;
                                        }
                                    }
                                }
                            }
                        }
                        if (!found)
                        {
                            lipSyncShapes.Add (new LipSyncShape (0, timeIndex, KickStarter.speechManager.lipSyncSpeed, 240f));
                        }
                    }
                }
            }
            else if (_lipSyncMode == LipSyncMode.FromSpeechText)
            {
                for (int i=0; i<_message.Length; i++)
                {
                    int maxSearch = Mathf.Min (5, _message.Length - i);
                    for (int n=maxSearch; n>0; n--)
                    {
                        string searchText = _message.Substring (i, n);
                        searchText = searchText.ToLower ();

                        foreach (string phoneme in KickStarter.speechManager.phonemes)
                        {
                            string[] shapesArray = phoneme.ToLower ().Split ("/"[0]);
                            foreach (string shape in shapesArray)
                            {
                                if (shape == searchText)
                                {
                                    int frame = KickStarter.speechManager.phonemes.IndexOf (phoneme);
                                    lipSyncShapes.Add (new LipSyncShape (frame, (float) i, KickStarter.speechManager.lipSyncSpeed));
                                    i += n;
                                    n = Mathf.Min (5, _message.Length - i);
                                    break;
                                }
                            }
                        }

                    }
                    lipSyncShapes.Add (new LipSyncShape (0, (float) i, KickStarter.speechManager.lipSyncSpeed));
                }
            }

            if (lipSyncShapes.Count > 1)
            {
                lipSyncShapes.Sort (delegate (LipSyncShape a, LipSyncShape b) {return a.timeIndex.CompareTo (b.timeIndex);});
            }

            return lipSyncShapes;
        }
Exemplo n.º 9
0
        /**
         * <summary>Generates the animation data for lipsyncing a given Speech line.</summary>
         * <param name = "_lipSyncMode">The chosen method of lipsyncing (Off, FromSpeechText, ReadPamelaFile, ReadSapiFile, ReadPapagayoFile, FaceFX, Salsa2D)</param>
         * <param name = "lineNumber">The speech line's ID number</param>
         * <param name = "_speaker">The speaking character</param>
         * <param name = "language">The name of the current language</param>
         * <param name = "_message">The speech text</param<
         * <returns>A List of LipSyncShape structs that contain the lipsync animation data</returns>
         */
        public virtual List <LipSyncShape> GenerateLipSyncShapes(LipSyncMode _lipSyncMode, int lineID, Char _speaker, string language = "", string _message = "")
        {
            List <LipSyncShape> lipSyncShapes = new List <LipSyncShape>();

            lipSyncShapes.Add(new LipSyncShape(0, 0f, KickStarter.speechManager.lipSyncSpeed));
            TextAsset textFile = null;

            if (_lipSyncMode == LipSyncMode.Salsa2D)
            {
                return(lipSyncShapes);
            }

            if (lineID > -1 && _speaker != null && KickStarter.speechManager.searchAudioFiles && KickStarter.speechManager.UseFileBasedLipSyncing())
            {
                textFile = (TextAsset)KickStarter.runtimeLanguages.GetSpeechLipsyncFile <TextAsset> (lineID, _speaker);
            }

            if (_lipSyncMode == LipSyncMode.ReadPamelaFile && textFile != null)
            {
                var splitFile = new string[] { "\r\n", "\r", "\n" };
                var pamLines  = textFile.text.Split(splitFile, System.StringSplitOptions.None);

                bool  foundSpeech = false;
                float fps         = 24f;
                foreach (string pamLine in pamLines)
                {
                    if (!foundSpeech)
                    {
                        if (pamLine.Contains("framespersecond:"))
                        {
                            string[] pamLineArray = pamLine.Split(':');
                            float.TryParse(pamLineArray[1], out fps);
                        }
                        else if (pamLine.Contains("[Speech]"))
                        {
                            foundSpeech = true;
                        }
                    }
                    else if (pamLine.Contains(":"))
                    {
                        string[] pamLineArray = pamLine.Split(':');

                        float timeIndex = 0f;
                        float.TryParse(pamLineArray[0], out timeIndex);
                        string searchText = pamLineArray[1].ToLower().Substring(0, pamLineArray[1].Length - 1);

                        bool found = false;
                        foreach (string phoneme in KickStarter.speechManager.phonemes)
                        {
                            string[] shapesArray = phoneme.ToLower().Split("/"[0]);
                            if (!found)
                            {
                                foreach (string shape in shapesArray)
                                {
                                    //if (shape == searchText)
                                    if (searchText.Contains(shape) && searchText.Length == shape.Length)
                                    {
                                        int frame = KickStarter.speechManager.phonemes.IndexOf(phoneme);
                                        lipSyncShapes.Add(new LipSyncShape(frame, timeIndex, KickStarter.speechManager.lipSyncSpeed, fps));
                                        found = true;
                                    }
                                }
                            }
                        }
                        if (!found)
                        {
                            lipSyncShapes.Add(new LipSyncShape(0, timeIndex, KickStarter.speechManager.lipSyncSpeed, fps));
                        }
                    }
                }
            }
            else if (_lipSyncMode == LipSyncMode.ReadSapiFile && textFile != null)
            {
                var splitFile = new string[] { "\r\n", "\r", "\n" };
                var sapiLines = textFile.text.Split(splitFile, System.StringSplitOptions.None);

                foreach (string sapiLine in sapiLines)
                {
                    if (sapiLine.StartsWith("phn "))
                    {
                        string[] sapiLineArray = sapiLine.Split(' ');
                        float    timeIndex     = 0f;
                        float.TryParse(sapiLineArray[1], out timeIndex);
                        string searchText = sapiLineArray[4].EndsWith(" ") ? sapiLineArray[4].ToLower().Substring(0, sapiLineArray[4].Length - 1) : sapiLineArray[4].ToLower();
                        bool   found      = false;
                        foreach (string _phoneme in KickStarter.speechManager.phonemes)
                        {
                            string phoneme = _phoneme.ToLower();
                            if (phoneme.Contains(searchText))
                            {
                                string[] shapesArray = phoneme.Split("/"[0]);
                                if (!found)
                                {
                                    foreach (string shape in shapesArray)
                                    {
                                        if (shape == searchText)
                                        {
                                            int frame = KickStarter.speechManager.phonemes.IndexOf(_phoneme);
                                            lipSyncShapes.Add(new LipSyncShape(frame, timeIndex, KickStarter.speechManager.lipSyncSpeed, 60f));
                                            found = true;
                                        }
                                    }
                                }
                            }
                        }
                        if (!found)
                        {
                            lipSyncShapes.Add(new LipSyncShape(0, timeIndex, KickStarter.speechManager.lipSyncSpeed, 60f));
                        }
                    }
                }
            }
            else if (_lipSyncMode == LipSyncMode.ReadPapagayoFile && textFile != null)
            {
                var splitFile     = new string[] { "\r\n", "\r", "\n" };
                var papagoyoLines = textFile.text.Split(splitFile, System.StringSplitOptions.None);

                foreach (string papagoyoLine in papagoyoLines)
                {
                    if (!string.IsNullOrEmpty(papagoyoLine) && !papagoyoLine.Contains("MohoSwitch"))
                    {
                        string[] papagoyoLineArray = papagoyoLine.Split(' ');
                        if (papagoyoLineArray.Length == 2)
                        {
                            float timeIndex = 0f;
                            if (float.TryParse(papagoyoLineArray[0], out timeIndex))
                            {
                                string searchText = papagoyoLineArray[1].ToLower().Substring(0, papagoyoLineArray[1].Length);

                                bool found = false;
                                if (!searchText.Contains("rest"))
                                {
                                    foreach (string phoneme in KickStarter.speechManager.phonemes)
                                    {
                                        string[] shapesArray = phoneme.ToLower().Split("/"[0]);
                                        if (!found)
                                        {
                                            foreach (string shape in shapesArray)
                                            {
                                                if (shape == searchText)
                                                {
                                                    int frame = KickStarter.speechManager.phonemes.IndexOf(phoneme);
                                                    lipSyncShapes.Add(new LipSyncShape(frame, timeIndex, KickStarter.speechManager.lipSyncSpeed, 24f));
                                                    found = true;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    if (!found && !searchText.Contains("etc"))
                                    {
                                        lipSyncShapes.Add(new LipSyncShape(0, timeIndex, KickStarter.speechManager.lipSyncSpeed, 24f));                                           // was 240
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else if (_lipSyncMode == LipSyncMode.FromSpeechText)
            {
                for (int i = 0; i < _message.Length; i++)
                {
                    int maxSearch = Mathf.Min(5, _message.Length - i);
                    for (int n = maxSearch; n > 0; n--)
                    {
                        string searchText = _message.Substring(i, n);
                        searchText = searchText.ToLower();

                        foreach (string phoneme in KickStarter.speechManager.phonemes)
                        {
                            string[] shapesArray = phoneme.ToLower().Split("/"[0]);
                            foreach (string shape in shapesArray)
                            {
                                if (shape == searchText)
                                {
                                    int frame = KickStarter.speechManager.phonemes.IndexOf(phoneme);
                                    lipSyncShapes.Add(new LipSyncShape(frame, (float)i, KickStarter.speechManager.lipSyncSpeed));
                                    i += n;
                                    n  = Mathf.Min(5, _message.Length - i);
                                    break;
                                }
                            }
                        }
                    }
                    lipSyncShapes.Add(new LipSyncShape(0, (float)i, KickStarter.speechManager.lipSyncSpeed));
                }
            }

            if (lipSyncShapes.Count > 1)
            {
                lipSyncShapes.Sort(delegate(LipSyncShape a, LipSyncShape b) { return(a.timeIndex.CompareTo(b.timeIndex)); });
            }

            return(lipSyncShapes);
        }
Exemplo n.º 10
0
        /**
         * Shows the GUI.
         */
        public void ShowGUI()
        {
            if (icon == null)
            {
                icon = (Texture2D) AssetDatabase.LoadAssetAtPath ("Assets/AdventureCreator/Graphics/Textures/inspector-use.png", typeof (Texture2D));
            }

            #if UNITY_WEBPLAYER
            EditorGUILayout.HelpBox ("Exporting game text cannot be performed in WebPlayer mode - please switch platform to do so.", MessageType.Warning);
            GUILayout.Space (10);
            #endif

            EditorGUILayout.LabelField ("Subtitles", EditorStyles.boldLabel);

            separateLines = EditorGUILayout.ToggleLeft ("Treat carriage returns as separate speech lines?", separateLines);
            if (separateLines)
            {
                separateLinePause = EditorGUILayout.Slider ("Split line delay (s):", separateLinePause, 0.1f, 1f);
            }
            scrollSubtitles = EditorGUILayout.ToggleLeft ("Scroll speech text?", scrollSubtitles);
            scrollNarration = EditorGUILayout.ToggleLeft ("Scroll narration text?", scrollNarration);
            if (scrollSubtitles || scrollNarration)
            {
                textScrollSpeed = EditorGUILayout.FloatField ("Text scroll speed:", textScrollSpeed);
            }

            displayForever = EditorGUILayout.ToggleLeft ("Display speech forever until user skips it?", displayForever);
            if (displayForever)
            {
                endScrollBeforeSkip = EditorGUILayout.ToggleLeft ("Skipping speech first displays currently-scrolling text?", endScrollBeforeSkip);
                allowGameplaySpeechSkipping = EditorGUILayout.ToggleLeft ("Speech during gameplay can also be skipped?", allowGameplaySpeechSkipping);
            }
            else
            {
                screenTimeFactor = EditorGUILayout.FloatField ("Display time factor:", screenTimeFactor);
                allowSpeechSkipping = EditorGUILayout.ToggleLeft ("Subtitles can be skipped?", allowSpeechSkipping);
                if (allowSpeechSkipping)
                {
                    allowGameplaySpeechSkipping = EditorGUILayout.ToggleLeft ("Speech during gameplay can also be skipped?", allowGameplaySpeechSkipping);
                    if (scrollSubtitles)
                    {
                        endScrollBeforeSkip = EditorGUILayout.ToggleLeft ("Skipping speech first displays currently-scrolling text?", endScrollBeforeSkip);
                    }
                }
            }

            keepTextInBuffer = EditorGUILayout.ToggleLeft ("Retain subtitle text buffer once line has ended?", keepTextInBuffer);

            if (scrollSubtitles || scrollNarration)
            {
                EditorGUILayout.Space ();
                EditorGUILayout.LabelField ("Subtitle-scrolling audio", EditorStyles.boldLabel);
                textScrollCLip = (AudioClip) EditorGUILayout.ObjectField ("Default text scroll audio:", textScrollCLip, typeof (AudioClip), false);
                playScrollAudioEveryCharacter = EditorGUILayout.Toggle ("Play audio on every letter?", playScrollAudioEveryCharacter);
            }

            EditorGUILayout.Space ();
            EditorGUILayout.LabelField ("Speech audio", EditorStyles.boldLabel);

            forceSubtitles = EditorGUILayout.ToggleLeft ("Force subtitles to display when no speech audio is found?", forceSubtitles);
            searchAudioFiles = EditorGUILayout.ToggleLeft ("Auto-play speech audio files?", searchAudioFiles);
            autoNameSpeechFiles = EditorGUILayout.ToggleLeft ("Auto-name speech audio files?", autoNameSpeechFiles);
            translateAudio = EditorGUILayout.ToggleLeft ("Speech audio can be translated?", translateAudio);
            usePlayerRealName = EditorGUILayout.ToggleLeft ("Use Player prefab name in filenames?", usePlayerRealName);
            placeAudioInSubfolders = EditorGUILayout.ToggleLeft ("Place audio files in speaker subfolders?", placeAudioInSubfolders);
            sfxDucking = EditorGUILayout.Slider ("SFX reduction during:", sfxDucking, 0f, 1f);
            musicDucking = EditorGUILayout.Slider ("Music reduction during:", musicDucking, 0f, 1f);
            relegateBackgroundSpeechAudio = EditorGUILayout.ToggleLeft ("End background speech audio if non-background plays?", relegateBackgroundSpeechAudio);

            EditorGUILayout.Space ();

            EditorGUILayout.Space ();
            EditorGUILayout.LabelField ("Lip synching", EditorStyles.boldLabel);

            lipSyncMode = (LipSyncMode) EditorGUILayout.EnumPopup ("Lip syncing:", lipSyncMode);
            if (lipSyncMode == LipSyncMode.FromSpeechText || lipSyncMode == LipSyncMode.ReadPamelaFile || lipSyncMode == LipSyncMode.ReadSapiFile || lipSyncMode == LipSyncMode.ReadPapagayoFile)
            {
                lipSyncOutput = (LipSyncOutput) EditorGUILayout.EnumPopup ("Perform lipsync on:", lipSyncOutput);
                lipSyncSpeed = EditorGUILayout.FloatField ("Process speed:", lipSyncSpeed);

                if (GUILayout.Button ("Phonemes Editor"))
                {
                    PhonemesWindow window = (PhonemesWindow) EditorWindow.GetWindow (typeof (PhonemesWindow));
                    //window = (PhonemesWindow) AdvGame.SetWindowTitle (window, "Phonemes Editor");
                    window.Repaint ();
                }
            }
            else if (lipSyncMode == LipSyncMode.FaceFX && !FaceFXIntegration.IsDefinePresent ())
            {
                EditorGUILayout.HelpBox ("The 'FaceFXIsPresent' preprocessor define must be declared in the Player Settings.", MessageType.Warning);
            }
            else if (lipSyncMode == LipSyncMode.Salsa2D)
            {
                lipSyncOutput = (LipSyncOutput) EditorGUILayout.EnumPopup ("Perform lipsync on:", lipSyncOutput);

                EditorGUILayout.HelpBox ("Speaking animations must have 4 frames: Rest, Small, Medium and Large.", MessageType.Info);

                #if !SalsaIsPresent
                EditorGUILayout.HelpBox ("The 'SalsaIsPresent' preprocessor define must be declared in the Player Settings.", MessageType.Warning);
                #endif
            }
            else if (lipSyncMode == LipSyncMode.RogoLipSync && !RogoLipSyncIntegration.IsDefinePresent ())
            {
                EditorGUILayout.HelpBox ("The 'RogoLipSyncIsPresent' preprocessor define must be declared in the Player Settings.", MessageType.Warning);
            }

            EditorGUILayout.Space ();
            LanguagesGUI ();

            EditorGUILayout.Space ();

            GUILayout.Label ("Game text", EditorStyles.boldLabel);

            EditorGUILayout.BeginHorizontal ();
            if (GUILayout.Button ("Gather text", EditorStyles.miniButtonLeft))
            {
                PopulateList ();

                if (sceneFiles.Length > 0)
                {
                    Array.Sort (sceneFiles);
                }
            }
            if (GUILayout.Button ("Reset text", EditorStyles.miniButtonMid))
            {
                ClearList ();
            }

            if (lines.Count == 0)
            {
                GUI.enabled = false;
            }

            if (GUILayout.Button ("Create script sheet", EditorStyles.miniButtonRight))
            {
                if (lines.Count > 0)
                {
                    CreateScript ();
                }
            }
            EditorGUILayout.EndHorizontal ();

            EditorGUILayout.BeginHorizontal ();
            if (GUILayout.Button ("Import all translations", EditorStyles.miniButtonLeft))
            {
                ImportGameText ();
            }
            if (GUILayout.Button ("Export all translations", EditorStyles.miniButtonRight))
            {
                ExportGameText ();
            }
            EditorGUILayout.EndHorizontal ();

            GUI.enabled = true;

            if (lines.Count > 0)
            {
                EditorGUILayout.Space ();
                ListLines ();
            }

            if (GUI.changed)
            {
                EditorUtility.SetDirty (this);
            }
        }
Exemplo n.º 11
0
        public List <LipSyncShape> GenerateLipSyncShapes(LipSyncMode _lipSyncMode, int lineNumber, string speakerName, string language, string _message)
        {
            List <LipSyncShape> lipSyncShapes = new List <LipSyncShape>();

            lipSyncShapes.Add(new LipSyncShape(0, 0f, KickStarter.speechManager.lipSyncSpeed));
            TextAsset textFile = null;

            if (_lipSyncMode == LipSyncMode.Salsa2D)
            {
                return(lipSyncShapes);
            }

            if (lineNumber > -1 && speakerName != "" && KickStarter.speechManager.searchAudioFiles)
            {
                string filename = "Lipsync/";
                if (KickStarter.speechManager.placeAudioInSubfolders)
                {
                    filename += "/" + speakerName + "/";
                }
                if (language != "" && KickStarter.speechManager.translateAudio)
                {
                    // Not in original language
                    filename += language + "/";
                }
                filename += speakerName + lineNumber;
                textFile  = Resources.Load(filename) as TextAsset;
            }

            if (_lipSyncMode == LipSyncMode.ReadPamelaFile && textFile != null)
            {
                string[] pamLines    = textFile.text.Split('\n');
                bool     foundSpeech = false;
                float    fps         = 24f;
                foreach (string pamLine in pamLines)
                {
                    if (!foundSpeech)
                    {
                        if (pamLine.Contains("framespersecond:"))
                        {
                            string[] pamLineArray = pamLine.Split(':');
                            float.TryParse(pamLineArray[1], out fps);
                        }
                        else if (pamLine.Contains("[Speech]"))
                        {
                            foundSpeech = true;
                        }
                    }
                    else if (pamLine.Contains(":"))
                    {
                        string[] pamLineArray = pamLine.Split(':');

                        float timeIndex = 0f;
                        float.TryParse(pamLineArray[0], out timeIndex);
                        string searchText = pamLineArray[1].ToLower().Substring(0, pamLineArray[1].Length - 1);

                        bool found = false;
                        foreach (string phoneme in KickStarter.speechManager.phonemes)
                        {
                            string[] shapesArray = phoneme.ToLower().Split("/"[0]);
                            if (!found)
                            {
                                foreach (string shape in shapesArray)
                                {
                                    if (shape == searchText)
                                    {
                                        int frame = KickStarter.speechManager.phonemes.IndexOf(phoneme);
                                        lipSyncShapes.Add(new LipSyncShape(frame, timeIndex, KickStarter.speechManager.lipSyncSpeed, fps));
                                        found = true;
                                    }
                                }
                            }
                        }
                        if (!found)
                        {
                            lipSyncShapes.Add(new LipSyncShape(0, timeIndex, KickStarter.speechManager.lipSyncSpeed, fps));
                        }
                    }
                }
            }
            else if (_lipSyncMode == LipSyncMode.ReadSapiFile && textFile != null)
            {
                string[] sapiLines = textFile.text.Split('\n');
                foreach (string sapiLine in sapiLines)
                {
                    if (sapiLine.StartsWith("phn "))
                    {
                        string[] sapiLineArray = sapiLine.Split(' ');

                        float timeIndex = 0f;
                        float.TryParse(sapiLineArray[1], out timeIndex);
                        string searchText = sapiLineArray[4].ToLower().Substring(0, sapiLineArray[4].Length - 1);
                        bool   found      = false;
                        foreach (string phoneme in KickStarter.speechManager.phonemes)
                        {
                            string[] shapesArray = phoneme.ToLower().Split("/"[0]);
                            if (!found)
                            {
                                foreach (string shape in shapesArray)
                                {
                                    if (shape == searchText)
                                    {
                                        int frame = KickStarter.speechManager.phonemes.IndexOf(phoneme);
                                        lipSyncShapes.Add(new LipSyncShape(frame, timeIndex, KickStarter.speechManager.lipSyncSpeed, 60f));
                                        found = true;
                                    }
                                }
                            }
                        }
                        if (!found)
                        {
                            lipSyncShapes.Add(new LipSyncShape(0, timeIndex, KickStarter.speechManager.lipSyncSpeed, 60f));
                        }
                    }
                }
            }
            else if (_lipSyncMode == LipSyncMode.ReadPapagayoFile && textFile != null)
            {
                string[] papagoyoLines = textFile.text.Split('\n');
                foreach (string papagoyoLine in papagoyoLines)
                {
                    if (papagoyoLine != "" && !papagoyoLine.Contains("MohoSwitch"))
                    {
                        string[] papagoyoLineArray = papagoyoLine.Split(' ');

                        float timeIndex = 0f;
                        float.TryParse(papagoyoLineArray[0], out timeIndex);
                        string searchText = papagoyoLineArray[1].ToLower().Substring(0, papagoyoLineArray[1].Length);

                        bool found = false;
                        if (!searchText.Contains("rest") && !searchText.Contains("etc"))
                        {
                            foreach (string phoneme in KickStarter.speechManager.phonemes)
                            {
                                string[] shapesArray = phoneme.ToLower().Split("/"[0]);
                                if (!found)
                                {
                                    foreach (string shape in shapesArray)
                                    {
                                        if (shape == searchText)
                                        {
                                            int frame = KickStarter.speechManager.phonemes.IndexOf(phoneme);
                                            lipSyncShapes.Add(new LipSyncShape(frame, timeIndex, KickStarter.speechManager.lipSyncSpeed, 24f));

                                            found = true;
                                        }
                                    }
                                }
                            }
                        }
                        if (!found)
                        {
                            lipSyncShapes.Add(new LipSyncShape(0, timeIndex, KickStarter.speechManager.lipSyncSpeed, 240f));
                        }
                    }
                }
            }
            else if (_lipSyncMode == LipSyncMode.FromSpeechText)
            {
                for (int i = 0; i < _message.Length; i++)
                {
                    int maxSearch = Mathf.Min(5, _message.Length - i);
                    for (int n = maxSearch; n > 0; n--)
                    {
                        string searchText = _message.Substring(i, n);
                        searchText = searchText.ToLower();

                        foreach (string phoneme in KickStarter.speechManager.phonemes)
                        {
                            string[] shapesArray = phoneme.ToLower().Split("/"[0]);
                            foreach (string shape in shapesArray)
                            {
                                if (shape == searchText)
                                {
                                    int frame = KickStarter.speechManager.phonemes.IndexOf(phoneme);
                                    lipSyncShapes.Add(new LipSyncShape(frame, (float)i, KickStarter.speechManager.lipSyncSpeed));
                                    i += n;
                                    n  = Mathf.Min(5, _message.Length - i);
                                    break;
                                }
                            }
                        }
                    }
                    lipSyncShapes.Add(new LipSyncShape(0, (float)i, KickStarter.speechManager.lipSyncSpeed));
                }
            }

            if (lipSyncShapes.Count > 1)
            {
                lipSyncShapes.Sort(delegate(LipSyncShape a, LipSyncShape b) { return(a.timeIndex.CompareTo(b.timeIndex)); });
            }

            return(lipSyncShapes);
        }
Exemplo n.º 12
0
		public void ShowGUI ()
		{
			#if UNITY_WEBPLAYER
			EditorGUILayout.HelpBox ("Exporting game text cannot be performed in WebPlayer mode - please switch platform to do so.", MessageType.Warning);
			GUILayout.Space (10);
			#endif

			EditorGUILayout.LabelField ("Subtitles", EditorStyles.boldLabel);

			separateLines = EditorGUILayout.Toggle ("Separate carriage returns?", separateLines);
			if (separateLines)
			{
				separateLinePause = EditorGUILayout.Slider ("Split line delay (s):", separateLinePause, 0.1f, 1f);
			}
			scrollSubtitles = EditorGUILayout.Toggle ("Scroll text?", scrollSubtitles);
			if (scrollSubtitles)
			{
				textScrollSpeed = EditorGUILayout.FloatField ("Text scroll speed:", textScrollSpeed);
				textScrollCLip = (AudioClip) EditorGUILayout.ObjectField ("Text scroll audio clip:", textScrollCLip, typeof (AudioClip), false);
			}

			displayForever = EditorGUILayout.Toggle ("Display indefinitely?", displayForever);
			if (displayForever)
			{
				endScrollBeforeSkip = EditorGUILayout.Toggle ("End scrolling before skip?", endScrollBeforeSkip);
			}
			else
			{
				screenTimeFactor = EditorGUILayout.FloatField ("Display time factor:", screenTimeFactor);
				allowSpeechSkipping = EditorGUILayout.Toggle ("Allow subtitle skipping?", allowSpeechSkipping);
				if (allowSpeechSkipping)
				{
					allowGameplaySpeechSkipping = EditorGUILayout.Toggle ("Skip background speech?", allowGameplaySpeechSkipping);
					if (scrollSubtitles)
					{
						endScrollBeforeSkip = EditorGUILayout.Toggle ("End scrolling before skip?", endScrollBeforeSkip);
					}
				}
			}

			keepTextInBuffer = EditorGUILayout.Toggle ("Retain text after playing?", keepTextInBuffer);

			EditorGUILayout.Space ();
			EditorGUILayout.LabelField ("Audio", EditorStyles.boldLabel);

			forceSubtitles = EditorGUILayout.Toggle ("Force subtitles if no audio?", forceSubtitles);
			searchAudioFiles = EditorGUILayout.Toggle ("Auto-play audio files?", searchAudioFiles);
			translateAudio = EditorGUILayout.Toggle ("Audio translations?", translateAudio);

			EditorGUILayout.Space ();

			EditorGUILayout.Space ();
			EditorGUILayout.LabelField ("Lip synching", EditorStyles.boldLabel);

			lipSyncMode = (LipSyncMode) EditorGUILayout.EnumPopup ("Lip syncing:", lipSyncMode);
			if (lipSyncMode == LipSyncMode.FromSpeechText || lipSyncMode == LipSyncMode.ReadPamelaFile || lipSyncMode == LipSyncMode.ReadSapiFile)
			{
				lipSyncOutput = (LipSyncOutput) EditorGUILayout.EnumPopup ("Perform lipsync on:", lipSyncOutput);
				lipSyncSpeed = EditorGUILayout.FloatField ("Process speed:", lipSyncSpeed);

				if (GUILayout.Button ("Phonemes Editor"))
				{
					PhonemesWindow window = (PhonemesWindow) EditorWindow.GetWindow (typeof (PhonemesWindow));
					window.title = "Phonemes Editor";
					window.Repaint ();
				}
			}
			else if (lipSyncMode == LipSyncMode.FaceFX && !FaceFXIntegration.IsDefinePresent ())
			{
				EditorGUILayout.HelpBox ("The 'FaceFXIsPresent' preprocessor define must be declared in the Player Settings.", MessageType.Warning);
			}

			EditorGUILayout.Space ();
			LanguagesGUI ();

			EditorGUILayout.Space ();
			
			GUILayout.Label ("Game text", EditorStyles.boldLabel);
			GUILayout.Label ("Speech audio files must be placed in: /Resources/Speech");

			EditorGUILayout.BeginHorizontal ();
			if (GUILayout.Button ("Gather text", EditorStyles.miniButtonLeft))
			{
				PopulateList ();
				
				if (sceneFiles.Length > 0)
				{
					Array.Sort (sceneFiles);
				}
			}
			if (GUILayout.Button ("Reset text", EditorStyles.miniButtonMid))
			{
				ClearList ();
			}
			if (GUILayout.Button ("Create script sheet", EditorStyles.miniButtonRight))
			{
				if (lines.Count > 0)
				{
					CreateScript ();
				}
			}
			EditorGUILayout.EndHorizontal ();

			EditorGUILayout.BeginHorizontal ();
			if (GUILayout.Button ("Import all translations", EditorStyles.miniButtonLeft))
			{
				ImportGameText ();
			}
			if (GUILayout.Button ("Export all translations", EditorStyles.miniButtonRight))
			{
				ExportGameText ();
			}
			EditorGUILayout.EndHorizontal ();

			if (lines.Count > 0)
			{
				ListLines ();
			}
			
			if (GUI.changed)
			{
				EditorUtility.SetDirty (this);
			}
		}