|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEditor;
|
|
|
|
|
using System.Collections;
|
|
|
|
|
using System;
|
|
|
|
|
|
|
|
|
|
namespace RootMotion.FinalIK {
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Custom inspector and scene view tools for IKSolverFullBody
|
|
|
|
|
* */
|
|
|
|
|
public class IKSolverFullBodyInspector : IKSolverInspector {
|
|
|
|
|
|
|
|
|
|
#region Public methods
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Draws the custom inspector for IKSolverFullBody
|
|
|
|
|
* */
|
|
|
|
|
public static void AddInspector(SerializedProperty prop, bool editWeights) {
|
|
|
|
|
EditorGUILayout.PropertyField(prop.FindPropertyRelative("IKPositionWeight"), new GUIContent("Weight", "Solver weight for smooth blending (ik.solver.IKPositionWeight)."));
|
|
|
|
|
EditorGUILayout.PropertyField(prop.FindPropertyRelative("iterations"), new GUIContent("Iterations", "Solver iterations per frame."));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Draws the scene view helpers for IKSolverFullBody
|
|
|
|
|
* */
|
|
|
|
|
public static void AddScene(UnityEngine.Object target, IKSolverFullBody solver, Color color, bool modifiable, ref int selectedEffector, float size) {
|
|
|
|
|
if (!modifiable) return;
|
|
|
|
|
if (!solver.initiated) return;
|
|
|
|
|
if (!Application.isPlaying && !solver.IsValid()) return;
|
|
|
|
|
|
|
|
|
|
// Effectors
|
|
|
|
|
for (int i = 0; i < solver.effectors.Length; i++) {
|
|
|
|
|
bool rotate = solver.effectors[i].isEndEffector;
|
|
|
|
|
float weight = rotate? Mathf.Max(solver.effectors[i].positionWeight, solver.effectors[i].rotationWeight): solver.effectors[i].positionWeight;
|
|
|
|
|
|
|
|
|
|
if (weight > 0 && selectedEffector != i) {
|
|
|
|
|
Handles.color = color;
|
|
|
|
|
|
|
|
|
|
if (rotate) {
|
|
|
|
|
if (Inspector.DotButton(solver.effectors[i].position, solver.effectors[i].rotation, size * 0.5f, size * 0.5f)) {
|
|
|
|
|
selectedEffector = i;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (Inspector.SphereButton(solver.effectors[i].position, solver.effectors[i].rotation, size, size)) {
|
|
|
|
|
selectedEffector = i;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < solver.effectors.Length; i++) IKEffectorInspector.AddScene(solver.effectors[i], color, modifiable && i == selectedEffector, size);
|
|
|
|
|
|
|
|
|
|
if (GUI.changed) EditorUtility.SetDirty(target);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion Public methods
|
|
|
|
|
|
|
|
|
|
public static void AddChain(FBIKChain[] chain, int index, Color color, float size) {
|
|
|
|
|
Handles.color = color;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < chain[index].nodes.Length - 1; i++) {
|
|
|
|
|
Handles.DrawLine(GetNodePosition(chain[index].nodes[i]), GetNodePosition(chain[index].nodes[i + 1]));
|
|
|
|
|
Inspector.SphereCap(0, GetNodePosition(chain[index].nodes[i]), Quaternion.identity, size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Inspector.SphereCap(0, GetNodePosition(chain[index].nodes[chain[index].nodes.Length - 1]), Quaternion.identity, size);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < chain[index].children.Length; i++) {
|
|
|
|
|
Handles.DrawLine(GetNodePosition(chain[index].nodes[chain[index].nodes.Length - 1]), GetNodePosition(chain[chain[index].children[i]].nodes[0]));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Vector3 GetNodePosition(IKSolver.Node node) {
|
|
|
|
|
if (Application.isPlaying) return node.solverPosition;
|
|
|
|
|
return node.transform.position;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|