private void OnGUI() { if (_editorEffector.GetCurrentlyEditing() == CurrentlyEditing.Nothing) { return; } if (_editorEffector.IsFirstTimeSetup() && _editorEffector.IsPreviewSetupValid()) { _editorEffector.ClearFirstTimeSetup(); } GUILayout.BeginArea(new Rect(position.width - 320, CgeLayoutCommon.SingleLineHeight * 2 + 5, 200, CgeLayoutCommon.SingleLineHeight + 2)); if (GUILayout.Button(new GUIContent("❈ ExpressionsEditor"), GUILayout.Width(170), GUILayout.Height(CgeLayoutCommon.SingleLineHeight + 2))) { EeAnimationEditorWindow.Obtain().Show(); } GUILayout.EndArea(); GUILayout.BeginArea(new Rect(position.width - 130, CgeLayoutCommon.SingleLineHeight * 2 + 5, 100, CgeLayoutCommon.SingleLineHeight + 2)); if (GUILayout.Button(new GUIContent(" " + CgeLocale.CGEE_Tutorials, _helpIcon16), GUILayout.Width(100), GUILayout.Height(CgeLayoutCommon.SingleLineHeight + 2))) { Application.OpenURL(CgeLocale.DocumentationUrl()); } GUILayout.EndArea(); switch (_editorEffector.GetCurrentlyEditing()) { case CurrentlyEditing.Nothing: break; case CurrentlyEditing.Activity: EditingAnActivity(); break; case CurrentlyEditing.Puppet: EditingAPuppet(); break; default: throw new ArgumentOutOfRangeException(); } }
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(); }