//============================================================================================ /** * @brief * *********************************************************************************************/ private void OnEnable() { m_animator = target as MxMAnimator; m_spDIYPlayableGraph = serializedObject.FindProperty("p_DIYPlayableGraph"); m_spAutoCreateAnimatorController = serializedObject.FindProperty("m_autoCreateAnimatorController"); m_spAnimatorControllerMask = serializedObject.FindProperty("m_animatorControllerMask"); m_spRootMotionMode = serializedObject.FindProperty("m_rootMotionMode"); m_spTransitionMethod = serializedObject.FindProperty("m_transitionMethod"); m_spUpdateInterval = serializedObject.FindProperty("m_updateInterval"); m_spPlaybackSpeed = serializedObject.FindProperty("m_playbackSpeed"); m_spPlaybackSpeedSmoothRate = serializedObject.FindProperty("m_playbackSpeedSmoothRate"); m_spMatchBlendTime = serializedObject.FindProperty("m_matchBlendTime"); m_spTurnInPlaceThreshold = serializedObject.FindProperty("m_turnInPlaceThreshold"); m_spAnimData = serializedObject.FindProperty("m_animData"); m_spAnimationRootOverride = serializedObject.FindProperty("m_animationRoot"); m_spMaxMixCount = serializedObject.FindProperty("m_maxMixCount"); m_spDebugGoal = serializedObject.FindProperty("m_debugGoal"); m_spDebugChosenTrajectory = serializedObject.FindProperty("m_debugChosenTrajectory"); m_spDebugPoses = serializedObject.FindProperty("m_debugPoses"); m_spDebugCurrentPose = serializedObject.FindProperty("m_debugCurrentPose"); m_spDebugAnimDataId = serializedObject.FindProperty("m_debugAnimDataId"); m_spDebugPoseId = serializedObject.FindProperty("m_debugPoseId"); m_spAngularWarpType = serializedObject.FindProperty("m_angularWarpType"); m_spAngularWarpMethod = serializedObject.FindProperty("m_angularWarpMethod"); m_spLongErrorWarpType = serializedObject.FindProperty("m_longErrorWarpType"); m_spSpeedWarpLimits = serializedObject.FindProperty("m_speedWarpLimits"); m_spBlendOutEarly = serializedObject.FindProperty("m_blendOutEarly"); m_spPoseMatchMethod = serializedObject.FindProperty("m_poseMatchMethod"); m_spFavourTagMethod = serializedObject.FindProperty("m_favourTagMethod"); m_spPastTrajectoryMode = serializedObject.FindProperty("m_pastTrajectoryMode"); m_spAngularErrorWarpRate = serializedObject.FindProperty("m_angularErrorWarpRate"); m_spAngularErrorWarpThreshold = serializedObject.FindProperty("m_angularErrorWarpThreshold"); m_spAngularErrorWarpAngleThreshold = serializedObject.FindProperty("m_angularErrorWarpAngleThreshold"); m_spAngularErrorWarpMinAngleThreshold = serializedObject.FindProperty("m_angularErrorWarpMinAngleThreshold"); m_spApplyTrajectoryBlending = serializedObject.FindProperty("m_applyTrajectoryBlending"); m_spTrajectoryBlendingWeight = serializedObject.FindProperty("m_trajectoryBlendingWeight"); m_spFavourCurrentPose = serializedObject.FindProperty("m_favourCurrentPose"); m_spTransformGoal = serializedObject.FindProperty("m_transformGoal"); m_spPoseFavourFactor = serializedObject.FindProperty("m_currentPoseFavour"); m_spBlendSpaceSmoothing = serializedObject.FindProperty("m_blendSpaceSmoothing"); m_spBlendSpaceSmoothRate = serializedObject.FindProperty("m_blendSpaceSmoothRate"); m_spNextPoseToleranceTest = serializedObject.FindProperty("m_nextPoseToleranceTest"); m_spNextPoseToleranceDist = serializedObject.FindProperty("m_nextPoseToleranceDist"); m_spNextPoseToleranceAngle = serializedObject.FindProperty("m_nextPoseToleranceAngle"); m_spOnSetupCompleteCallback = serializedObject.FindProperty("m_onSetupComplete"); m_spOnIdleTriggeredCallback = serializedObject.FindProperty("m_onIdleTriggered"); m_spOnLeftFootStepStartCallback = serializedObject.FindProperty("m_onLeftFootStepStart"); m_spOnRightFootStepStartCallback = serializedObject.FindProperty("m_onRightFootStepStart"); m_spOnEventCompleteCallback = serializedObject.FindProperty("m_onEventComplete"); m_spOnEventContactCallback = serializedObject.FindProperty("m_onEventContactReached"); m_spOnEventChangeStateCallback = serializedObject.FindProperty("m_onEventStateChanged"); m_spGeneralFoldout = serializedObject.FindProperty("m_generalFoldout"); m_spAnimDataFoldout = serializedObject.FindProperty("m_animDataFoldout"); m_spOptionsFoldout = serializedObject.FindProperty("m_optionsFoldout"); m_spWarpingFoldout = serializedObject.FindProperty("m_warpingFoldout"); m_spCallbackFoldout = serializedObject.FindProperty("m_debugFoldout"); m_spDebugFoldout = serializedObject.FindProperty("m_callbackFoldout"); if (m_spAnimData.arraySize == 0) m_spAnimData.InsertArrayElementAtIndex(0); if (m_spAnimData.arraySize > 0) { SerializedProperty spAnimData = m_spAnimData.GetArrayElementAtIndex(0); if (spAnimData != null) { m_animData = m_spAnimData.GetArrayElementAtIndex(0).objectReferenceValue as MxMAnimData; } } if (m_spDebugPoses.boolValue) m_animator.StartPoseDebug(m_spDebugAnimDataId.intValue); m_animDataReorderableList = new ReorderableList(serializedObject, m_spAnimData, true, true, true, true); m_animDataReorderableList.drawElementCallback = (Rect a_rect, int a_index, bool a_isActive, bool a_isFocused) => { var element = m_animDataReorderableList.serializedProperty.GetArrayElementAtIndex(a_index); EditorGUI.LabelField(new Rect(a_rect.x, a_rect.y, 100f, EditorGUIUtility.singleLineHeight), "Anim Data " + (a_index + 1).ToString()); EditorGUI.ObjectField(new Rect(a_rect.x + 100f, a_rect.y, EditorGUIUtility.currentViewWidth - 170f, EditorGUIUtility.singleLineHeight), element, new GUIContent("")); }; m_animDataReorderableList.drawHeaderCallback = (Rect a_rect) => { EditorGUI.LabelField(a_rect, "Anim Data"); }; m_animDataReorderableList.onRemoveCallback = (ReorderableList a_list) => { if(a_list.index >= 0 && a_list.index < a_list.serializedProperty.arraySize) { SerializedProperty spObject = a_list.serializedProperty.GetArrayElementAtIndex(a_list.index); if(spObject.objectReferenceValue != null) { spObject.objectReferenceValue = null; } } ReorderableList.defaultBehaviours.DoRemoveButton(a_list); }; serializedObject.ApplyModifiedProperties(); if(EditorApplication.isPlaying) SetDebuggerTarget(); EditorApplication.playModeStateChanged += OnPlayModeStateChanged; }
//============================================================================================ /** * @brief * *********************************************************************************************/ public override void OnInspectorGUI() { if (m_animData == null) { if (m_spAnimData.arraySize > 0) { SerializedProperty spAnimData = m_spAnimData.GetArrayElementAtIndex(0); if (spAnimData != null) { m_animData = m_spAnimData.GetArrayElementAtIndex(0).objectReferenceValue as MxMAnimData; } } } EditorGUILayout.LabelField(""); Rect lastRect = GUILayoutUtility.GetLastRect(); float curHeight = lastRect.y + 9f; curHeight = EditorUtil.EditorFunctions.DrawTitle("MxM Animator", curHeight); m_spGeneralFoldout.boolValue = EditorUtil.EditorFunctions.DrawFoldout("General", curHeight, EditorGUIUtility.currentViewWidth, m_spGeneralFoldout.boolValue); if (m_spGeneralFoldout.boolValue) { EditorGUILayout.Slider(m_spPlaybackSpeed, 0f, 3f, new GUIContent("PlaybackSpeed")); EditorGUI.BeginChangeCheck(); m_spPlaybackSpeedSmoothRate.floatValue = EditorGUILayout.FloatField(new GUIContent("Playback Smooth Rate"), m_spPlaybackSpeedSmoothRate.floatValue); if(EditorGUI.EndChangeCheck()) { if (m_spPlaybackSpeedSmoothRate.floatValue <= 0.01f) m_spPlaybackSpeedSmoothRate.floatValue = 0.01f; } m_spMaxMixCount.intValue = EditorGUILayout.IntField("Max Blend Channels", m_spMaxMixCount.intValue); EditorGUI.BeginChangeCheck(); float updateRate = EditorGUILayout.Slider(new GUIContent("Update Rate (Hz)", "The rate at which motion matching searches take place (not the FPS!)"), 1f / m_spUpdateInterval.floatValue, 1f, 144f); if(EditorGUI.EndChangeCheck()) { m_spUpdateInterval.floatValue = 1f / updateRate; } EditorGUILayout.Slider(m_spMatchBlendTime, 0f, 2f, new GUIContent("Blend Time")); EditorGUILayout.Slider(m_spTurnInPlaceThreshold, 0f, 180f, new GUIContent("Turn in place threshold")); curHeight += 18f * 10f; } curHeight += 30f; GUILayout.Space(3f); m_spAnimDataFoldout.boolValue = EditorUtil.EditorFunctions.DrawFoldout("Animation Data", curHeight, EditorGUIUtility.currentViewWidth, m_spAnimDataFoldout.boolValue); bool greyOutData = false; if (m_spAnimDataFoldout.boolValue) { m_animDataReorderableList.DoLayoutList(); GUIStyle redBoldStyle = new GUIStyle(GUI.skin.label); redBoldStyle.fontStyle = FontStyle.Bold; redBoldStyle.normal.textColor = Color.red; for (int i=0; i < m_spAnimData.arraySize; ++i) { SerializedProperty spAnimData = m_spAnimData.GetArrayElementAtIndex(i); if(spAnimData.objectReferenceValue == null) { EditorGUILayout.LabelField("You have NULL anim data in the list. Please remove or fill the null entry in the list.", redBoldStyle); curHeight += 18f; greyOutData = true; } } if (m_spAnimData.arraySize == 0) { EditorGUILayout.LabelField("Please add anim data into the list above.", redBoldStyle); curHeight += 18f; greyOutData = false; } } curHeight += 31f; GUILayout.Space(3f); if (greyOutData) { GUI.enabled = false; } m_spOptionsFoldout.boolValue = EditorUtil.EditorFunctions.DrawFoldout("Options", curHeight, EditorGUIUtility.currentViewWidth, m_spOptionsFoldout.boolValue); if (m_spOptionsFoldout.boolValue) { EditorGUILayout.ObjectField(m_spAnimationRootOverride, typeof(Transform), new GUIContent("Animation Root Override", "The root transform for animation. Leaveing this blank will use the transform of the MxMAnimator.")); EditorGUILayout.ObjectField(m_spAnimatorControllerMask, typeof(AvatarMask), new GUIContent("Controller Mask", "The mask that is placed here will be applied to the mecanim animator controller if you are using one.")); GUILayout.Space(10f); curHeight += 10f; m_spPoseMatchMethod.enumValueIndex = (int)(EPoseMatchMethod)EditorGUILayout.EnumPopup(new GUIContent( "Pose Match Method", "The method to use for pose matching"), (EPoseMatchMethod)m_spPoseMatchMethod.enumValueIndex); m_spFavourTagMethod.enumValueIndex = (int)(EFavourTagMethod)EditorGUILayout.EnumPopup(new GUIContent( "Favour Tag Method", "The method to process favour tags with"), (EFavourTagMethod)m_spFavourTagMethod.enumValueIndex); m_spRootMotionMode.enumValueIndex = (int)(EMxMRootMotion)EditorGUILayout.EnumPopup(new GUIContent( "Root Motion", "How to handle root motion"), (EMxMRootMotion)m_spRootMotionMode.enumValueIndex); m_spPastTrajectoryMode.intValue = (int)(EPastTrajectoryMode)EditorGUILayout.EnumPopup( "Past Trajectory Mode", (EPastTrajectoryMode)m_spPastTrajectoryMode.intValue); m_spBlendSpaceSmoothing.enumValueIndex = (int)(EBlendSpaceSmoothing)EditorGUILayout.EnumPopup( new GUIContent("Blend Space Smoothing", "How blend space smoothing should operate"), (EBlendSpaceSmoothing)m_spBlendSpaceSmoothing.enumValueIndex); switch (m_spBlendSpaceSmoothing.intValue) { case (int)EBlendSpaceSmoothing.Lerp: { EditorGUILayout.BeginHorizontal(); GUILayout.Space(15f); EditorGUI.BeginChangeCheck(); float smoothRate = EditorGUILayout.FloatField(new GUIContent("Smooth Rate"), m_spBlendSpaceSmoothRate.vector2Value.x); if(EditorGUI.EndChangeCheck()) { m_spBlendSpaceSmoothRate.vector2Value = new Vector2(smoothRate, smoothRate); } EditorGUILayout.EndHorizontal(); curHeight += 18f; } break; case (int)EBlendSpaceSmoothing.Lerp2D: { EditorGUILayout.BeginHorizontal(); GUILayout.Space(15f); m_spBlendSpaceSmoothRate.vector2Value = EditorGUILayout.Vector2Field(new GUIContent("Smooth Rate"), m_spBlendSpaceSmoothRate.vector2Value); EditorGUILayout.EndHorizontal(); } break; } EditorGUI.BeginChangeCheck(); m_spTransitionMethod.intValue = (int)(ETransitionMethod)EditorGUILayout.EnumPopup( "Transition Method", (ETransitionMethod)m_spTransitionMethod.intValue); if (EditorGUI.EndChangeCheck()) { if (m_spTransitionMethod.intValue == (int)ETransitionMethod.None) m_spBlendOutEarly.boolValue = false; } EditorGUILayout.BeginHorizontal(); GUILayout.Space(15f); if (m_spTransitionMethod.intValue == (int)ETransitionMethod.Blend) { m_spBlendOutEarly.boolValue = EditorGUILayout.Toggle(new GUIContent("Blend Out Early", "If true, animations will be " + "forced to change and blend out before they reach their end."), m_spBlendOutEarly.boolValue); curHeight += 18f; } EditorGUILayout.EndHorizontal(); GUILayout.Space(10f); curHeight += 10f; m_spTransformGoal.boolValue = EditorGUILayout.Toggle(new GUIContent("Transorm Goal"), m_spTransformGoal.boolValue); //m_spApplyBlending.boolValue = EditorGUILayout.Toggle(new GUIContent("Apply Blending"), m_spApplyBlending.boolValue); m_spApplyTrajectoryBlending.boolValue = EditorGUILayout.Toggle(new GUIContent("Apply Trajectory Blending"), m_spApplyTrajectoryBlending.boolValue); if(m_spApplyTrajectoryBlending.boolValue) { EditorGUILayout.BeginHorizontal(); GUILayout.Space(15f); m_spTrajectoryBlendingWeight.floatValue = EditorGUILayout.FloatField("Trajectory Blend Weight", m_spTrajectoryBlendingWeight.floatValue); EditorGUILayout.EndHorizontal(); curHeight += 18f; } m_spFavourCurrentPose.boolValue = EditorGUILayout.Toggle( new GUIContent("Favour Current Pose"), m_spFavourCurrentPose.boolValue); if (m_spFavourCurrentPose.boolValue) { EditorGUILayout.BeginHorizontal(); GUILayout.Space(15f); m_spPoseFavourFactor.floatValue = EditorGUILayout.FloatField( new GUIContent("Pose Favour Factor"), m_spPoseFavourFactor.floatValue); EditorGUILayout.EndHorizontal(); curHeight += 18f; } m_spNextPoseToleranceTest.boolValue = EditorGUILayout.Toggle(new GUIContent("Next Pose Tolerance Test"), m_spNextPoseToleranceTest.boolValue); if (m_spNextPoseToleranceTest.boolValue) { EditorGUILayout.BeginHorizontal(); GUILayout.Space(15f); EditorGUILayout.BeginVertical(); m_spNextPoseToleranceDist.floatValue = EditorGUILayout.FloatField("Distance Tolerance", m_spNextPoseToleranceDist.floatValue); m_spNextPoseToleranceAngle.floatValue = EditorGUILayout.FloatField("Angular Tolerance", m_spNextPoseToleranceAngle.floatValue); EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); curHeight += 18f * 2f; } m_spDIYPlayableGraph.boolValue = EditorGUILayout.Toggle(new GUIContent("DIY Playable Graph"), m_spDIYPlayableGraph.boolValue); if (m_spDIYPlayableGraph.boolValue) { EditorGUILayout.BeginHorizontal(); GUILayout.Space(15f); m_spAutoCreateAnimatorController.boolValue = EditorGUILayout.Toggle( new GUIContent("Auto Create Controller"), m_spAutoCreateAnimatorController.boolValue); EditorGUILayout.EndHorizontal(); curHeight += 18f; } GUILayout.Space(5f); curHeight += 18 * 13f + 5f; } curHeight += 30f; GUILayout.Space(2f); m_spWarpingFoldout.boolValue = EditorUtil.EditorFunctions.DrawFoldout("Warping", curHeight, EditorGUIUtility.currentViewWidth, m_spWarpingFoldout.boolValue); if (m_spWarpingFoldout.boolValue) { m_spAngularWarpType.intValue = (int)(EAngularErrorWarp)EditorGUILayout.EnumPopup( "Angular Error Warping", (EAngularErrorWarp)m_spAngularWarpType.intValue); if (m_spAngularWarpType.intValue > 0) { EditorGUILayout.BeginHorizontal(); GUILayout.Space(15f); m_spAngularWarpMethod.intValue = (int)(EAngularErrorWarpMethod)EditorGUILayout.EnumPopup( "Warp Method", (EAngularErrorWarpMethod)m_spAngularWarpMethod.intValue); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Space(15f); m_spAngularErrorWarpRate.floatValue = EditorGUILayout.FloatField(new GUIContent("Warp Rate", "How fast the error will be warped for in 'degrees per second'."), m_spAngularErrorWarpRate.floatValue); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Space(15f); m_spAngularErrorWarpThreshold.floatValue = EditorGUILayout.FloatField(new GUIContent("Distance Threshold", "Discrepancy compensation will not activate unless the final trajectory point is greater than this value"), m_spAngularErrorWarpThreshold.floatValue); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Space(15f); Vector2 angularErrorWarpRange = new Vector2(m_spAngularErrorWarpMinAngleThreshold.floatValue, m_spAngularErrorWarpAngleThreshold.floatValue); EditorGUI.BeginChangeCheck(); angularErrorWarpRange = EditorGUILayout.Vector2Field(new GUIContent("Angle Range", "The minimum and maximum angle underwhich angular error warping will be activated (degrees)."), angularErrorWarpRange); if(EditorGUI.EndChangeCheck()) { m_spAngularErrorWarpAngleThreshold.floatValue = angularErrorWarpRange.y; m_spAngularErrorWarpMinAngleThreshold.floatValue = angularErrorWarpRange.x; } EditorGUILayout.EndHorizontal(); curHeight += 18f * 3f; } GUILayout.Space(10f); curHeight += 10f; m_spLongErrorWarpType.intValue = (int)(ELongitudinalErrorWarp)EditorGUILayout.EnumPopup( "Longitudinal Error Warping", (ELongitudinalErrorWarp)m_spLongErrorWarpType.intValue); if (m_spLongErrorWarpType.intValue > 0) { EditorGUILayout.BeginHorizontal(); GUILayout.Space(15f); EditorGUI.BeginChangeCheck(); if (m_spLongErrorWarpType.intValue == 1) { m_spSpeedWarpLimits.vector2Value = EditorGUILayout.Vector2Field( "Speed Warp Limits", m_spSpeedWarpLimits.vector2Value); if (EditorGUI.EndChangeCheck()) { if (m_spSpeedWarpLimits.vector2Value.x > m_spSpeedWarpLimits.vector2Value.y) { m_spSpeedWarpLimits.vector2Value = new Vector2(m_spSpeedWarpLimits.vector2Value.y, m_spSpeedWarpLimits.vector2Value.y); } } } else { GUIStyle redBoldStyle = new GUIStyle(GUI.skin.label); redBoldStyle.fontStyle = FontStyle.Bold; redBoldStyle.normal.textColor = Color.red; EditorGUILayout.LabelField("Check Stride Warper Component Attached", redBoldStyle); } EditorGUILayout.EndHorizontal(); } GUILayout.Space(5f); curHeight += 5f; } curHeight += 30f; GUILayout.Space(2f); m_spDebugFoldout.boolValue = EditorUtil.EditorFunctions.DrawFoldout("Debug", curHeight, EditorGUIUtility.currentViewWidth, m_spDebugFoldout.boolValue); if (m_spDebugFoldout.boolValue) { m_spDebugGoal.boolValue = EditorGUILayout.Toggle(new GUIContent("Debug Goal"), m_spDebugGoal.boolValue); m_spDebugChosenTrajectory.boolValue = EditorGUILayout.Toggle(new GUIContent("Debug AnimTrajectory"), m_spDebugChosenTrajectory.boolValue); m_spDebugCurrentPose.boolValue = EditorGUILayout.Toggle(new GUIContent("Debug Current Pose"), m_spDebugCurrentPose.boolValue); if (!Application.IsPlaying(m_animator)) { EditorGUI.BeginChangeCheck(); m_spDebugPoses.boolValue = EditorGUILayout.Toggle(new GUIContent("Debug Poses In Editor"), m_spDebugPoses.boolValue); if (EditorGUI.EndChangeCheck()) { if (m_spDebugPoses.boolValue) m_animator.StartPoseDebug(m_spDebugAnimDataId.intValue); else m_animator.StopPoseDebug(); } } if (m_spDebugPoses.boolValue) { EditorGUILayout.BeginHorizontal(); GUILayout.Space(15f); EditorGUI.BeginChangeCheck(); m_spDebugAnimDataId.intValue = EditorGUILayout.IntField(new GUIContent("AnimData Id"), m_spDebugAnimDataId.intValue); if (EditorGUI.EndChangeCheck()) { if (m_spDebugAnimDataId.intValue < 0) m_spDebugAnimDataId.intValue = 0; if (m_spDebugAnimDataId.intValue >= m_spAnimData.arraySize - 1) m_spDebugAnimDataId.intValue = m_spAnimData.arraySize - 2; m_animator.StopPoseDebug(); m_animator.StartPoseDebug(m_spDebugAnimDataId.intValue); } EditorGUILayout.EndHorizontal(); if (m_spDebugAnimDataId.intValue < m_spAnimData.arraySize - 1) { m_animData = m_spAnimData.GetArrayElementAtIndex(m_spDebugAnimDataId.intValue).objectReferenceValue as MxMAnimData; } EditorGUILayout.BeginHorizontal(); GUILayout.Space(15f); m_spDebugPoseId.intValue = EditorGUILayout.IntField(new GUIContent("Pose Id"), m_spDebugPoseId.intValue); EditorGUILayout.EndHorizontal(); if (m_spDebugPoseId.intValue < 0) m_spDebugPoseId.intValue = 0; if (m_spDebugPoseId.intValue >= m_animData.Poses.Length) m_spDebugPoseId.intValue = m_animData.Poses.Length - 1; EditorGUILayout.BeginHorizontal(); GUILayout.Space(15f); PoseData curPose = m_animData.Poses[m_spDebugPoseId.intValue]; EditorGUILayout.LabelField(m_animData.Clips[curPose.PrimaryClipId].name); if (GUILayout.Button("Back")) { m_spDebugPoseId.intValue -= 1; if (m_spDebugPoseId.intValue < 0) m_spDebugPoseId.intValue = 0; } if (GUILayout.Button("Next")) { m_spDebugPoseId.intValue += 1; if (m_spDebugPoseId.intValue >= m_animData.Poses.Length) m_spDebugPoseId.intValue = m_animData.Poses.Length - 1; } EditorGUILayout.EndHorizontal(); curHeight += 36f; } if(GUILayout.Button("OpenDebugWindow")) { MxMDebuggerWindow.SetTarget(m_animator); MxMDebuggerWindow.ShowWindow(); } if (Application.IsPlaying(m_animator)) { string pauseString = "Pause"; if (m_animator.IsPaused) pauseString = "UnPause"; if (GUILayout.Button(new GUIContent(pauseString))) { m_animator.TogglePause(); } } if (GUILayout.Button(new GUIContent("Strip Pose Masks"))) { if (EditorUtility.DisplayDialog("Strip Pose Masks", "Are you sure you want to delete all pose masks attached " + "to animData in this Animator? This is irreversible.", "Yes", "No")) { m_animator.ClearPoseMask(); } } } lastRect = GUILayoutUtility.GetLastRect(); curHeight = lastRect.y + lastRect.height + 5f; GUILayout.Space(5f); m_spCallbackFoldout.boolValue = EditorUtil.EditorFunctions.DrawFoldout("Callbacks", curHeight, EditorGUIUtility.currentViewWidth, m_spCallbackFoldout.boolValue); if (m_spCallbackFoldout.boolValue) { EditorGUILayout.PropertyField(m_spOnSetupCompleteCallback); EditorGUILayout.PropertyField(m_spOnIdleTriggeredCallback); EditorGUILayout.PropertyField(m_spOnLeftFootStepStartCallback); EditorGUILayout.PropertyField(m_spOnRightFootStepStartCallback); EditorGUILayout.PropertyField(m_spOnEventCompleteCallback); EditorGUILayout.PropertyField(m_spOnEventContactCallback); EditorGUILayout.PropertyField(m_spOnEventChangeStateCallback); } if (m_spAnimData.arraySize <= 1 || m_spAnimData.GetArrayElementAtIndex(0).objectReferenceValue == null) { GUI.enabled = true; } serializedObject.ApplyModifiedProperties(); }
public override void OnInspectorGUI() { EditorGUILayout.LabelField(""); Rect lastRect = GUILayoutUtility.GetLastRect(); float curHeight = lastRect.y + 9f; curHeight = EditorUtil.EditorFunctions.DrawTitle("MxM Animation Data", curHeight); m_generalFoldout = EditorUtil.EditorFunctions.DrawFoldout("General", curHeight, EditorGUIUtility.currentViewWidth, m_generalFoldout); if (m_generalFoldout) { EditorGUI.BeginChangeCheck(); m_spStartPoseId.intValue = EditorGUILayout.IntField("Start Pose Id: ", m_spStartPoseId.intValue); if (EditorGUI.EndChangeCheck()) { if (m_spStartPoseId.intValue < 0) { m_spStartPoseId.intValue = 0; } if (m_spStartPoseId.intValue >= m_animData.Poses.Length) { m_spStartPoseId.intValue = m_animData.Poses.Length - 1; } } EditorGUILayout.LabelField("Pose Interval: " + m_animData.PoseInterval + " seconds"); EditorGUILayout.LabelField("Clip Count: " + m_animData.Clips.Length); EditorGUILayout.LabelField("Pose Count: " + m_animData.Poses.Length); EditorGUILayout.LabelField("Event Count: " + m_animData.Events.Length); GUILayout.Space(9f); EditorGUILayout.LabelField("Complex Anims:", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); GUILayout.Space(20f); EditorGUILayout.BeginVertical(); { EditorGUILayout.LabelField("Single Composite Count " + m_animData.ClipsData.Length); EditorGUILayout.LabelField("Spliced Composite Count " + m_animData.Composites.Length); EditorGUILayout.LabelField("IdleSet Count: " + m_animData.IdleSets.Length); EditorGUILayout.LabelField("BlendSpace Count: " + m_animData.BlendSpaces.Length); EditorGUILayout.LabelField("BlendClip Count: " + m_animData.BlendClips.Length); } EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); GUILayout.Space(9f); EditorGUILayout.LabelField("Match Joints:", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); GUILayout.Space(20f); EditorGUILayout.BeginVertical(); if (m_animData.GetBonesByName) { for (int i = 0; i < m_animData.MatchBonesGeneric.Length; ++i) { EditorGUILayout.LabelField((i + 1) + ". " + m_animData.MatchBonesGeneric[i]); curHeight += 18f; } } else { for (int i = 0; i < m_animData.MatchBones.Length; ++i) { EditorGUILayout.LabelField((i + 1) + ". " + m_animData.MatchBones[i].ToString()); curHeight += 18f; } } EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); GUILayout.Space(9f); EditorGUILayout.LabelField("Trajectory Points:", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); GUILayout.Space(20f); EditorGUILayout.BeginVertical(); for (int i = 0; i < m_animData.PosePredictionTimes.Length; ++i) { EditorGUILayout.LabelField("Point " + i + ": " + m_animData.PosePredictionTimes[i].ToString()); curHeight += 18f; } EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); curHeight += 18f * 8f + 1f; } curHeight += 30f; GUILayout.Space(3f); m_animClipsFoldout = EditorUtil.EditorFunctions.DrawFoldout("Animation Clips", curHeight, EditorGUIUtility.currentViewWidth, m_animClipsFoldout); if (m_animClipsFoldout) { EditorGUI.BeginDisabledGroup(true); for (int i = 0; i < m_spAnimClipList.arraySize; ++i) { EditorGUILayout.ObjectField(m_spAnimClipList.GetArrayElementAtIndex(i), new GUIContent("Clip " + i)); curHeight += 18f; } EditorGUI.EndDisabledGroup(); } curHeight += 30f; GUILayout.Space(3f); m_calibrationFoldout = EditorUtil.EditorFunctions.DrawFoldout("Calibration Sets", curHeight, EditorGUIUtility.currentViewWidth, m_calibrationFoldout); curHeight += 28f; if (m_calibrationFoldout) { for (int i = 0; i < m_spCalibrationSets.arraySize; ++i) { SerializedProperty spCalibData = m_spCalibrationSets.GetArrayElementAtIndex(i); SerializedProperty spCalibrationName = spCalibData.FindPropertyRelative("CalibrationName"); m_calibDataFoldouts[i] = EditorUtil.EditorFunctions.DrawFoldout(spCalibrationName.stringValue, curHeight, EditorGUIUtility.currentViewWidth, m_calibDataFoldouts[i], 1, true); curHeight += 24f; if (m_calibDataFoldouts[i]) { MxMAnimData animData = target as MxMAnimData; SerializedProperty spPoseTrajectoryRatio = spCalibData.FindPropertyRelative("PoseTrajectoryRatio"); SerializedProperty spPoseVelocityWeight = spCalibData.FindPropertyRelative("PoseVelocityWeight"); SerializedProperty spPoseAspectMultiplier = spCalibData.FindPropertyRelative("PoseAspectMultiplier"); SerializedProperty spPoseResultantVelocityMultiplier = spCalibData.FindPropertyRelative("PoseResultantVelocityMultiplier"); SerializedProperty spTrajPosMultiplier = spCalibData.FindPropertyRelative("TrajPosMultiplier"); SerializedProperty spTrajFAngleMultiplier = spCalibData.FindPropertyRelative("TrajFAngleMultiplier"); SerializedProperty spJointPositionWeights = spCalibData.FindPropertyRelative("JointPositionWeights"); SerializedProperty spJointVelocityWeights = spCalibData.FindPropertyRelative("JointVelocityWeights"); spCalibrationName.stringValue = EditorGUILayout.TextField(new GUIContent("Name"), spCalibrationName.stringValue); if (GUILayout.Button(new GUIContent("Delete"))) { if (EditorUtility.DisplayDialog("Delete Calibration Data", "Are you sure you want to delete calibration data?", "Yes", "No")) { m_spCalibrationSets.DeleteArrayElementAtIndex(i); --i; Repaint(); continue; } } EditorGUILayout.Slider(spPoseTrajectoryRatio, 0f, 1f, m_poseTrajGUIContent); GUILayout.Space(5f); EditorGUILayout.LabelField(new GUIContent("Pose", "Contains all weightings related to pose"), EditorStyles.boldLabel); spPoseVelocityWeight.floatValue = EditorGUILayout.FloatField(m_bodyVelocityWeightGUIContent, spPoseVelocityWeight.floatValue); spPoseAspectMultiplier.floatValue = EditorGUILayout.FloatField(m_poseWeightGUIContent, spPoseAspectMultiplier.floatValue); spPoseResultantVelocityMultiplier.floatValue = EditorGUILayout.FloatField(m_resultantVelocityCostingGUIContent, spPoseResultantVelocityMultiplier.floatValue); EditorGUILayout.BeginHorizontal(); GUILayout.Space(10f); EditorGUILayout.LabelField("Joints:", EditorStyles.boldLabel); EditorGUILayout.EndHorizontal(); for (int n = 0; n < spJointPositionWeights.arraySize; ++n) { SerializedProperty spJointPositionWeight = spJointPositionWeights.GetArrayElementAtIndex(n); SerializedProperty spJointVelocityWeight = spJointVelocityWeights.GetArrayElementAtIndex(n); EditorGUILayout.BeginHorizontal(); GUILayout.Space(10f); string boneName = ""; if (m_animData.GetBonesByName) { boneName = animData.MatchBonesGeneric[n]; } else { boneName = animData.MatchBones[n].ToString(); } spJointPositionWeight.floatValue = EditorGUILayout.FloatField(new GUIContent( boneName + " Position", m_jointPosTooltip), spJointPositionWeight.floatValue); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Space(10f); spJointVelocityWeight.floatValue = EditorGUILayout.FloatField(new GUIContent( boneName + " Velocity", m_jointVelTooltip), spJointVelocityWeight.floatValue); EditorGUILayout.EndHorizontal(); curHeight += 18f * 2f; } GUILayout.Space(5f); EditorGUILayout.LabelField(new GUIContent("Trajectory: ", "Contains all weighting related to trajectory"), EditorStyles.boldLabel); spTrajPosMultiplier.floatValue = EditorGUILayout.FloatField(m_trajPosWeightGUIContent, spTrajPosMultiplier.floatValue); spTrajFAngleMultiplier.floatValue = EditorGUILayout.FloatField(m_trajDirWeightGUIContent, spTrajFAngleMultiplier.floatValue); curHeight += 18f * 11f; curHeight += 15f + 10f; GUILayout.Space(10f); } } if (GUILayout.Button(new GUIContent("Add New Calibration"))) { if (m_animData != null) { m_spCalibrationSets.InsertArrayElementAtIndex(m_spCalibrationSets.arraySize); SerializedProperty spCalibData = m_spCalibrationSets.GetArrayElementAtIndex(m_spCalibrationSets.arraySize - 1); SerializedProperty spCalibrationName = spCalibData.FindPropertyRelative("CalibrationName"); spCalibrationName.stringValue = "Calibration " + (m_spCalibrationSets.arraySize - 1); SerializedProperty spPoseTrajectoryRatio = spCalibData.FindPropertyRelative("PoseTrajectoryRatio"); SerializedProperty spPoseVelocityWeight = spCalibData.FindPropertyRelative("PoseVelocityWeight"); SerializedProperty spPoseAspectMultiplier = spCalibData.FindPropertyRelative("PoseAspectMultiplier"); SerializedProperty spTrajPosMultiplier = spCalibData.FindPropertyRelative("TrajPosMultiplier"); SerializedProperty spTrajFAngleMultiplier = spCalibData.FindPropertyRelative("TrajFAngleMultiplier"); SerializedProperty spJointPositionWeights = spCalibData.FindPropertyRelative("JointPositionWeights"); SerializedProperty spJointVelocityWeights = spCalibData.FindPropertyRelative("JointVelocityWeights"); spPoseTrajectoryRatio.floatValue = 0.6f; spPoseAspectMultiplier.floatValue = 1f; spPoseVelocityWeight.floatValue = 3f; spTrajPosMultiplier.floatValue = 5f; spTrajFAngleMultiplier.floatValue = 0.04f; spJointPositionWeights.ClearArray(); spJointVelocityWeights.ClearArray(); for (int k = 0; k < m_animData.MatchBones.Length; ++k) { spJointPositionWeights.InsertArrayElementAtIndex(k); spJointPositionWeights.GetArrayElementAtIndex(k).floatValue = 1f; spJointVelocityWeights.InsertArrayElementAtIndex(k); spJointVelocityWeights.GetArrayElementAtIndex(k).floatValue = 3f; } m_calibDataFoldouts.Add(true); } } curHeight += 22f; } curHeight += 1f; GUILayout.Space(2f); m_poseMaskFoldout = EditorUtil.EditorFunctions.DrawFoldout("Pose Mask", curHeight, EditorGUIUtility.currentViewWidth, m_poseMaskFoldout); if (m_poseMaskFoldout) { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.ObjectField(m_spPoseMask, new GUIContent("Pose Mask")); EditorGUI.EndDisabledGroup(); if (GUILayout.Button(new GUIContent("Strip Pose Mask"))) { if (EditorUtility.DisplayDialog("Srip Pose Mask", "Are you sure you want to strip the pose mask? " + "This operation cannot be reversed", "Yes", "No")) { m_animData.StripPoseMask(); } } curHeight += 18f * 2f; } serializedObject.ApplyModifiedProperties(); }
public override void OnInspectorGUI() { EditorGUILayout.LabelField(""); Rect lastRect = GUILayoutUtility.GetLastRect(); float curHeight = lastRect.y + 9f; curHeight = EditorUtil.EditorFunctions.DrawTitle("MxM Event Definition", curHeight); m_generalFoldout = EditorUtil.EditorFunctions.DrawFoldout("General", curHeight, EditorGUIUtility.currentViewWidth, m_generalFoldout); if (m_generalFoldout) { MxMAnimData animData = m_spTargetAnimData.objectReferenceValue as MxMAnimData; if (animData != null) { EditorGUI.BeginChangeCheck(); m_spId.intValue = EditorGUILayout.Popup("Event Name", m_spId.intValue, animData.EventNames); if (EditorGUI.EndChangeCheck()) { if (m_spId.intValue > -1 && m_spId.intValue < animData.EventNames.Length) { m_spEventName.stringValue = animData.EventNames[m_spId.intValue]; } } } else { EditorGUI.BeginChangeCheck(); m_spId.intValue = EditorGUILayout.IntField("Event Id", m_spId.intValue); if (EditorGUI.EndChangeCheck()) { if (m_spId.intValue < 0) { m_spId.intValue = 0; } } } m_spEventType.intValue = (int)(EMxMEventType)EditorGUILayout.EnumPopup("Event Type", (EMxMEventType)m_spEventType.intValue); EditorGUI.BeginChangeCheck(); m_spPriority.intValue = EditorGUILayout.IntField("Priority", m_spPriority.intValue); if (EditorGUI.EndChangeCheck()) { if (m_spPriority.intValue < -1) { m_spPriority.intValue = -1; } } EditorGUI.BeginChangeCheck(); m_spContactCountToMatch.intValue = EditorGUILayout.IntField("Num Contacts to Match", m_spContactCountToMatch.intValue); if (EditorGUI.EndChangeCheck()) { if (m_spContactCountToMatch.intValue < 0) { m_spContactCountToMatch.intValue = 0; } } EditorGUI.BeginChangeCheck(); m_spContactCountToWarp.intValue = EditorGUILayout.IntField("Num Contacts to Warp", m_spContactCountToWarp.intValue); if (EditorGUI.EndChangeCheck()) { if (m_spContactCountToWarp.intValue < 0) { m_spContactCountToWarp.intValue = 0; } } m_spExitWithMotion.boolValue = EditorGUILayout.Toggle("Exit With Motion", m_spExitWithMotion.boolValue); m_spMatchPose.boolValue = EditorGUILayout.Toggle("Match Pose", m_spMatchPose.boolValue); m_spMatchTrajectory.boolValue = EditorGUILayout.Toggle("Match Trajectory", m_spMatchTrajectory.boolValue); m_spPostEventTrajectoryMode.intValue = (int)(EPostEventTrajectoryMode)EditorGUILayout.EnumPopup( "Post Event Trajectory Mode", (EPostEventTrajectoryMode)m_spPostEventTrajectoryMode.intValue); EditorGUI.BeginChangeCheck(); EditorGUILayout.ObjectField(m_spTargetAnimData, typeof(MxMAnimData), new GUIContent("Ref AnimData")); if (EditorGUI.EndChangeCheck()) { animData = m_spTargetAnimData.objectReferenceValue as MxMAnimData; if (animData != null) { (target as MxMEventDefinition).ValidateEventId(); } } curHeight += 18f * 9f; } curHeight += 30f; GUILayout.Space(3f); m_timingFoldout = EditorUtil.EditorFunctions.DrawFoldout("Time Warping", curHeight, EditorGUIUtility.currentViewWidth, m_timingFoldout); if (m_timingFoldout) { EditorGUI.BeginChangeCheck(); m_spMatchTiming.boolValue = EditorGUILayout.Toggle("Match Timing", m_spMatchTiming.boolValue); if (EditorGUI.EndChangeCheck()) { if (m_spMatchTiming.boolValue) { m_spWarpTimeScaling.boolValue = false; } } m_spTimingWeight.floatValue = EditorGUILayout.FloatField("Timing Weight", m_spTimingWeight.floatValue); m_spTimingWarpType.intValue = (int)(EEventWarpType)EditorGUILayout.EnumPopup("Timing Warp Type", (EEventWarpType)m_spTimingWarpType.intValue); curHeight += 18f * 3f; } curHeight += 30f; GUILayout.Space(3f); m_positionFoldout = EditorUtil.EditorFunctions.DrawFoldout("Position Warping", curHeight, EditorGUIUtility.currentViewWidth, m_positionFoldout); if (m_positionFoldout) { m_spMatchPosition.boolValue = EditorGUILayout.Toggle("Match Position", m_spMatchPosition.boolValue); m_spPositionWeight.floatValue = EditorGUILayout.FloatField("Position Weight", m_spPositionWeight.floatValue); m_spMotionWarpType.intValue = (int)(EEventWarpType)EditorGUILayout.EnumPopup("Position Warp Type", (EEventWarpType)m_spMotionWarpType.intValue); EditorGUI.BeginChangeCheck(); m_spWarpTimeScaling.boolValue = EditorGUILayout.Toggle("Time Scaling", m_spWarpTimeScaling.boolValue); if (EditorGUI.EndChangeCheck()) { if (m_spWarpTimeScaling.boolValue) { m_spMatchTiming.boolValue = false; } } if (m_spWarpTimeScaling.boolValue) { EditorGUILayout.BeginHorizontal(); GUILayout.Space(20f); EditorGUILayout.BeginVertical(); m_spContactCountToTimeScale.intValue = EditorGUILayout.IntField("Contact Count", m_spContactCountToTimeScale.intValue); m_spMinWarpTimeScale.floatValue = EditorGUILayout.FloatField("Min", m_spMinWarpTimeScale.floatValue); m_spMaxWarpTimeScale.floatValue = EditorGUILayout.FloatField("Max", m_spMaxWarpTimeScale.floatValue); EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); curHeight += 18f * 3f; } curHeight += 18f * 4f; } curHeight += 30f; GUILayout.Space(3f); m_rotationFoldout = EditorUtil.EditorFunctions.DrawFoldout("Rotation Warping", curHeight, EditorGUIUtility.currentViewWidth, m_rotationFoldout); if (m_rotationFoldout) { m_spMatchRotation.boolValue = EditorGUILayout.Toggle("Match Rotation", m_spMatchRotation.boolValue); m_spRotationWeight.floatValue = EditorGUILayout.FloatField("Rotation Weight", m_spRotationWeight.floatValue); m_spRotationWarpType.intValue = (int)(EEventWarpType)EditorGUILayout.EnumPopup("Rotation Warp Type", (EEventWarpType)m_spRotationWarpType.intValue); curHeight += 18f * 3f; } curHeight += 30f; GUILayout.Space(3f); serializedObject.ApplyModifiedProperties(); }
private void OnEnable() { m_animData = target as MxMAnimData; m_spAnimClipList = serializedObject.FindProperty("Clips"); m_spCalibrationSets = serializedObject.FindProperty("CalibrationSets"); m_spPoseMask = serializedObject.FindProperty("poseMask"); m_spStartPoseId = serializedObject.FindProperty("StartPoseId"); if (m_calibDataFoldouts == null) { m_calibDataFoldouts = new List <bool>(m_spCalibrationSets.arraySize + 1); for (int i = 0; i < m_spCalibrationSets.arraySize; ++i) { m_calibDataFoldouts.Add(true); } } m_poseTrajGUIContent = new GUIContent("Pose-Traj Ratio", "A slider to balance the relationship between Pose Cost and Trajectory Cost. Setting the" + "value closer to '0' will make pose more weighted meaning more fluid motion. However, " + "values closer to '1' will make the trajectory more weighted meaning higher responsiveness." + "Treat this as a 'fluidity' - 'responsiveness' slider. User Manual: Section 6.3"); m_poseWeightGUIContent = new GUIContent("Pose Weight", "This is an overall multiplier to pose joint" + "costs both for position and velocity. Each joint's position and velocity weighting is multiplied by this value" + "before to get their final weightings. Essentially, higher values make the pose more important as " + "a whole excluding body velocity while lower values do the opposite. User Manual: Section 6.1"); m_bodyVelocityWeightGUIContent = new GUIContent("Body Velocity Weight", "For motion matching to work it is important" + "to match the overall body velocity to ensure it does not snap between different movement speeds too quickly. Higher" + "values for body velocity weighting will ensure more inertia is retained but it may be less responsive. " + "User Manual: Section 6.1"); m_resultantVelocityCostingGUIContent = new GUIContent("Resultant Velocity Weight", "MxM doesn't just compare the velocity between" + "pose joints. It also checks to see if the resulting velocity of a joint, if a certain pose is picked' will match closesly to " + "the current velocity. This stops animation running backwards. This weighting is a multiplier to those costs. It is a very sensitive" + "setting and it is recommended to keep it around a value of 0.1f - 0.3f. User Manual: Section 6.1 "); m_trajPosWeightGUIContent = new GUIContent("Position Weight", "This value determines the importance of the trajectory points' position" + "when comparing to the desired trajectory. Higher values will make the trajectory position more important making for more responsive" + "animation. Keep in mind this multiplier does not affect trajectory angle. Typically the trajectory should have a higher weighting than" + "pose joints, around 5 - 10 depending on your game. User Manual: Section 6.2"); m_trajDirWeightGUIContent = new GUIContent("Angle Weight", "This value determines the importance of the trajectory points' facing angle" + "when comparing to the desired trajectory. Higher values will make the trajectory facing angle more important ensuring that character" + "faces the direction you want them to face. This value does not affect trajectory position weighting. Facing angle differences are very " + "sensitive compared positions so a weighting around 0.03 - 0.1 is often used. User Manual: Section 6.2"); m_jointPosTooltip = "Importance of this joint's position for pose comparison. Values of '1' " + "make the joint position cost unchanged. Lesser values make the joint position less important and higher " + "values make the joint position more important. Keep in mind that joint velocity values are much higher than" + "position values. So to normalize them, position weightings generaly need to be lower than velocity values." + "User Manual: Section 6.1"; m_jointVelTooltip = "Importance of this joint's velocity for pose comparison. Values of '1' make the joint velocity" + "cost unchanged. Lesser values make the joint velocity less important and higher values make the joint velocity more" + "important. Keep in mind that joint velocity values are much higher than position values. So to normalize them, velocity" + "weighting generaly needs to be higher. User Manual: Section 6.1"; }