From 64b383fe6ee280a2d34b5740bd599bc3a3f3a5fd Mon Sep 17 00:00:00 2001 From: Savya Bikram Shah Date: Tue, 2 Jun 2026 13:03:27 +0545 Subject: [PATCH] fixes --- .../Features/ShapeBuilder/UI/ShapePiece.cs | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/Assets/Darkmatter/Code/Features/ShapeBuilder/UI/ShapePiece.cs b/Assets/Darkmatter/Code/Features/ShapeBuilder/UI/ShapePiece.cs index 998b959..85fb05d 100644 --- a/Assets/Darkmatter/Code/Features/ShapeBuilder/UI/ShapePiece.cs +++ b/Assets/Darkmatter/Code/Features/ShapeBuilder/UI/ShapePiece.cs @@ -221,11 +221,12 @@ namespace Darkmatter.Features.ShapeBuilder.UI if (toSlot && _activeSlot != null) { var slot = _activeSlot.RectTransform; + SlotPoseInDragSpace(out var slotRot, out var slotScale); if (image != null) image.preserveAspect = false; _previewSeq = Sequence.Create() .Group(Tween.UIAnchoredPosition(RectTransform, SlotPosInDragSpace(), _cfg.SnapDuration, Ease.OutQuad)) - .Group(Tween.LocalScale(RectTransform, SlotScaleInDragSpace(), _cfg.SnapDuration, Ease.OutQuad)) - .Group(Tween.LocalRotation(RectTransform, SlotRotInDragSpace(), _cfg.SnapDuration, Ease.OutQuad)) + .Group(Tween.LocalScale(RectTransform, slotScale, _cfg.SnapDuration, Ease.OutQuad)) + .Group(Tween.LocalRotation(RectTransform, slotRot, _cfg.SnapDuration, Ease.OutQuad)) .Group(Tween.UISizeDelta(RectTransform, slot.rect.size, _cfg.SnapDuration, Ease.OutQuad)); } else @@ -254,19 +255,25 @@ namespace Darkmatter.Features.ShapeBuilder.UI _inPreview = false; } - private Quaternion SlotRotInDragSpace() + // Rotation + signed scale that make the piece (a child of the drag root) match the pose + // it will have once parented into the slot. Derived from the slot's local X/Y axes + // expressed in drag-root space: their angle gives the rotation, their lengths the scale, + // and their handedness the mirror. A quaternion + lossyScale pair can't encode a negative + // (mirrored) scale, which is why flipped slots previewed at the wrong orientation while the + // snapped piece — which inherits the slot's real transform — looked correct. + private void SlotPoseInDragSpace(out Quaternion rot, out Vector3 scale) { - return Quaternion.Inverse(_parentRect.rotation) * _activeSlot.RectTransform.rotation; - } + var slot = _activeSlot.RectTransform; + Vector3 r = _parentRect.InverseTransformVector(slot.TransformVector(Vector3.right)); + Vector3 u = _parentRect.InverseTransformVector(slot.TransformVector(Vector3.up)); - private Vector3 SlotScaleInDragSpace() - { - Vector3 parentLossy = _parentRect.lossyScale; - Vector3 slotLossy = _activeSlot.RectTransform.lossyScale; - return new Vector3( - slotLossy.x / Mathf.Max(0.0001f, parentLossy.x), - slotLossy.y / Mathf.Max(0.0001f, parentLossy.y), - slotLossy.z / Mathf.Max(0.0001f, parentLossy.z)); + float angle = Mathf.Atan2(r.y, r.x) * Mathf.Rad2Deg; + float sx = new Vector2(r.x, r.y).magnitude; + float sy = new Vector2(u.x, u.y).magnitude; + if (r.x * u.y - r.y * u.x < 0f) sy = -sy; // mirrored hierarchy -> flip one axis + + rot = Quaternion.Euler(0f, 0f, angle); + scale = new Vector3(sx, sy, 1f); } internal void SnapInternal()