static void DrawArrowCap(Vector3 localOffset, Quaternion localRotation, Transform bone) { HandlesHelper.Scope(() => { Vector3 worldPos = bone.TransformPoint(localOffset); Handles.matrix = Matrix4x4.TRS( worldPos, bone.rotation * localRotation, bone.localScale ); float size = 0.1f; //HandleUtility.GetHandleSize(worldPos); Handles.color = Color.blue.WithAlpha(0.5f); Handles.ArrowHandleCap( controlID: 0, position: Vector3.zero, rotation: Quaternion.LookRotation(Vector3.forward), size: size, eventType: EventType.Repaint ); Handles.color = Color.red.WithAlpha(0.5f); Handles.ArrowHandleCap( controlID: 0, position: Vector3.zero, rotation: Quaternion.LookRotation(Vector3.right), size: size, eventType: EventType.Repaint ); Handles.color = Color.green.WithAlpha(0.5f); Handles.ArrowHandleCap( controlID: 0, position: Vector3.zero, rotation: Quaternion.LookRotation(Vector3.up), size: size, eventType: EventType.Repaint ); }); }
public static void Draw(SerializedProperty fieldProperty, GUIContent label, Transform self) { if (fieldProperty.hasMultipleDifferentValues) { return; } if (editingProperty != null && !IsEditingProperty(fieldProperty)) { return; } var kindProp = fieldProperty.FindPropertyRelative("kind"); var parentProp = fieldProperty.FindPropertyRelative("parent"); var childNameProp = fieldProperty.FindPropertyRelative("childName"); var findInactiveProp = fieldProperty.FindPropertyRelative("findInactive"); var findInChildrenProp = fieldProperty.FindPropertyRelative("findInChildren"); var directCompProp = fieldProperty.FindPropertyRelative("directComponent"); var localOffsetProp = fieldProperty.FindPropertyRelative("_localOffset"); var localRotProp = fieldProperty.FindPropertyRelative("_localRotation"); bool anyNull = kindProp == null || parentProp == null || childNameProp == null || findInactiveProp == null || findInChildrenProp == null || directCompProp == null || localOffsetProp == null || localRotProp == null; if (anyNull) { Dbg.LogWarnOnceRelease( Dbg.Context(fieldProperty.propertyPath), "Property with path {0} lacked a field. Are you sure it's a LocalOffsetField?", fieldProperty.propertyPath ); return; } Transform bone = FindCompField <Transform> .Get( kindProp.EnumValue <FindCompKind>(), (Transform)parentProp.objectReferenceValue, self, childNameProp.stringValue, findInChildrenProp.boolValue, findInactiveProp.boolValue, (Transform)directCompProp.objectReferenceValue ); if (bone == null) { return; } var localOffset = localOffsetProp.vector3Value; var localRotation = Quaternion.Euler(localRotProp.vector3Value); EditorHelper.RegisterUndo("Transformed Effect", fieldProperty.serializedObject.targetObject, undoHelper ); Vector3 worldPos = bone.TransformPoint(localOffset); bool clicked = false; HandlesHelper.Scope(() => { if (IsEditingProperty(fieldProperty)) { Handles.color = Color.green; } if (editingProperty == null) { clicked = Handles.Button( worldPos, Quaternion.identity, size: 0.05f, pickSize: 0.05f, capFunction: Handles.SphereHandleCap ); } else { Handles.SphereHandleCap( controlID: 0, position: worldPos, rotation: Quaternion.identity, size: 0.05f, eventType: EventType.Repaint ); } }); if (clicked) { undoHelper.worldSpaceRot = Quaternion.identity; editingProperty = fieldProperty; if (Tools.current != Tool.Move && Tools.current != Tool.Rotate) { Tools.current = Tool.Move; } } GUIStyle style = EditorStyles.toolbarTextField; style.CalcSize(label); Handles.Label(worldPos, label, style); if (!IsEditingProperty(fieldProperty)) { return; } fieldProperty.serializedObject.Update(); HandlesHelper.Scope(() => { if (Tools.current == Tool.Rotate) { if (Tools.pivotRotation == PivotRotation.Local) { Handles.matrix = bone.localToWorldMatrix; } else { Handles.matrix = Matrix4x4.TRS( bone.TransformPoint(localOffset), Quaternion.identity, bone.localScale ); } DrawArrowCap(localOffset, localRotation, bone); Quaternion newLocalRot = localRotation; if (Tools.pivotRotation == PivotRotation.Global) { var newWorldSpaceRot = Handles.RotationHandle(undoHelper.worldSpaceRot, Vector3.zero); // Difference between the the new and the old world space rotation var diff = Quaternion.Inverse(undoHelper.worldSpaceRot) * newWorldSpaceRot; if (diff != Quaternion.identity) { // Convert local rot to world Quaternion rotInWorld = bone.rotation * localRotation; // Apply world difference rotInWorld = diff * rotInWorld; // Convert back to local space newLocalRot = Quaternion.Inverse(bone.rotation) * rotInWorld; undoHelper.worldSpaceRot = newWorldSpaceRot; } } else { newLocalRot = Handles.RotationHandle(localRotation, localOffset); } if (localRotation != newLocalRot) { localRotProp.vector3Value = newLocalRot.eulerAngles; } } else if (Tools.current == Tool.Move) { Handles.matrix = bone.localToWorldMatrix; var rot = localRotation; if (Tools.pivotRotation == PivotRotation.Global) { rot = Quaternion.LookRotation( bone.InverseTransformDirection(Vector3.forward), bone.InverseTransformDirection(Vector3.up) ); } var pos = Handles.PositionHandle(localOffset, rot); if (localOffset != pos) { localOffsetProp.vector3Value = pos; } } }); fieldProperty.serializedObject.ApplyModifiedProperties(); DrawEditingWarning(); Event e = Event.current; if (e.type == EventType.keyUp) { if (e.keyCode == KeyCode.Escape) { StopEditing(); } } }