170 lines
6.9 KiB
C#
170 lines
6.9 KiB
C#
using UnityEditor;
|
|
using UnityEditorInternal;
|
|
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
|
|
namespace Obi
|
|
{
|
|
|
|
[CustomEditor(typeof(ObiPinhole))]
|
|
public class ObiPinholeEditor : Editor
|
|
{
|
|
|
|
SerializedProperty targetTransform;
|
|
SerializedProperty position;
|
|
SerializedProperty limitRange;
|
|
SerializedProperty range;
|
|
SerializedProperty compliance;
|
|
SerializedProperty friction;
|
|
SerializedProperty motorSpeed;
|
|
SerializedProperty motorForce;
|
|
SerializedProperty clamp;
|
|
SerializedProperty breakThreshold;
|
|
|
|
ObiPinhole pinhole;
|
|
|
|
public void OnEnable()
|
|
{
|
|
|
|
pinhole = target as ObiPinhole;
|
|
targetTransform = serializedObject.FindProperty("m_Target");
|
|
position = serializedObject.FindProperty("m_Position");
|
|
limitRange = serializedObject.FindProperty("m_LimitRange");
|
|
range = serializedObject.FindProperty("m_Range");
|
|
friction = serializedObject.FindProperty("m_Friction");
|
|
motorSpeed = serializedObject.FindProperty("m_MotorSpeed");
|
|
motorForce = serializedObject.FindProperty("m_MotorForce");
|
|
compliance = serializedObject.FindProperty("m_Compliance");
|
|
clamp = serializedObject.FindProperty("m_ClampAtEnds");
|
|
breakThreshold = serializedObject.FindProperty("breakThreshold");
|
|
}
|
|
|
|
public override void OnInspectorGUI()
|
|
{
|
|
|
|
serializedObject.UpdateIfRequiredOrScript();
|
|
|
|
// warn about incorrect setups:
|
|
if (!targetTransform.hasMultipleDifferentValues)
|
|
{
|
|
var targetValue = targetTransform.objectReferenceValue as UnityEngine.Component;
|
|
if (targetValue != null)
|
|
{
|
|
var collider = targetValue.GetComponent<ObiColliderBase>();
|
|
if (collider == null)
|
|
{
|
|
EditorGUILayout.HelpBox("Pinholes require the target object to have a ObiCollider component. Please add one.", MessageType.Warning);
|
|
}
|
|
}
|
|
}
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
Transform trget = EditorGUILayout.ObjectField("Target", pinhole.target, typeof(Transform), true) as Transform;
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
Undo.RecordObject(pinhole, "Set target");
|
|
pinhole.target = trget;
|
|
PrefabUtility.RecordPrefabInstancePropertyModifications(pinhole);
|
|
}
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
EditorGUILayout.PropertyField(position, new GUIContent("Position"));
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
serializedObject.ApplyModifiedProperties();
|
|
pinhole.CalculateMu();
|
|
}
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
EditorGUILayout.PropertyField(limitRange, new GUIContent("Limit Range"));
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
serializedObject.ApplyModifiedProperties();
|
|
pinhole.CalculateRange();
|
|
}
|
|
|
|
if (limitRange.boolValue)
|
|
{
|
|
EditorGUI.indentLevel++;
|
|
EditorGUI.BeginChangeCheck();
|
|
EditorGUILayout.PropertyField(range, new GUIContent("Range"));
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
serializedObject.ApplyModifiedProperties();
|
|
pinhole.CalculateRange();
|
|
}
|
|
EditorGUI.indentLevel--;
|
|
}
|
|
EditorGUILayout.PropertyField(clamp, new GUIContent("Clamp at ends"));
|
|
EditorGUILayout.PropertyField(friction, new GUIContent("Friction"));
|
|
EditorGUILayout.PropertyField(motorSpeed, new GUIContent("Motor Target Speed"));
|
|
EditorGUILayout.PropertyField(motorForce, new GUIContent("Motor Max Force"));
|
|
EditorGUILayout.PropertyField(compliance, new GUIContent("Compliance"));
|
|
EditorGUILayout.PropertyField(breakThreshold, new GUIContent("Break threshold"));
|
|
|
|
if (GUI.changed)
|
|
serializedObject.ApplyModifiedProperties();
|
|
|
|
}
|
|
|
|
[DrawGizmo(GizmoType.Selected)]
|
|
private static void DrawGizmos(ObiPinhole pinhole, GizmoType gizmoType)
|
|
{
|
|
var rope = pinhole.GetComponent<ObiRope>();
|
|
|
|
var ropeBlueprint = rope.sharedBlueprint as ObiRopeBlueprintBase;
|
|
if (rope.isLoaded && ropeBlueprint != null && ropeBlueprint.deformableEdges != null)
|
|
{
|
|
Handles.color = new Color(1, 0.5f, 0.2f, 1);
|
|
Handles.matrix = rope.solver.transform.localToWorldMatrix;
|
|
|
|
// draw limits:
|
|
if (pinhole.limitRange)
|
|
{
|
|
for (int i = pinhole.firstEdge.edgeIndex; i <= pinhole.lastEdge.edgeIndex; ++i)
|
|
{
|
|
if (i >= 0 && i < ropeBlueprint.deformableEdges.Length)
|
|
{
|
|
int p1 = ropeBlueprint.deformableEdges[i * 2];
|
|
int p2 = ropeBlueprint.deformableEdges[i * 2 + 1];
|
|
var pos1 = rope.solver.positions[rope.solverIndices[p1]];
|
|
var pos2 = rope.solver.positions[rope.solverIndices[p2]];
|
|
|
|
if (i == pinhole.firstEdge.edgeIndex)
|
|
{
|
|
pos1 = Vector4.Lerp(pos1, pos2, pinhole.firstEdge.coordinate);
|
|
Handles.DrawSolidDisc(pos1, pos2 - pos1, HandleUtility.GetHandleSize(pos1) * 0.05f);
|
|
}
|
|
if (i == pinhole.lastEdge.edgeIndex)
|
|
{
|
|
pos2 = Vector4.Lerp(pos1, pos2, pinhole.lastEdge.coordinate);
|
|
Handles.DrawSolidDisc(pos2, pos1 - pos2, HandleUtility.GetHandleSize(pos2) * 0.05f);
|
|
}
|
|
|
|
Handles.DrawLine(pos1, pos2, 2);
|
|
}
|
|
}
|
|
}
|
|
|
|
// draw source particle:
|
|
int edgeIndex = pinhole.edgeIndex;
|
|
|
|
if (edgeIndex >= 0 && edgeIndex < ropeBlueprint.deformableEdges.Length)
|
|
{
|
|
int p1 = ropeBlueprint.deformableEdges[edgeIndex * 2];
|
|
int p2 = ropeBlueprint.deformableEdges[edgeIndex * 2 + 1];
|
|
var pos1 = rope.solver.positions[rope.solverIndices[p1]];
|
|
var pos2 = rope.solver.positions[rope.solverIndices[p2]];
|
|
Vector4 pos = Vector4.Lerp(pos1, pos2, pinhole.edgeCoordinate);
|
|
Handles.DrawWireDisc(pos, pos1 - pos2, HandleUtility.GetHandleSize(pos) * 0.1f, 2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|