diff --git a/AnimationCurvePopupMenu/.gitignore b/AnimationCurvePopupMenu/.gitignore new file mode 100644 index 0000000..933a9f0 --- /dev/null +++ b/AnimationCurvePopupMenu/.gitignore @@ -0,0 +1,2 @@ +/Library/ +/Temp/ diff --git a/AnimationCurvePopupMenu/Assets/Editor.meta b/AnimationCurvePopupMenu/Assets/Editor.meta new file mode 100644 index 0000000..ed0d894 --- /dev/null +++ b/AnimationCurvePopupMenu/Assets/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 7e121d2db1b5f6a46a3a29ebffb3a894 +folderAsset: yes +timeCreated: 1467200556 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/AnimationCurvePopupMenu/Assets/Editor/AnimationCurveDrawer.cs b/AnimationCurvePopupMenu/Assets/Editor/AnimationCurveDrawer.cs new file mode 100644 index 0000000..a6d7e30 --- /dev/null +++ b/AnimationCurvePopupMenu/Assets/Editor/AnimationCurveDrawer.cs @@ -0,0 +1,11 @@ +using UnityEngine; +using UnityEditor; + +[CustomPropertyDrawer(typeof(AnimationCurve))] +public class AnimationCurveDrawer : PropertyDrawer +{ + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + AnimationCurveGUI.OnGUI(position, property, label); + } +} diff --git a/AnimationCurvePopupMenu/Assets/Editor/AnimationCurveDrawer.cs.meta b/AnimationCurvePopupMenu/Assets/Editor/AnimationCurveDrawer.cs.meta new file mode 100644 index 0000000..12671cd --- /dev/null +++ b/AnimationCurvePopupMenu/Assets/Editor/AnimationCurveDrawer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 51fc08f728922d94b804b10d0dddf893 +timeCreated: 1467200556 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AnimationCurvePopupMenu/Assets/Editor/AnimationCurveGUI.cs b/AnimationCurvePopupMenu/Assets/Editor/AnimationCurveGUI.cs new file mode 100644 index 0000000..dbd02f1 --- /dev/null +++ b/AnimationCurvePopupMenu/Assets/Editor/AnimationCurveGUI.cs @@ -0,0 +1,72 @@ +using UnityEngine; +using UnityEditor; + +public class AnimationCurveGUI +{ + private static Rect SubtractPopupWidth(Rect position) + { + position.width -= 18f; + return position; + } + + private static Rect GetPopupRect(Rect position) + { + position.xMin = position.xMax - 13f; + return position; + } + + #region EditorGUILayout + public static AnimationCurve CurveField(AnimationCurve value, params GUILayoutOption[] options) + { + Rect position = EditorGUILayout.GetControlRect(false, 16f, EditorStyles.colorField, options); + return CurveField(position, value); + } + + public static AnimationCurve CurveField(string label, AnimationCurve value, params GUILayoutOption[] options) + { + Rect position = EditorGUILayout.GetControlRect(true, 16f, EditorStyles.colorField, options); + return CurveField(position, label, value); + } + + public static AnimationCurve CurveField(GUIContent label, AnimationCurve value, params GUILayoutOption[] options) + { + Rect position = EditorGUILayout.GetControlRect(true, 16f, EditorStyles.colorField, options); + return CurveField(position, label, value); + } + #endregion + + #region EditorGUI + public static AnimationCurve CurveField(Rect position, AnimationCurve value) + { + AnimationCurve animationCurve = EditorGUI.CurveField(SubtractPopupWidth(position), value); + AnimationCurvePopupMenu.Show(GetPopupRect(position), animationCurve, null); + return animationCurve; + } + + public static AnimationCurve CurveField(Rect position, string label, AnimationCurve value) + { + return CurveField(position, new GUIContent(label), value); + } + + public static AnimationCurve CurveField(Rect position, GUIContent label, AnimationCurve value) + { + AnimationCurve animationCurve = EditorGUI.CurveField(SubtractPopupWidth(position), label, value); + AnimationCurvePopupMenu.Show(GetPopupRect(position), animationCurve, null); + return animationCurve; + } + #endregion + + /// + /// 默认属性字段的绘制,也会为PropertyField自动绘制 + /// + /// + /// + /// + public static void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + label = EditorGUI.BeginProperty(position, label, property); + EditorGUI.CurveField(EditorGUI.PrefixLabel(SubtractPopupWidth(position), label), property, Color.green, default(Rect)); + AnimationCurvePopupMenu.Show(GetPopupRect(position), null, property); + EditorGUI.EndProperty(); + } +} diff --git a/AnimationCurvePopupMenu/Assets/Editor/AnimationCurveGUI.cs.meta b/AnimationCurvePopupMenu/Assets/Editor/AnimationCurveGUI.cs.meta new file mode 100644 index 0000000..3066383 --- /dev/null +++ b/AnimationCurvePopupMenu/Assets/Editor/AnimationCurveGUI.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 677915183234a3c40bff720f40d27e22 +timeCreated: 1467200556 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AnimationCurvePopupMenu/Assets/Editor/AnimationCurvePopupMenu.cs b/AnimationCurvePopupMenu/Assets/Editor/AnimationCurvePopupMenu.cs new file mode 100644 index 0000000..1aac08e --- /dev/null +++ b/AnimationCurvePopupMenu/Assets/Editor/AnimationCurvePopupMenu.cs @@ -0,0 +1,118 @@ +using System; +using System.Reflection; +using UnityEngine; +using UnityEditor; +using UnityEditorInternal; + +public class AnimationCurvePopupMenu +{ + private static AnimationCurve s_ClipBoardAnimationCurve; + + public static void Show(Rect popupRect, AnimationCurve animationCurve, SerializedProperty property) + { + if (GUI.Button(popupRect, GUIContent.none, "ShurikenDropdown")) + { + GUIContent content = new GUIContent("Copy"); + GUIContent content2 = new GUIContent("Paste"); + GUIContent content3 = new GUIContent("Clear"); + GenericMenu genericMenu = new GenericMenu(); + + if (property != null) + { + genericMenu.AddItem(content, false, AnimationCurveCallbackCopy, property); + genericMenu.AddItem(content2, false, AnimationCurveCallbackPaste, property); + genericMenu.AddItem(content3, false, AnimationCurveCallbackClear, property); + } + else + { + genericMenu.AddItem(content, false, AnimationCurveCallback2Copy, animationCurve); + genericMenu.AddItem(content2, false, AnimationCurveCallback2Paste, animationCurve); + genericMenu.AddItem(content3, false, AnimationCurveCallback2Clear, animationCurve); + } + + if (!HasClipBoardAnimationCurve()) + { + genericMenu.AddDisabledItem(content2); + } + genericMenu.DropDown(popupRect); + Event.current.Use(); + } + } + + /// + /// 清除检视器界面的曲线缓存,才能刷新新的值 + /// + public static void AnimationCurvePreviewCacheClearCache() + { + Assembly assembly = Assembly.GetAssembly(typeof(ReorderableList)); + Type type = assembly.GetType("UnityEditorInternal.AnimationCurvePreviewCache"); + MethodInfo clearCache = type.GetMethod("ClearCache", BindingFlags.Static | BindingFlags.Public); + if (clearCache != null) + { + clearCache.Invoke(null, null); + } + } + + private static bool HasClipBoardAnimationCurve() + { + return s_ClipBoardAnimationCurve != null; + } + + private static void AnimationCurveCallbackCopy(object obj) + { + SerializedProperty property = (SerializedProperty)obj; + s_ClipBoardAnimationCurve = property.animationCurveValue; + } + + private static void AnimationCurveCallbackPaste(object obj) + { + if (s_ClipBoardAnimationCurve == null) + { + return; + } + SerializedProperty property = (SerializedProperty)obj; + property.serializedObject.Update(); + property.animationCurveValue = s_ClipBoardAnimationCurve; + property.serializedObject.ApplyModifiedProperties(); + } + + private static void AnimationCurveCallbackClear(object obj) + { + SerializedProperty property = (SerializedProperty)obj; + property.serializedObject.Update(); + property.animationCurveValue = new AnimationCurve(); + property.serializedObject.ApplyModifiedProperties(); + } + + private static void AnimationCurveCallback2Copy(object obj) + { + AnimationCurve animationCurve = (AnimationCurve)obj; + s_ClipBoardAnimationCurve = animationCurve; + } + + private static void AnimationCurveCallback2Paste(object obj) + { + if (s_ClipBoardAnimationCurve == null) + { + return; + } + AnimationCurve animationCurve = (AnimationCurve)obj; + animationCurve.keys = s_ClipBoardAnimationCurve.keys; + animationCurve.postWrapMode = s_ClipBoardAnimationCurve.postWrapMode; + animationCurve.preWrapMode = s_ClipBoardAnimationCurve.preWrapMode; + AnimationCurvePreviewCacheClearCache(); + } + + private static void AnimationCurveCallback2Clear(object obj) + { + AnimationCurve animationCurve = (AnimationCurve)obj; + if (animationCurve != null) + { + for (int i = animationCurve.length - 1; i >= 0; i--) + { + animationCurve.RemoveKey(i); + } + AnimationCurvePreviewCacheClearCache(); + } + } +} diff --git a/AnimationCurvePopupMenu/Assets/Editor/AnimationCurvePopupMenu.cs.meta b/AnimationCurvePopupMenu/Assets/Editor/AnimationCurvePopupMenu.cs.meta new file mode 100644 index 0000000..0397452 --- /dev/null +++ b/AnimationCurvePopupMenu/Assets/Editor/AnimationCurvePopupMenu.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a489e6d3b58df6a46bc47348469a40e5 +timeCreated: 1467200556 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AnimationCurvePopupMenu/Assets/Editor/TestCurveEditor.cs b/AnimationCurvePopupMenu/Assets/Editor/TestCurveEditor.cs new file mode 100644 index 0000000..4c5a9e6 --- /dev/null +++ b/AnimationCurvePopupMenu/Assets/Editor/TestCurveEditor.cs @@ -0,0 +1,32 @@ +using UnityEngine; +using UnityEditor; + +[CustomEditor(typeof(TestCurve))] +public class TestCurveEditor : Editor +{ + SerializedProperty curveProp; + SerializedProperty curveProp2; + private AnimationCurve m_TestAnimCurve = new AnimationCurve(); + private AnimationCurve m_TestAnimCurve2 = new AnimationCurve(); + + void OnEnable() + { + curveProp = serializedObject.FindProperty("curve"); + curveProp2 = serializedObject.FindProperty("curve2"); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + EditorGUILayout.PropertyField(curveProp); + EditorGUILayout.PropertyField(curveProp2, new GUIContent("Curve2 Object")); + + m_TestAnimCurve = AnimationCurveGUI.CurveField("扩展曲线", m_TestAnimCurve); + m_TestAnimCurve2 = EditorGUILayout.CurveField("默认曲线", m_TestAnimCurve2); + + //EditorGUILayout.TextField("abc"); + + serializedObject.ApplyModifiedProperties(); + } +} diff --git a/AnimationCurvePopupMenu/Assets/Editor/TestCurveEditor.cs.meta b/AnimationCurvePopupMenu/Assets/Editor/TestCurveEditor.cs.meta new file mode 100644 index 0000000..3391d7e --- /dev/null +++ b/AnimationCurvePopupMenu/Assets/Editor/TestCurveEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 60ff6bafc5d32db4b87abf5dc2159d9d +timeCreated: 1467200556 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AnimationCurvePopupMenu/Assets/Test.unity b/AnimationCurvePopupMenu/Assets/Test.unity new file mode 100644 index 0000000..cac3448 Binary files /dev/null and b/AnimationCurvePopupMenu/Assets/Test.unity differ diff --git a/AnimationCurvePopupMenu/Assets/Test.unity.meta b/AnimationCurvePopupMenu/Assets/Test.unity.meta new file mode 100644 index 0000000..7d3369e --- /dev/null +++ b/AnimationCurvePopupMenu/Assets/Test.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: da67d09a4f151594ca7fb2dd4e2e85b7 +timeCreated: 1467200688 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/AnimationCurvePopupMenu/Assets/TestCurve.cs b/AnimationCurvePopupMenu/Assets/TestCurve.cs new file mode 100644 index 0000000..1f9f38a --- /dev/null +++ b/AnimationCurvePopupMenu/Assets/TestCurve.cs @@ -0,0 +1,8 @@ +using UnityEngine; +using System.Collections; + +public class TestCurve : MonoBehaviour +{ + public AnimationCurve curve; // for preview + public AnimationCurve curve2; // for preview +} diff --git a/AnimationCurvePopupMenu/Assets/TestCurve.cs.meta b/AnimationCurvePopupMenu/Assets/TestCurve.cs.meta new file mode 100644 index 0000000..c254e16 --- /dev/null +++ b/AnimationCurvePopupMenu/Assets/TestCurve.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 079fcfcf76d5a204f9af86781d95edac +timeCreated: 1467200556 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AnimationCurvePopupMenu/ProjectSettings/AudioManager.asset b/AnimationCurvePopupMenu/ProjectSettings/AudioManager.asset new file mode 100644 index 0000000..1a76003 Binary files /dev/null and b/AnimationCurvePopupMenu/ProjectSettings/AudioManager.asset differ diff --git a/AnimationCurvePopupMenu/ProjectSettings/ClusterInputManager.asset b/AnimationCurvePopupMenu/ProjectSettings/ClusterInputManager.asset new file mode 100644 index 0000000..4b124b6 Binary files /dev/null and b/AnimationCurvePopupMenu/ProjectSettings/ClusterInputManager.asset differ diff --git a/AnimationCurvePopupMenu/ProjectSettings/DynamicsManager.asset b/AnimationCurvePopupMenu/ProjectSettings/DynamicsManager.asset new file mode 100644 index 0000000..2d634db Binary files /dev/null and b/AnimationCurvePopupMenu/ProjectSettings/DynamicsManager.asset differ diff --git a/AnimationCurvePopupMenu/ProjectSettings/EditorBuildSettings.asset b/AnimationCurvePopupMenu/ProjectSettings/EditorBuildSettings.asset new file mode 100644 index 0000000..1574502 Binary files /dev/null and b/AnimationCurvePopupMenu/ProjectSettings/EditorBuildSettings.asset differ diff --git a/AnimationCurvePopupMenu/ProjectSettings/EditorSettings.asset b/AnimationCurvePopupMenu/ProjectSettings/EditorSettings.asset new file mode 100644 index 0000000..a7b221f Binary files /dev/null and b/AnimationCurvePopupMenu/ProjectSettings/EditorSettings.asset differ diff --git a/AnimationCurvePopupMenu/ProjectSettings/GraphicsSettings.asset b/AnimationCurvePopupMenu/ProjectSettings/GraphicsSettings.asset new file mode 100644 index 0000000..ed6c17f Binary files /dev/null and b/AnimationCurvePopupMenu/ProjectSettings/GraphicsSettings.asset differ diff --git a/AnimationCurvePopupMenu/ProjectSettings/InputManager.asset b/AnimationCurvePopupMenu/ProjectSettings/InputManager.asset new file mode 100644 index 0000000..a12aa70 Binary files /dev/null and b/AnimationCurvePopupMenu/ProjectSettings/InputManager.asset differ diff --git a/AnimationCurvePopupMenu/ProjectSettings/NavMeshAreas.asset b/AnimationCurvePopupMenu/ProjectSettings/NavMeshAreas.asset new file mode 100644 index 0000000..2ccaab7 Binary files /dev/null and b/AnimationCurvePopupMenu/ProjectSettings/NavMeshAreas.asset differ diff --git a/AnimationCurvePopupMenu/ProjectSettings/NetworkManager.asset b/AnimationCurvePopupMenu/ProjectSettings/NetworkManager.asset new file mode 100644 index 0000000..6700c35 Binary files /dev/null and b/AnimationCurvePopupMenu/ProjectSettings/NetworkManager.asset differ diff --git a/AnimationCurvePopupMenu/ProjectSettings/Physics2DSettings.asset b/AnimationCurvePopupMenu/ProjectSettings/Physics2DSettings.asset new file mode 100644 index 0000000..d2fda8b Binary files /dev/null and b/AnimationCurvePopupMenu/ProjectSettings/Physics2DSettings.asset differ diff --git a/AnimationCurvePopupMenu/ProjectSettings/ProjectSettings.asset b/AnimationCurvePopupMenu/ProjectSettings/ProjectSettings.asset new file mode 100644 index 0000000..31c0cb3 Binary files /dev/null and b/AnimationCurvePopupMenu/ProjectSettings/ProjectSettings.asset differ diff --git a/AnimationCurvePopupMenu/ProjectSettings/ProjectVersion.txt b/AnimationCurvePopupMenu/ProjectSettings/ProjectVersion.txt new file mode 100644 index 0000000..c35bf9d --- /dev/null +++ b/AnimationCurvePopupMenu/ProjectSettings/ProjectVersion.txt @@ -0,0 +1,2 @@ +m_EditorVersion: 5.3.4p5 +m_StandardAssetsVersion: 0 diff --git a/AnimationCurvePopupMenu/ProjectSettings/QualitySettings.asset b/AnimationCurvePopupMenu/ProjectSettings/QualitySettings.asset new file mode 100644 index 0000000..d83c764 Binary files /dev/null and b/AnimationCurvePopupMenu/ProjectSettings/QualitySettings.asset differ diff --git a/AnimationCurvePopupMenu/ProjectSettings/TagManager.asset b/AnimationCurvePopupMenu/ProjectSettings/TagManager.asset new file mode 100644 index 0000000..e68f8fc Binary files /dev/null and b/AnimationCurvePopupMenu/ProjectSettings/TagManager.asset differ diff --git a/AnimationCurvePopupMenu/ProjectSettings/TimeManager.asset b/AnimationCurvePopupMenu/ProjectSettings/TimeManager.asset new file mode 100644 index 0000000..b8ff322 Binary files /dev/null and b/AnimationCurvePopupMenu/ProjectSettings/TimeManager.asset differ diff --git a/AnimationCurvePopupMenu/ProjectSettings/UnityAdsSettings.asset b/AnimationCurvePopupMenu/ProjectSettings/UnityAdsSettings.asset new file mode 100644 index 0000000..532825c Binary files /dev/null and b/AnimationCurvePopupMenu/ProjectSettings/UnityAdsSettings.asset differ diff --git a/AnimationCurvePopupMenu/ProjectSettings/UnityConnectSettings.asset b/AnimationCurvePopupMenu/ProjectSettings/UnityConnectSettings.asset new file mode 100644 index 0000000..1447c4a Binary files /dev/null and b/AnimationCurvePopupMenu/ProjectSettings/UnityConnectSettings.asset differ diff --git a/README.md b/README.md index 8de8c82..89afe05 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,55 @@ -# UnityAnimationCurvePopupMenu -Unity AnimationCurvePopupMenu (Copy, Paste) +# Unity AnimationCurvePopupMenu +Unity 曲线编辑扩展菜单功能 + +# 原因 +默认的 AnimationCurve 字段曲线编辑,不支持复制粘贴到另一个 AnimationCurve 字段,亦不支持关键帧的清空。所以扩展 AnimationCurve 的绘制,在右侧添加下拉菜单,以扩展功能。 + +# 功能 +* 复制曲线 +* 粘贴曲线 +* 清空曲线 + +# 截图 +点击右侧下拉按钮,点击 Copy 复制: +![](https://github.com/akof1314/UnityAnimationCurvePopupMenu/raw/master/Screenshots/screenshot_copy.png) +在另一个曲线,右侧菜单点击 Paste 粘贴: +![](https://github.com/akof1314/UnityAnimationCurvePopupMenu/raw/master/Screenshots/screenshot_copy.png) +清空曲线的关键帧值,点击 Clear 清空: +![](https://github.com/akof1314/UnityAnimationCurvePopupMenu/raw/master/Screenshots/screenshot_clear.png) + +# 使用说明 +代码放进工程里面,对于默认的脚本,会自动调用扩展的曲线绘制方式: +默认的脚本类似: +``` +public class TestCurve : MonoBehaviour +{ + public AnimationCurve curve; +} +``` +高级方式,要对默认脚本进行自定义绘制的话,创建 Editor 类。接着,对于属性值,调用 Unity 自带的接口 `EditorGUILayout.PropertyField` 即可。对于非属性值,可通过 AnimationCurveGUI 接口来替换 EditorGUILayout 和 EditorGUI 来绘制曲线: +``` +using UnityEngine; +using UnityEditor; + +[CustomEditor(typeof(TestCurve))] +public class TestCurveEditor : Editor +{ + private SerializedProperty curveProp; + private AnimationCurve m_TestAnimCurve = new AnimationCurve(); + + void OnEnable() + { + curveProp = serializedObject.FindProperty("curve"); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + EditorGUILayout.PropertyField(curveProp); + m_TestAnimCurve = AnimationCurveGUI.CurveField("扩展曲线", m_TestAnimCurve); + + serializedObject.ApplyModifiedProperties(); + } +} +``` diff --git a/Screenshots/screenshot_clear.png b/Screenshots/screenshot_clear.png new file mode 100644 index 0000000..e561987 Binary files /dev/null and b/Screenshots/screenshot_clear.png differ diff --git a/Screenshots/screenshot_copy.png b/Screenshots/screenshot_copy.png new file mode 100644 index 0000000..18ca338 Binary files /dev/null and b/Screenshots/screenshot_copy.png differ diff --git a/Screenshots/screenshot_paste.png b/Screenshots/screenshot_paste.png new file mode 100644 index 0000000..4cedd04 Binary files /dev/null and b/Screenshots/screenshot_paste.png differ