using UnityEngine;
using UnityEngine.U2D.IK;
namespace UnityEditor.U2D.IK
{
///
/// Custom Inspector for Solver2D.
///
[CustomEditor(typeof(Solver2D))]
[CanEditMultipleObjects]
public abstract class Solver2DEditor : Editor
{
static class Contents
{
public static readonly GUIContent constrainRotationLabel = new GUIContent("Constrain Rotation", "Set Effector's rotation to Target");
public static readonly GUIContent solveFromDefaultPoseLabel = new GUIContent("Solve from Default Pose", "Restore transform's rotation to default value before solving the IK");
public static readonly GUIContent weightLabel = new GUIContent("Weight", "Blend between Forward and Inverse Kinematics");
public static readonly string restoreDefaultPoseString = "Restore Default Pose";
public static readonly string createTargetString = "Create Target";
}
SerializedProperty m_ConstrainRotationProperty;
SerializedProperty m_SolveFromDefaultPoseProperty;
SerializedProperty m_WeightProperty;
SerializedProperty m_SolverColorProperty;
void SetupProperties()
{
if(m_ConstrainRotationProperty == null || m_SolveFromDefaultPoseProperty == null || m_WeightProperty == null)
{
m_ConstrainRotationProperty = serializedObject.FindProperty("m_ConstrainRotation");
m_SolveFromDefaultPoseProperty = serializedObject.FindProperty("m_SolveFromDefaultPose");
m_WeightProperty = serializedObject.FindProperty("m_Weight");
}
}
///
/// Custom Inspector GUI for Solver2D.
///
protected void DrawCommonSolverInspector()
{
SetupProperties();
EditorGUILayout.PropertyField(m_ConstrainRotationProperty, Contents.constrainRotationLabel);
EditorGUILayout.PropertyField(m_SolveFromDefaultPoseProperty, Contents.solveFromDefaultPoseLabel);
EditorGUILayout.PropertyField(m_WeightProperty, Contents.weightLabel);
EditorGUILayout.Space();
EditorGUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
EditorGUI.BeginDisabledGroup(!EnableCreateTarget());
DoCreateTargetButton();
EditorGUI.EndDisabledGroup();
EditorGUI.BeginDisabledGroup(!EnableRestoreDefaultPose());
DoRestoreDefaultPoseButton();
EditorGUI.EndDisabledGroup();
GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
}
bool EnableRestoreDefaultPose()
{
foreach (var l_target in targets)
{
var solver = l_target as Solver2D;
if (!solver.isValid || IKEditorManager.instance.FindManager(solver) == null)
continue;
return true;
}
return false;
}
bool EnableCreateTarget()
{
foreach (var l_target in targets)
{
var solver = l_target as Solver2D;
if (!solver.isValid)
continue;
for(int i = 0; i < solver.chainCount; ++i)
{
var chain = solver.GetChain(i);
if(chain.target == null)
return true;
}
}
return false;
}
void DoRestoreDefaultPoseButton()
{
if (GUILayout.Button(Contents.restoreDefaultPoseString, GUILayout.MaxWidth(150f)))
{
foreach (var l_target in targets)
{
var solver = l_target as Solver2D;
if (!solver.isValid)
continue;
IKEditorManager.instance.Record(solver, Contents.restoreDefaultPoseString);
for(int i = 0; i < solver.chainCount; ++i)
{
var chain = solver.GetChain(i);
chain.RestoreDefaultPose(solver.constrainRotation);
if(chain.target)
{
chain.target.position = chain.effector.position;
chain.target.rotation = chain.effector.rotation;
}
}
IKEditorManager.instance.UpdateSolverImmediate(solver, true);
}
}
}
void DoCreateTargetButton()
{
if (GUILayout.Button(Contents.createTargetString, GUILayout.MaxWidth(125f)))
{
foreach (var l_target in targets)
{
var solver = l_target as Solver2D;
if (!solver.isValid)
continue;
for(int i = 0; i < solver.chainCount; ++i)
{
var chain = solver.GetChain(i);
if(chain.target == null)
{
Undo.RegisterCompleteObjectUndo(solver, Contents.createTargetString);
chain.target = new GameObject(GameObjectUtility.GetUniqueNameForSibling(solver.transform, solver.name + "_Target")).transform;
chain.target.SetParent(solver.transform);
chain.target.position = chain.effector.position;
chain.target.rotation = chain.effector.rotation;
Undo.RegisterCreatedObjectUndo(chain.target.gameObject, Contents.createTargetString);
}
}
}
}
}
}
}