public static void ConvertPreset()
    {
        Object[] selection = Selection.GetFiltered(typeof(BlendshapePreset), SelectionMode.Assets);

        foreach (Object preset in selection)
        {
            BlendshapePreset oldPreset = (BlendshapePreset)preset;
            LipSyncPreset    newPreset = ScriptableObject.CreateInstance <LipSyncPreset>();

            string path = AssetDatabase.GetAssetPath(oldPreset);
            path = System.IO.Path.GetDirectoryName(path);

            newPreset.CreateFromShapes(oldPreset.phonemeShapes.ToArray(), null);

            AssetDatabase.CreateAsset(newPreset, path + "/" + oldPreset.name + "_converted.Asset");
            AssetDatabase.Refresh();
        }
    }
示例#2
0
 public void OnEnable()
 {
     target = (LipSyncPreset)base.target;
 }
示例#3
0
    void LoadPreset(object data)
    {
        string file = (string)data;

        if (file.EndsWith(".asset", true, null))
        {
            LipSyncPreset preset = AssetDatabase.LoadAssetAtPath <LipSyncPreset>("Assets" + file.Substring((Application.dataPath).Length));

            if (preset != null)
            {
                List <PhonemeShape> newPhonemes = new List <PhonemeShape>();

                // Phonemes
                for (int shape = 0; shape < preset.phonemeShapes.Length; shape++)
                {
                    newPhonemes.Add(new PhonemeShape(preset.phonemeShapes[shape].phoneme));

                    for (int blendable = 0; blendable < preset.phonemeShapes[shape].blendables.Length; blendable++)
                    {
                        int finalBlendable = preset.FindBlendable(preset.phonemeShapes[shape].blendables[blendable], lsTarget.blendSystem);
                        if (finalBlendable >= 0)
                        {
                            newPhonemes[shape].blendShapes.Add(finalBlendable);
                            newPhonemes[shape].weights.Add(preset.phonemeShapes[shape].blendables[blendable].weight);
                        }
                    }

                    for (int bone = 0; bone < preset.phonemeShapes[shape].bones.Length; bone++)
                    {
                        BoneShape newBone = new BoneShape();
                        newBone.bone = preset.FindBone(preset.phonemeShapes[shape].bones[bone], lsTarget.transform);
                        newBone.SetNeutral();
                        newBone.endPosition  = preset.phonemeShapes[shape].bones[bone].localPosition;
                        newBone.endRotation  = preset.phonemeShapes[shape].bones[bone].localRotation;
                        newBone.lockPosition = preset.phonemeShapes[shape].bones[bone].lockPosition;
                        newBone.lockRotation = preset.phonemeShapes[shape].bones[bone].lockRotation;

                        newPhonemes[shape].bones.Add(newBone);
                    }
                }

                lsTarget.phonemes = newPhonemes;

                for (int bShape = 0; bShape < lsTarget.blendSystem.blendableCount; bShape++)
                {
                    lsTarget.blendSystem.SetBlendableValue(bShape, 0);
                }

                if (markerTab == 0)
                {
                    if (LipSyncEditorExtensions.currentToggle >= 0)
                    {
                        int b = 0;
                        foreach (int shape in lsTarget.phonemes[LipSyncEditorExtensions.currentToggle].blendShapes)
                        {
                            lsTarget.blendSystem.SetBlendableValue(shape, lsTarget.phonemes[LipSyncEditorExtensions.currentToggle].weights[b]);
                            b++;
                        }
                    }
                }
            }
        }
    }
