public override void OnInspectorGUI()
        {
            serializedObject.Update();

            if (GUILayout.Button("Switch language (English / 日本語)"))
            {
                CgeLocalization.CycleLocale();
            }

            if (CgeLocalization.IsEnglishLocaleActive())
            {
                EditorGUILayout.LabelField("");
            }
            else
            {
                EditorGUILayout.LabelField("一部の翻訳は正確ではありません。cge.jp.jsonを編集することができます。");
            }

            _foldoutHelp = EditorGUILayout.Foldout(_foldoutHelp, new GUIContent("Help", _guideIcon32));
            if (_foldoutHelp)
            {
                if (GUILayout.Button(new GUIContent("Open documentation and tutorials", _guideIcon32)))
                {
                    Application.OpenURL("https://hai-vr.github.io/combo-gesture-expressions-av3/");
                }
            }

            EditorGUILayout.Separator();
            EditorGUI.BeginDisabledGroup(serializedObject.isEditingMultipleObjects);
            if (GUILayout.Button(new GUIContent(CgeLocale.CGEE_Open_editor), GUILayout.Height(40)))
            {
                CgeWindowHandler.Obtain().ShowActivity((ComboGestureActivity)serializedObject.targetObject);
            }

            if (serializedObject.isEditingMultipleObjects)
            {
                EditorGUILayout.HelpBox("Editor window is not available in multi-editing.", MessageType.Info);
            }
            EditorGUI.EndDisabledGroup();
            EditorGUILayout.Separator();

            if (!serializedObject.isEditingMultipleObjects)
            {
                editorLegacyFoldout.boolValue = EditorGUILayout.Foldout(editorLegacyFoldout.boolValue, "Legacy editor");
            }
            else
            {
                GUILayout.Label("Legacy editor / Multi editing", EditorStyles.boldLabel);
            }

            if (serializedObject.isEditingMultipleObjects || editorLegacyFoldout.boolValue)
            {
                LegacyEditor();
            }

            serializedObject.ApplyModifiedProperties();
        }
