IKSolverHeuristicInspector.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. using UnityEngine;
  2. using UnityEditor;
  3. using System.Collections;
  4. namespace RootMotion.FinalIK {
  5. /*
  6. * Custom inspector and scene view tools for IK solvers extending IKSolverHeuristic
  7. * */
  8. public class IKSolverHeuristicInspector: IKSolverInspector {
  9. #region Public methods
  10. /*
  11. * Draws the custom inspector for IKSolverHeuristic
  12. * */
  13. public static void AddInspector(SerializedProperty prop, bool editHierarchy, bool editWeights) {
  14. AddTarget(prop);
  15. AddIKPositionWeight(prop);
  16. AddProps(prop);
  17. AddBones(prop, editHierarchy, editWeights);
  18. }
  19. public static void AddTarget(SerializedProperty prop) {
  20. EditorGUILayout.PropertyField(prop.FindPropertyRelative("target"), new GUIContent("Target", "The target Transform. Solver IKPosition will be automatically set to the position of the target."));
  21. }
  22. public static void AddIKPositionWeight(SerializedProperty prop) {
  23. EditorGUILayout.PropertyField(prop.FindPropertyRelative("IKPositionWeight"), new GUIContent("Weight", "Solver weight for smooth blending."));
  24. }
  25. public static void AddProps(SerializedProperty prop) {
  26. AddClampedFloat(prop.FindPropertyRelative("tolerance"), new GUIContent("Tolerance", "Minimum offset from last reached position. Will stop solving if offset is less than tolerance. If tolerance is zero, will iterate until maxIterations."));
  27. AddClampedInt(prop.FindPropertyRelative("maxIterations"), new GUIContent("Max Iterations", "Max solver iterations per frame."), 0, int.MaxValue);
  28. }
  29. public static void AddBones(SerializedProperty prop, bool editHierarchy, bool editWeights) {
  30. EditorGUILayout.PropertyField(prop.FindPropertyRelative("useRotationLimits"), new GUIContent("Use Rotation Limits", "If true, rotation limits (if existing) will be applied on each iteration."));
  31. EditorGUILayout.PropertyField(prop.FindPropertyRelative("XY"), new GUIContent("2D", "If true, will solve only in the XY plane."));
  32. EditorGUILayout.Space();
  33. weights = editWeights;
  34. if (editHierarchy || editWeights) {
  35. AddArray(prop.FindPropertyRelative("bones"), new GUIContent("Bones", string.Empty), editHierarchy, false, null, OnAddToArrayBone, DrawArrayElementLabelBone);
  36. }
  37. EditorGUILayout.Space();
  38. }
  39. /*
  40. * Draws the scene view helpers for IKSolverHeuristic
  41. * */
  42. public static void AddScene(IKSolverHeuristic solver, Color color, bool modifiable) {
  43. // Protect from null reference errors
  44. if (Application.isPlaying && !solver.initiated) return;
  45. if (!Application.isPlaying && !solver.IsValid()) return;
  46. Handles.color = color;
  47. GUI.color = color;
  48. // Display the bones
  49. for (int i = 0; i < solver.bones.Length; i++) {
  50. IKSolver.Bone bone = solver.bones[i];
  51. if (i < solver.bones.Length - 1) Handles.DrawLine(bone.transform.position, solver.bones[i + 1].transform.position);
  52. Inspector.SphereCap(0, solver.bones[i].transform.position, Quaternion.identity, GetHandleSize(solver.bones[i].transform.position));
  53. }
  54. // Selecting joint and manipulating IKPosition
  55. if (Application.isPlaying && solver.IKPositionWeight > 0) {
  56. if (modifiable) {
  57. Inspector.CubeCap(0, solver.IKPosition, solver.GetRoot().rotation, GetHandleSize(solver.IKPosition));
  58. // Manipulating position
  59. if (solver.target == null) solver.IKPosition = Handles.PositionHandle(solver.IKPosition, Quaternion.identity);
  60. }
  61. // Draw a transparent line from last bone to IKPosition
  62. Handles.color = new Color(color.r, color.g, color.b, color.a * solver.IKPositionWeight);
  63. Handles.DrawLine(solver.bones[solver.bones.Length - 1].transform.position, solver.IKPosition);
  64. }
  65. Handles.color = Color.white;
  66. GUI.color = Color.white;
  67. }
  68. #endregion Public methods
  69. private static bool weights;
  70. private static void DrawArrayElementLabelBone(SerializedProperty bone, bool editHierarchy) {
  71. AddObjectReference(bone.FindPropertyRelative("transform"), GUIContent.none, editHierarchy, 0, weights? 100: 200);
  72. if (weights) AddWeightSlider(bone.FindPropertyRelative("weight"));
  73. }
  74. private static void OnAddToArrayBone(SerializedProperty bone) {
  75. bone.FindPropertyRelative("weight").floatValue = 1f;
  76. }
  77. private static void AddWeightSlider(SerializedProperty prop) {
  78. GUILayout.Label("Weight", GUILayout.Width(45));
  79. EditorGUILayout.PropertyField(prop, GUIContent.none);
  80. }
  81. }
  82. }