示例#4
0
    public override void OnInspectorGUI()
    {
        if (serializedTarget == null)
        {
            OnEnable();
        }

        if (miniLabelDark == null)
        {
            miniLabelDark = new GUIStyle(EditorStyles.miniLabel);
            miniLabelDark.normal.textColor = Color.black;
        }

        serializedTarget.Update();

        EditorGUI.BeginDisabledGroup(saving);
        Rect fullheight = EditorGUILayout.BeginVertical();

        GUILayout.BeginHorizontal();
        GUILayout.FlexibleSpace();
        GUILayout.Box(logo, GUIStyle.none);
        GUILayout.FlexibleSpace();
        GUILayout.EndHorizontal();

        if (blendSystems == null)
        {
            FindBlendSystems();
        }
        if (blendSystems.Count == 0)
        {
            EditorGUILayout.Popup("Blend System", 0, new string[] { "No BlendSystems Found" });
        }
        else
        {
            if (lsTarget.blendSystem == null)
            {
                EditorGUI.BeginChangeCheck();
                blendSystemNumber = EditorGUILayout.Popup("Blend System", blendSystemNumber, blendSystemNames.ToArray(), GUIStyle.none);
                if (EditorGUI.EndChangeCheck())
                {
                    ChangeBlendSystem();
                }
                GUI.Box(new Rect(EditorGUIUtility.labelWidth + GUILayoutUtility.GetLastRect().x, GUILayoutUtility.GetLastRect().y, GUILayoutUtility.GetLastRect().width, GUILayoutUtility.GetLastRect().height), "Select a BlendSystem", EditorStyles.popup);
            }
            else
            {
                EditorGUI.BeginChangeCheck();
                blendSystemNumber = EditorGUILayout.Popup("Blend System", blendSystemNumber, blendSystemNames.ToArray());
                if (EditorGUI.EndChangeCheck())
                {
                    ChangeBlendSystem();
                }
            }
        }
        if (lsTarget.blendSystem == null)
        {
            GUILayout.Label("No BlendSystem Selected");
            EditorGUILayout.HelpBox("A Blend System is required to use LipSync.", MessageType.Info);
        }

        EditorGUILayout.Space();
        if (lsTarget.blendSystem != null)
        {
            if (blendSystemEditor == null)
            {
                CreateBlendSystemEditor();
            }
            blendSystemEditor.OnInspectorGUI();
            if (!lsTarget.blendSystem.isReady)
            {
                GUILayout.Space(10);
                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                if (GUILayout.Button("Continue", GUILayout.MaxWidth(200)))
                {
                    lsTarget.blendSystem.OnVariableChanged();
                }
                GUILayout.FlexibleSpace();
                GUILayout.EndHorizontal();
                GUILayout.Space(10);
            }
        }

        if (lsTarget.blendSystem != null)
        {
            if (lsTarget.blendSystem.isReady)
            {
                EditorGUILayout.Space();
                EditorGUILayout.PropertyField(audioSource, new GUIContent("Audio Source", "AudioSource to play dialogue from."));

                EditorGUILayout.Space();
                EditorGUILayout.PropertyField(useBones, new GUIContent("Use Bone Transforms", "Allow BoneShapes to be added to phoneme poses. This enables the use of bone based facial animation."));
                showBoneOptions.target = lsTarget.useBones;
                if (EditorGUILayout.BeginFadeGroup(showBoneOptions.faded))
                {
                    EditorGUILayout.PropertyField(boneUpdateAnimation, new GUIContent("Account for Animation", "If true, will calculate relative bone positions/rotations each frame. Improves results when using animation, but will cause errors when not."));
                    EditorGUILayout.Space();
                }
                FixedEndFadeGroup(showBoneOptions.faded);
                EditorGUILayout.Space();
                if (blendSystemButtons.Length > 0 && blendSystemButtons.Length < 3)
                {
                    Rect buttonPanel = EditorGUILayout.BeginHorizontal();
                    EditorGUI.HelpBox(new Rect(buttonPanel.x, buttonPanel.y - 4, buttonPanel.width, buttonPanel.height + 8), "BlendSystem Commands:", MessageType.Info);
                    GUILayout.FlexibleSpace();
                    DrawBlendSystemButtons();
                    GUILayout.FlexibleSpace();
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.Space();
                }
                else if (blendSystemButtons.Length >= 3)
                {
                    Rect buttonPanel = EditorGUILayout.BeginHorizontal();
                    EditorGUI.HelpBox(new Rect(buttonPanel.x, buttonPanel.y - 4, buttonPanel.width, buttonPanel.height + 8), "BlendSystem Commands:", MessageType.Info);
                    GUILayout.FlexibleSpace();
                    DrawBlendSystemButtons();
                    GUILayout.Space(5);
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.Space();
                }
                int oldTab = markerTab;

                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                EditorGUI.BeginDisabledGroup(true);
                markerTab = GUILayout.Toolbar(markerTab, new GUIContent[] { new GUIContent("Phonemes"), new GUIContent("Emotions"), new GUIContent("Gestures") }, GUILayout.MaxWidth(400), GUILayout.MinHeight(23));
                EditorGUI.EndDisabledGroup();
                Rect presetRect = EditorGUILayout.BeginHorizontal();
                if (GUILayout.Button(new GUIContent(presetsIcon, "Presets"), GUILayout.MaxWidth(32), GUILayout.MinHeight(23)))
                {
                    GenericMenu menu = new GenericMenu();

                    string[] directories = Directory.GetDirectories(Application.dataPath, "Presets", SearchOption.AllDirectories);

                    bool noItems = true;
                    foreach (string directory in directories)
                    {
                        foreach (string file in Directory.GetFiles(directory))
                        {
                            if (Path.GetExtension(file).ToLower() == ".asset")
                            {
                                LipSyncPreset preset = AssetDatabase.LoadAssetAtPath <LipSyncPreset>("Assets" + file.Substring((Application.dataPath).Length));
                                if (preset != null)
                                {
                                    noItems = false;
                                    menu.AddItem(new GUIContent(Path.GetFileNameWithoutExtension(file)), false, LoadPreset, file);
                                }
                            }
                        }

                        string[] subdirectories = Directory.GetDirectories(directory);
                        foreach (string subdirectory in subdirectories)
                        {
                            foreach (string file in Directory.GetFiles(subdirectory))
                            {
                                if (Path.GetExtension(file).ToLower() == ".asset")
                                {
                                    LipSyncPreset preset = AssetDatabase.LoadAssetAtPath <LipSyncPreset>("Assets" + file.Substring((Application.dataPath).Length));
                                    if (preset != null)
                                    {
                                        noItems = false;
                                        menu.AddItem(new GUIContent(Path.GetFileName(subdirectory) + "/" + Path.GetFileNameWithoutExtension(file)), false, LoadPreset, file);
                                    }
                                }
                            }
                        }
                    }


                    if (noItems)
                    {
                        menu.AddDisabledItem(new GUIContent("No Presets Found"));
                    }

                    menu.AddSeparator("");
                    menu.AddItem(new GUIContent("Save New Preset"), false, NewPreset);
                    if (AssetDatabase.FindAssets("t:BlendShapePreset").Length > 0)
                    {
                        menu.AddDisabledItem(new GUIContent("Old-style presets found. Convert them to use."));
                    }

                    menu.DropDown(presetRect);
                }
                EditorGUILayout.EndHorizontal();

                GUILayout.FlexibleSpace();
                GUILayout.EndHorizontal();

                GUILayout.Space(10);
                GUILayout.Label("Upgrade to LipSync Pro to unlock Emotions and Gestures, along with many more features!");
                if (markerTab != oldTab)
                {
                    if (oldTab == 0)
                    {
                        foreach (PhonemeShape phoneme in lsTarget.phonemes)
                        {
                            foreach (int shape in phoneme.blendShapes)
                            {
                                lsTarget.blendSystem.SetBlendableValue(shape, 0);
                            }
                        }
                    }
                    if (LipSyncEditorExtensions.currentTarget == lsTarget)
                    {
                        LipSyncEditorExtensions.currentToggle = -1;
                    }
                }

                if (markerTab == 0)
                {
                    int a = 0;
                    foreach (PhonemeShape phoneme in lsTarget.phonemes)
                    {
                        this.DrawShapeEditor(lsTarget.blendSystem, lsTarget.useBones, phoneme, phoneme.phoneme.ToString() + " Phoneme", a);
                        a++;
                    }
                }

                EditorGUILayout.Space();
                GUILayout.Box("General Animation Settings", EditorStyles.boldLabel);
                EditorGUILayout.PropertyField(animationTimingMode, new GUIContent("Timing Mode", "How animations are sampled: AudioPlayback uses the audioclip, CustomTimer uses a framerate independent timer, FixedFrameRate is framerate dependent."));
                showFixedFrameRate.target = lsTarget.animationTimingMode == LipSync.AnimationTimingMode.FixedFrameRate;
                if (EditorGUILayout.BeginFadeGroup(showFixedFrameRate.faded))
                {
                    EditorGUILayout.PropertyField(frameRate, new GUIContent("Frame Rate", "The framerate to play the animation at."));
                }
                EditorGUILayout.EndFadeGroup();
                EditorGUILayout.PropertyField(playOnAwake, new GUIContent("Play On Awake", "If checked, the default clip will play when the script awakes."));
                showPlayOnAwake.target = lsTarget.playOnAwake;
                if (EditorGUILayout.BeginFadeGroup(showPlayOnAwake.faded))
                {
                    EditorGUILayout.PropertyField(defaultClip, new GUIContent("Default Clip", "The clip to play on awake."));
                    EditorGUILayout.PropertyField(defaultDelay, new GUIContent("Default Delay", "The delay between the scene starting and the clip playing."));
                }
                EditorGUILayout.EndFadeGroup();
                EditorGUILayout.PropertyField(loop, new GUIContent("Loop Clip", "If true, will make any played clip loop when it finishes."));
                EditorGUILayout.PropertyField(scaleAudioSpeed, new GUIContent("Scale Audio Speed", "Whether or not the speed of the audio will be slowed/sped up to match Time.timeScale."));
                EditorGUILayout.Space();
                GUILayout.Box("Phoneme Animation Settings", EditorStyles.boldLabel);
                EditorGUILayout.PropertyField(restTime, new GUIContent("Rest Time", "If there are no phonemes within this many seconds of the previous one, a rest will be inserted."));
                EditorGUILayout.PropertyField(restHoldTime, new GUIContent("Pre-Rest Hold Time", "The time, in seconds, a shape will be held before blending when a rest is inserted."));
                EditorGUILayout.PropertyField(phonemeCurveGenerationMode, new GUIContent("Phoneme Curve Generation Mode", "How tangents are generated for animations. Tight is more accurate, Loose is more natural."));
                EditorGUILayout.Space();

                GUILayout.Space(20);

                EditorGUILayout.PropertyField(onFinishedPlaying);

                if (LipSyncEditorExtensions.oldToggle != LipSyncEditorExtensions.currentToggle && LipSyncEditorExtensions.currentTarget == lsTarget)
                {
                    if (LipSyncEditorExtensions.oldToggle > -1)
                    {
                        if (markerTab == 0)
                        {
                            if (lsTarget.useBones)
                            {
                                foreach (BoneShape boneshape in lsTarget.phonemes[LipSyncEditorExtensions.oldToggle].bones)
                                {
                                    if (boneshape.bone != null)
                                    {
                                        boneshape.bone.localPosition    = boneshape.neutralPosition;
                                        boneshape.bone.localEulerAngles = boneshape.neutralRotation;
                                    }
                                }
                            }

                            foreach (PhonemeShape shape in lsTarget.phonemes)
                            {
                                foreach (int blendable in shape.blendShapes)
                                {
                                    lsTarget.blendSystem.SetBlendableValue(blendable, 0);
                                }
                            }
                        }
                    }

                    if (LipSyncEditorExtensions.currentToggle > -1)
                    {
                        if (markerTab == 0)
                        {
                            if (lsTarget.useBones)
                            {
                                foreach (BoneShape boneshape in lsTarget.phonemes[LipSyncEditorExtensions.currentToggle].bones)
                                {
                                    if (boneshape.bone != null)
                                    {
                                        boneshape.bone.localPosition    = boneshape.endPosition;
                                        boneshape.bone.localEulerAngles = boneshape.endRotation;
                                    }
                                }
                            }

                            for (int b = 0; b < lsTarget.phonemes[LipSyncEditorExtensions.currentToggle].blendShapes.Count; b++)
                            {
                                lsTarget.blendSystem.SetBlendableValue(lsTarget.phonemes[LipSyncEditorExtensions.currentToggle].blendShapes[b], lsTarget.phonemes[LipSyncEditorExtensions.currentToggle].weights[b]);
                            }
                        }
                    }

                    LipSyncEditorExtensions.oldToggle = LipSyncEditorExtensions.currentToggle;
                }

                if (GUI.changed)
                {
                    if (blendables == null)
                    {
                        GetBlendShapes();
                    }

                    if (LipSyncEditorExtensions.currentToggle > -1 && LipSyncEditorExtensions.currentTarget == lsTarget)
                    {
                        if (markerTab == 0)
                        {
                            for (int b = 0; b < lsTarget.phonemes[LipSyncEditorExtensions.currentToggle].blendShapes.Count; b++)
                            {
                                lsTarget.blendSystem.SetBlendableValue(lsTarget.phonemes[LipSyncEditorExtensions.currentToggle].blendShapes[b], lsTarget.phonemes[LipSyncEditorExtensions.currentToggle].weights[b]);
                            }
                        }
                    }

                    EditorUtility.SetDirty(lsTarget);
                    serializedTarget.SetIsDifferentCacheDirty();
                }
            }
            else
            {
                EditorGUILayout.HelpBox(lsTarget.blendSystem.notReadyMessage, MessageType.Warning);
            }
        }
        EditorGUI.EndDisabledGroup();
        EditorGUILayout.EndVertical();

        if (saving)
        {
            GUI.Box(new Rect(40, fullheight.y + (fullheight.height / 2) - 60, fullheight.width - 80, 120), "", (GUIStyle)"flow node 0");
            GUI.Box(new Rect(50, fullheight.y + (fullheight.height / 2) - 50, fullheight.width - 100, 20), "Create New Preset", EditorStyles.label);
            GUI.Box(new Rect(50, fullheight.y + (fullheight.height / 2) - 20, 80, 20), "Preset Path", EditorStyles.label);
            savingName = EditorGUI.TextField(new Rect(140, fullheight.y + (fullheight.height / 2) - 20, fullheight.width - 290, 20), "", savingName);

            if (GUI.Button(new Rect(fullheight.width - 140, fullheight.y + (fullheight.height / 2) - 20, 80, 20), "Browse"))
            {
                GUI.FocusControl("");
                string newPath = EditorUtility.SaveFilePanelInProject("Chose Preset Location", "New Preset", "asset", "");

                if (newPath != "")
                {
                    savingName = newPath.Substring("Assets/".Length);
                }
            }
            if (GUI.Button(new Rect(100, fullheight.y + (fullheight.height / 2) + 15, (fullheight.width / 2) - 110, 25), "Cancel"))
            {
                GUI.FocusControl("");
                savingName = "";
                saving     = false;
            }
            if (GUI.Button(new Rect((fullheight.width / 2) + 10, fullheight.y + (fullheight.height / 2) + 15, (fullheight.width / 2) - 110, 25), "Save"))
            {
                if (!Path.GetDirectoryName(savingName).Contains("Presets"))
                {
                    EditorUtility.DisplayDialog("Invalid Path", "Presets must be saved in a folder called Presets, or a subfolder of one.", "OK");
                    return;
                }
                else if (!Directory.Exists(Application.dataPath + "/" + Path.GetDirectoryName(savingName)))
                {
                    EditorUtility.DisplayDialog("Directory Does Not Exist", "The directory " + Path.GetDirectoryName(savingName) + " does not exist.", "OK");
                    return;
                }
                else if (!Path.HasExtension(savingName))
                {
                    savingName = Path.GetDirectoryName(savingName) + "/" + Path.GetFileNameWithoutExtension(savingName) + ".asset";
                }
                else if (Path.GetExtension(savingName) != ".asset")
                {
                    savingName = Path.GetDirectoryName(savingName) + "/" + Path.GetFileNameWithoutExtension(savingName) + ".asset";
                }

                LipSyncPreset preset = ScriptableObject.CreateInstance <LipSyncPreset>();
                preset.phonemeShapes = new LipSyncPreset.PhonemeShapeInfo[lsTarget.phonemes.Count];

                // Add phonemes
                for (int p = 0; p < lsTarget.phonemes.Count; p++)
                {
                    LipSyncPreset.PhonemeShapeInfo phonemeInfo = new LipSyncPreset.PhonemeShapeInfo();
                    phonemeInfo.phoneme    = lsTarget.phonemes[p].phoneme;
                    phonemeInfo.blendables = new LipSyncPreset.BlendableInfo[lsTarget.phonemes[p].blendShapes.Count];
                    phonemeInfo.bones      = new LipSyncPreset.BoneInfo[lsTarget.phonemes[p].bones.Count];

                    // Add blendables
                    for (int b = 0; b < lsTarget.phonemes[p].blendShapes.Count; b++)
                    {
                        LipSyncPreset.BlendableInfo blendable = new LipSyncPreset.BlendableInfo();
                        blendable.blendableNumber = lsTarget.phonemes[p].blendShapes[b];
                        blendable.blendableName   = blendables[lsTarget.phonemes[p].blendShapes[b]];
                        blendable.weight          = lsTarget.phonemes[p].weights[b];

                        phonemeInfo.blendables[b] = blendable;
                    }

                    // Add bones
                    for (int b = 0; b < lsTarget.phonemes[p].bones.Count; b++)
                    {
                        LipSyncPreset.BoneInfo bone = new LipSyncPreset.BoneInfo();
                        bone.name          = lsTarget.phonemes[p].bones[b].bone.name;
                        bone.localPosition = lsTarget.phonemes[p].bones[b].endPosition;
                        bone.localRotation = lsTarget.phonemes[p].bones[b].endRotation;
                        bone.lockPosition  = lsTarget.phonemes[p].bones[b].lockPosition;
                        bone.lockRotation  = lsTarget.phonemes[p].bones[b].lockRotation;

                        string    path  = "";
                        Transform level = lsTarget.phonemes[p].bones[b].bone.parent;
                        while (level != null)
                        {
                            path += level.name + "/";
                            level = level.parent;
                        }
                        bone.path = path;

                        phonemeInfo.bones[b] = bone;
                    }

                    preset.phonemeShapes[p] = phonemeInfo;
                }

                AssetDatabase.CreateAsset(preset, "Assets/" + savingName);
                AssetDatabase.Refresh();
                savingName = "";
                saving     = false;
            }
        }

        serializedTarget.ApplyModifiedProperties();
    }