Ejemplo n.º 2
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            if (GUILayout.Button("Switch language (English / 日本語)"))
            {
                CgeLocalization.CycleLocale();
            }

            if (CgeLocalization.IsEnglishLocaleActive())
            {
                EditorGUILayout.LabelField("");
            }
            else
            {
                EditorGUILayout.LabelField("一部の翻訳は正確ではありません。cge.jp.jsonを編集することができます。");
            }

            if (GUILayout.Button(new GUIContent(CgeLocale.CGEI_Documentation, _guideIcon32)))
            {
                Application.OpenURL(CgeLocale.IntegratorDocumentationUrl());
            }

            var italic = new GUIStyle(GUI.skin.label)
            {
                fontStyle = FontStyle.Italic
            };

            EditorGUILayout.LabelField(CgeLocale.CGEI_BackupAnimator, italic);
            EditorGUILayout.PropertyField(animatorController, new GUIContent(CgeLocale.CGEI_Animator_Controller));
            EditorGUILayout.PropertyField(writeDefaults, new GUIContent("Write Defaults"));

            EditorGUILayout.Space();

            EditorGUI.BeginDisabledGroup(ThereIsNoAnimatorController());

            bool ThereIsNoAnimatorController()
            {
                return(animatorController.objectReferenceValue == null);
            }

            if (GUILayout.Button(CgeLocale.CGEI_Synchronize_Animator_layers, GUILayout.Height(40)))
            {
                DoGenerate();
            }
            EditorGUI.EndDisabledGroup();

            EditorGUILayout.Space();

            EditorGUILayout.HelpBox(CgeLocale.CGEI_Info, MessageType.Info);
            EditorGUILayout.TextField("GestureLeftWeight", "_Hai_GestureLWSmoothing");
            EditorGUILayout.TextField("GestureRightWeight", "_Hai_GestureRWSmoothing");

            serializedObject.ApplyModifiedProperties();
        }
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            if (mainTree.objectReferenceValue != null && mainTree.objectReferenceValue is AnimationClip)
            {
                mainTree.objectReferenceValue = null;
            }

            if (GUILayout.Button("Switch language (English / 日本語)"))
            {
                CgeLocalization.CycleLocale();
            }

            if (CgeLocalization.IsEnglishLocaleActive())
            {
                EditorGUILayout.LabelField("");
            }
            else
            {
                EditorGUILayout.LabelField("一部の翻訳は正確ではありません。cge.jp.jsonを編集することができます。");
            }

            EditorGUILayout.Separator();
            EditorGUI.BeginDisabledGroup(serializedObject.isEditingMultipleObjects);
            if (GUILayout.Button(new GUIContent(CgeLocale.CGEE_Open_editor), GUILayout.Height(40)))
            {
                CgeWindowHandler.Obtain().ShowPuppet((ComboGesturePuppet)serializedObject.targetObject);
            }

            if (serializedObject.isEditingMultipleObjects)
            {
                EditorGUILayout.HelpBox("Editor window is not available in multi-editing.", MessageType.Info);
            }
            EditorGUI.EndDisabledGroup();
            EditorGUILayout.Separator();

            if (!serializedObject.isEditingMultipleObjects)
            {
                editorLegacyFoldout.boolValue = EditorGUILayout.Foldout(editorLegacyFoldout.boolValue, "Legacy editor");
            }
            else
            {
                GUILayout.Label("Legacy editor / Multi editing", EditorStyles.boldLabel);
            }

            if (serializedObject.isEditingMultipleObjects || editorLegacyFoldout.boolValue)
            {
                LegacyEditor();
            }

            serializedObject.ApplyModifiedProperties();
        }
        public override void OnInspectorGUI()
        {
            if (AsCompiler().comboLayers == null)
            {
                AsCompiler().comboLayers = new List <GestureComboStageMapper>();
            }
            serializedObject.Update();
            var italic = new GUIStyle(GUI.skin.label)
            {
                fontStyle = FontStyle.Italic
            };

            if (GUILayout.Button("Switch language (English / 日本語)"))
            {
                CgeLocalization.CycleLocale();
            }

            if (CgeLocalization.IsEnglishLocaleActive())
            {
                EditorGUILayout.LabelField("");
            }
            else
            {
                EditorGUILayout.LabelField("一部の翻訳は正確ではありません。cge.jp.jsonを編集することができます。");
            }

            if (GUILayout.Button(new GUIContent(CgeLocale.CGEC_Documentation_and_tutorials, _guideIcon32)))
            {
                Application.OpenURL(CgeLocale.DocumentationUrl());
            }

            EditorGUILayout.LabelField(CgeLocale.CGEC_Mood_sets, EditorStyles.boldLabel);
            EditorGUILayout.PropertyField(avatarDescriptor, new GUIContent(CgeLocale.CGEC_Avatar_descriptor));
            var compiler = AsCompiler();

            EditorGUI.BeginDisabledGroup(comboLayers.arraySize <= 1);
            EditorGUILayout.PropertyField(parameterMode, new GUIContent(CgeLocale.CGEC_Parameter_Mode));
            EditorGUI.EndDisabledGroup();
            if (compiler.parameterMode == ParameterMode.SingleInt)
            {
                EditorGUILayout.PropertyField(activityStageName, new GUIContent(CgeLocale.CGEC_Parameter_Name));
            }

            if (compiler.parameterMode == ParameterMode.SingleInt && comboLayers.arraySize < 8 && comboLayers.arraySize > 1)
            {
                EditorGUILayout.HelpBox(
                    CgeLocale.CGEC_HelpExpressionParameterOptimize,
                    MessageType.Info);
            }

            comboLayersReorderableList.DoLayoutList();

            EditorGUILayout.Separator();

            bool ThereIsAnOverlap()
            {
                if (compiler.parameterMode == ParameterMode.SingleInt)
                {
                    return(compiler.comboLayers != null && comboLayers.arraySize != compiler.comboLayers.Select(mapper => mapper.stageValue).Distinct().Count());
                }
                else
                {
                    return(compiler.comboLayers != null && comboLayers.arraySize != compiler.comboLayers.Select(mapper => mapper.booleanParameterName).Distinct().Count());
                }
            }

            bool MultipleBooleanNoDefault()
            {
                return(compiler.parameterMode == ParameterMode.MultipleBools && compiler.comboLayers != null && compiler.comboLayers.TrueForAll(mapper => !string.IsNullOrEmpty(mapper.booleanParameterName)));
            }

            bool ThereIsAPuppetWithNoBlendTree()
            {
                return(compiler.comboLayers != null && compiler.comboLayers
                       .Where(mapper => mapper.kind == GestureComboStageKind.Puppet)
                       .Where(mapper => mapper.puppet != null)
                       .Any(mapper => !(mapper.puppet.mainTree is BlendTree)));
            }

            bool ThereIsAMassiveBlendWithIncorrectConfiguration()
            {
                return(compiler.comboLayers != null && compiler.comboLayers
                       .Where(mapper => mapper.kind == GestureComboStageKind.Massive)
                       .Where(mapper => mapper.massiveBlend != null)
                       .Any(mapper =>
                {
                    var massiveBlend = mapper.massiveBlend;
                    switch (massiveBlend.mode)
                    {
                    case CgeMassiveBlendMode.Simple:
                        return massiveBlend.simpleZero == null || massiveBlend.simpleOne == null;

                    case CgeMassiveBlendMode.TwoDirections:
                        return massiveBlend.simpleZero == null || massiveBlend.simpleOne == null || massiveBlend.simpleMinusOne == null;

                    case CgeMassiveBlendMode.ComplexBlendTree:
                        return massiveBlend.blendTreeMoods.Count == 0 ||
                        massiveBlend.blendTree == null ||
                        !(massiveBlend.blendTree is BlendTree) ||
                        ((BlendTree)massiveBlend.blendTree).children.Length != massiveBlend.blendTreeMoods.Count;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }));
            }

            bool ThereIsANullMapper()
            {
                return(compiler.comboLayers != null && compiler.comboLayers.Any(mapper =>
                                                                                mapper.kind == GestureComboStageKind.Activity && mapper.activity == null ||
                                                                                mapper.kind == GestureComboStageKind.Puppet && mapper.puppet == null ||
                                                                                mapper.kind == GestureComboStageKind.Massive && mapper.massiveBlend == null
                                                                                ));
            }

            bool ThereIsNoActivityNameForMultipleActivities()
            {
                return(compiler.parameterMode == ParameterMode.SingleInt && comboLayers.arraySize >= 2 && (activityStageName.stringValue == null || activityStageName.stringValue.Trim() == ""));
            }

            if (ThereIsAnOverlap())
            {
                if (compiler.parameterMode == ParameterMode.SingleInt)
                {
                    EditorGUILayout.HelpBox(CgeLocale.CGEC_WarnValuesOverlap, MessageType.Error);
                }
                else
                {
                    EditorGUILayout.HelpBox(CgeLocale.CGEC_WarnNamesOverlap, MessageType.Error);
                }
            }
            else if (ThereIsAPuppetWithNoBlendTree())
            {
                EditorGUILayout.HelpBox(CgeLocale.CGEC_WarnNoBlendTree, MessageType.Error);
            }
            else if (ThereIsAMassiveBlendWithIncorrectConfiguration())
            {
                EditorGUILayout.HelpBox(CgeLocale.CGEC_WarnNoMassiveBlend, MessageType.Error);
            }
            else if (ThereIsNoActivityNameForMultipleActivities())
            {
                EditorGUILayout.HelpBox(CgeLocale.CGEC_WarnNoActivityName, MessageType.Error);
            }
            else if (ThereIsANullMapper())
            {
                EditorGUILayout.HelpBox(CgeLocale.CGEC_WarnNoActivity, MessageType.Warning);
            }
            else
            {
                // Good cases
                if (compiler.comboLayers != null && compiler.comboLayers.Count > 1)
                {
                    if (MultipleBooleanNoDefault())
                    {
                        EditorGUILayout.HelpBox(string.Format(CgeLocale.CGEC_HelpWhenAllParameterNamesDefined, compiler.comboLayers.First().SimpleName(), compiler.comboLayers.First().booleanParameterName), MessageType.Info);
                    }

                    var defaultMapper = compiler.comboLayers.FirstOrDefault(mapper => mapper.booleanParameterName == "");
                    if (compiler.parameterMode == ParameterMode.MultipleBools &&
                        (defaultMapper.kind == GestureComboStageKind.Activity && defaultMapper.activity != null ||
                         defaultMapper.kind == GestureComboStageKind.Puppet && defaultMapper.puppet != null ||
                         defaultMapper.kind == GestureComboStageKind.Massive && defaultMapper.massiveBlend != null))
                    {
                        EditorGUILayout.HelpBox(string.Format(CgeLocale.CGEC_HintDefaultMood, defaultMapper.SimpleName()), MessageType.Info);
                    }
                }
            }

            EditorGUILayout.LabelField(CgeLocale.CGEC_FX_Playable_Layer, EditorStyles.boldLabel);
            EditorGUILayout.LabelField(CgeLocale.CGEC_BackupFX, italic);
            EditorGUILayout.PropertyField(animatorController, new GUIContent(CgeLocale.CGEC_FX_Animator_Controller));
            EditorGUILayout.PropertyField(writeDefaultsRecommendationMode, new GUIContent(CgeLocale.CGEC_FX_Playable_Mode));
            WriteDefaultsSection(writeDefaultsRecommendationMode);

            EditorGUILayout.Separator();

            EditorGUILayout.LabelField(CgeLocale.CGEC_Gesture_Playable_Layer, EditorStyles.boldLabel);
            EditorGUILayout.LabelField(CgeLocale.CGEC_Support_for_other_transforms, italic);
            EditorGUILayout.LabelField(CgeLocale.CGEC_MusclesUnsupported, italic);
            EditorGUILayout.PropertyField(useGesturePlayableLayer, new GUIContent(CgeLocale.CGEC_Gesture_playable_layer_support));
            if (useGesturePlayableLayer.boolValue)
            {
                EditorGUILayout.LabelField(CgeLocale.CGEC_BackupGesture, italic);
                EditorGUILayout.PropertyField(gesturePlayableLayerController, new GUIContent(CgeLocale.CGEC_Gesture_Animator_Controller));

                EditorGUILayout.PropertyField(writeDefaultsRecommendationModeGesture, new GUIContent(CgeLocale.CGEC_Gesture_Playable_Mode));
                EditorGUILayout.PropertyField(gestureLayerTransformCapture, new GUIContent(CgeLocale.CGEC_Capture_Transforms_Mode));
                WriteDefaultsSection(writeDefaultsRecommendationModeGesture);

                EditorGUI.BeginDisabledGroup(true);
                EditorGUILayout.PropertyField(generatedAvatarMask, new GUIContent(CgeLocale.CGEC_Asset_container));
                EditorGUI.EndDisabledGroup();

                var missingMaskCount = CgeMaskApplicator.FindAllLayersMissingAMask(compiler.animatorController).Count();
                if (missingMaskCount > 0)
                {
                    EditorGUILayout.HelpBox(string.Format(CgeLocale.CGEC_MissingFxMask, missingMaskCount), MessageType.Error);
                }

                EditorGUI.BeginDisabledGroup(compiler.avatarDescriptor == null || compiler.animatorController == null || missingMaskCount == 0);
                if (GUILayout.Button(CgeLocale.CGEC_Add_missing_masks))
                {
                    AddMissingMasks(compiler);
                }
                EditorGUI.EndDisabledGroup();

                if (compiler.generatedAvatarMask != null)
                {
                    EditorGUI.BeginDisabledGroup(compiler.avatarDescriptor == null || compiler.animatorController == null);
                    MaskRemovalUi(compiler);
                    EditorGUI.EndDisabledGroup();
                }
            }
            else
            {
                if (compiler.animatorController != null && compiler.generatedAvatarMask != null)
                {
                    MaskRemovalUi(compiler);
                }
            }

            EditorGUILayout.Separator();

            EditorGUILayout.LabelField(CgeLocale.CGEC_Synchronization, EditorStyles.boldLabel);

            EditorGUI.BeginDisabledGroup(
                ThereIsNoAnimatorController() ||
                ThereIsNoGestureAnimatorController() ||
                ThereIsNoActivity() ||
                ThereIsAnOverlap() ||
                ThereIsAPuppetWithNoBlendTree() ||
                ThereIsAMassiveBlendWithIncorrectConfiguration() ||
                ThereIsANullMapper() ||
                ThereIsNoActivityNameForMultipleActivities() ||
                ThereIsNoAvatarDescriptor() ||
                LipsyncIsIntegratedButThereIsNoCorrection()
                );

            bool ThereIsNoAnimatorController()
            {
                return(animatorController.objectReferenceValue == null);
            }

            bool ThereIsNoGestureAnimatorController()
            {
                return(useGesturePlayableLayer.boolValue && gesturePlayableLayerController.objectReferenceValue == null);
            }

            bool ThereIsNoActivity()
            {
                return(comboLayers.arraySize == 0);
            }

            bool ThereIsNoAvatarDescriptor()
            {
                return(!compiler.bypassMandatoryAvatarDescriptor &&
                       compiler.avatarDescriptor == null);
            }

            bool LipsyncIsIntegratedButThereIsNoCorrection()
            {
                return(!compiler.bypassMandatoryAvatarDescriptor &&
                       !compiler.doNotGenerateLipsyncOverrideLayer &&
                       compiler.integrateLimitedLipsync &&
                       compiler.lipsyncForWideOpenMouth == null);
            }

            if (GUILayout.Button(compiler.useGesturePlayableLayer ?
                                 CgeLocale.CGEC_Synchronize_Animator_FX_and_Gesture_layers :
                                 CgeLocale.CGEC_Synchronize_Animator_FX_layers, GUILayout.Height(40)))
            {
                DoGenerate();
            }
            EditorGUI.EndDisabledGroup();

            EditorGUILayout.HelpBox(
                CgeLocale.CGEC_SynchronizationConditionsV1, MessageType.Info);

            if (compiler.assetContainer != null)
            {
                EditorGUILayout.LabelField(CgeLocale.CGEC_Asset_generation, EditorStyles.boldLabel);
                EditorGUILayout.PropertyField(assetContainer, new GUIContent(CgeLocale.CGEC_Asset_container));
            }

            EditorGUILayout.Separator();

            EditorGUILayout.LabelField(CgeLocale.CGEC_Other_tweaks, EditorStyles.boldLabel);
            EditorGUILayout.PropertyField(analogBlinkingUpperThreshold, new GUIContent(CgeLocale.CGEC_Analog_fist_blinking_threshold, CgeLocale.CGEC_AnalogFist_Popup));

            editorAdvancedFoldout.boolValue = EditorGUILayout.Foldout(editorAdvancedFoldout.boolValue, CgeLocale.CGEC_Advanced);
            if (editorAdvancedFoldout.boolValue)
            {
                EditorGUILayout.LabelField("Corrections", EditorStyles.boldLabel);
                if (compiler.avatarDescriptor != null)
                {
                    EditorGUILayout.PropertyField(weightCorrectionMode, new GUIContent(FakeBooleanIcon(compiler.WillUseGestureWeightCorrection()) + CgeLocale.CGEC_GestureWeight_correction));

                    EditorGUI.BeginDisabledGroup(compiler.doNotGenerateLipsyncOverrideLayer);
                    if (compiler.integrateLimitedLipsync && !compiler.doNotGenerateLipsyncOverrideLayer)
                    {
                        EditorGUILayout.PropertyField(lipsyncForWideOpenMouth, new GUIContent(CgeLocale.CGEC_Lipsync_correction));
                        var lipsyncBlendshapes = new BlendshapesFinder(compiler.avatarDescriptor).FindLipsync();
                        if (lipsyncBlendshapes.Any())
                        {
                            var firstLipsyncBlendshape = lipsyncBlendshapes.FirstOrDefault();
                            if (lipsyncBlendshapes.Any())
                            {
                                EditorGUILayout.LabelField(CgeLocale.CGEC_Found_lipsync_blendshapes);
                                EditorGUILayout.LabelField("- " + firstLipsyncBlendshape.Path + "::" + firstLipsyncBlendshape.BlendShapeName + " (+ " + (lipsyncBlendshapes.Count - 1) + " more...)");
                            }
                            else
                            {
                                EditorGUILayout.LabelField(CgeLocale.CGEC_No_lipsync_blendshapes_found);
                            }
                        }
                    }
                    EditorGUI.EndDisabledGroup();
                }

                EditorGUILayout.LabelField("Fine tuning", EditorStyles.boldLabel);
                EditorGUILayout.PropertyField(customEmptyClip, new GUIContent("Custom 2-frame empty animation clip (optional)"));

                EditorGUILayout.Separator();

                EditorGUILayout.LabelField("Layer generation", EditorStyles.boldLabel);
                EditorGUILayout.PropertyField(expressionsAvatarMask, new GUIContent("Override Avatar Mask on Expressions layer"));
                EditorGUILayout.PropertyField(logicalAvatarMask, new GUIContent("Override Avatar Mask on Controller&Blinking layers"));
                EditorGUILayout.PropertyField(weightCorrectionAvatarMask, new GUIContent("Override Avatar Mask on Weight Correction layer"));
                EditorGUILayout.PropertyField(gesturePlayableLayerExpressionsAvatarMask, new GUIContent("Override Avatar Mask on Gesture playable expressions layer"));
                EditorGUILayout.PropertyField(gesturePlayableLayerTechnicalAvatarMask, new GUIContent("Override Avatar Mask on Gesture playable technical layers"));
                EditorGUILayout.PropertyField(doNotGenerateBlinkingOverrideLayer, new GUIContent("Don't update Blinking layer"));
                GenBlinkingWarning(true);
                EditorGUILayout.PropertyField(doNotGenerateLipsyncOverrideLayer, new GUIContent("Don't update Lipsync layer"));
                EditorGUILayout.PropertyField(doNotGenerateWeightCorrectionLayer, new GUIContent("Don't update Weight Correction layer"));
                GenWeightCorrection(true);

                EditorGUILayout.LabelField("Animation generation", EditorStyles.boldLabel);
                EditorGUILayout.PropertyField(assetContainer, new GUIContent(CgeLocale.CGEC_Asset_container));

                EditorGUI.BeginDisabledGroup(assetContainer.objectReferenceValue != null);
                EditorGUILayout.PropertyField(generateNewContainerEveryTime, new GUIContent("Don't keep track of newly generated containers"));
                EditorGUILayout.PropertyField(folderToGenerateNeutralizedAssetsIn, new GUIContent("Generate assets in the same folder as..."));
                if (animatorController.objectReferenceValue != null)
                {
                    EditorGUILayout.LabelField("Assets will be generated in:");
                    EditorGUI.BeginDisabledGroup(true);
                    EditorGUILayout.TextField(ResolveFolderToCreateNeutralizedAssetsIn((RuntimeAnimatorController)folderToGenerateNeutralizedAssetsIn.objectReferenceValue, (RuntimeAnimatorController)animatorController.objectReferenceValue));
                    EditorGUI.EndDisabledGroup();
                }
                EditorGUI.EndDisabledGroup();

                EditorGUILayout.PropertyField(conflictFxLayerMode, new GUIContent("FX Transforms removal"));

                CpmRemovalWarning(true);
                EditorGUILayout.Separator();

                EditorGUILayout.LabelField("Fallback generation", EditorStyles.boldLabel);
                EditorGUILayout.PropertyField(ignoreParamList, new GUIContent("Ignored properties"));
                EditorGUILayout.PropertyField(fallbackParamList, new GUIContent("Fallback values"));
                EditorGUILayout.PropertyField(doNotFixSingleKeyframes, new GUIContent("Do not fix single keyframes"));
                EditorGUILayout.PropertyField(bypassMandatoryAvatarDescriptor, new GUIContent("Bypass mandatory avatar descriptor"));

                EditorGUILayout.LabelField("Translations", EditorStyles.boldLabel);
                if (GUILayout.Button("(Debug) Print default translation file to console"))
                {
                    Debug.Log(CgeLocale.CompileDefaultLocaleJson());
                }
                if (GUILayout.Button("(Debug) Reload localization files"))
                {
                    CgeLocalization.ReloadLocalizations();
                }
            }
            else
            {
                GenBlinkingWarning(false);
                GenWeightCorrection(false);
                CpmRemovalWarning(false);
            }

            serializedObject.ApplyModifiedProperties();
        }
 private static string LocalizeOrElse(string key, string defaultCultureLocalization)
 {
     return(CgeLocalization.LocalizeOrElse(key, defaultCultureLocalization));
 }