This commit is contained in:
Savya Bikram Shah
2026-06-02 13:03:27 +05:45
parent 46b5bcc978
commit 64b383fe6e

View File

@@ -221,11 +221,12 @@ namespace Darkmatter.Features.ShapeBuilder.UI
if (toSlot && _activeSlot != null) if (toSlot && _activeSlot != null)
{ {
var slot = _activeSlot.RectTransform; var slot = _activeSlot.RectTransform;
SlotPoseInDragSpace(out var slotRot, out var slotScale);
if (image != null) image.preserveAspect = false; if (image != null) image.preserveAspect = false;
_previewSeq = Sequence.Create() _previewSeq = Sequence.Create()
.Group(Tween.UIAnchoredPosition(RectTransform, SlotPosInDragSpace(), _cfg.SnapDuration, Ease.OutQuad)) .Group(Tween.UIAnchoredPosition(RectTransform, SlotPosInDragSpace(), _cfg.SnapDuration, Ease.OutQuad))
.Group(Tween.LocalScale(RectTransform, SlotScaleInDragSpace(), _cfg.SnapDuration, Ease.OutQuad)) .Group(Tween.LocalScale(RectTransform, slotScale, _cfg.SnapDuration, Ease.OutQuad))
.Group(Tween.LocalRotation(RectTransform, SlotRotInDragSpace(), _cfg.SnapDuration, Ease.OutQuad)) .Group(Tween.LocalRotation(RectTransform, slotRot, _cfg.SnapDuration, Ease.OutQuad))
.Group(Tween.UISizeDelta(RectTransform, slot.rect.size, _cfg.SnapDuration, Ease.OutQuad)); .Group(Tween.UISizeDelta(RectTransform, slot.rect.size, _cfg.SnapDuration, Ease.OutQuad));
} }
else else
@@ -254,19 +255,25 @@ namespace Darkmatter.Features.ShapeBuilder.UI
_inPreview = false; _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() float angle = Mathf.Atan2(r.y, r.x) * Mathf.Rad2Deg;
{ float sx = new Vector2(r.x, r.y).magnitude;
Vector3 parentLossy = _parentRect.lossyScale; float sy = new Vector2(u.x, u.y).magnitude;
Vector3 slotLossy = _activeSlot.RectTransform.lossyScale; if (r.x * u.y - r.y * u.x < 0f) sy = -sy; // mirrored hierarchy -> flip one axis
return new Vector3(
slotLossy.x / Mathf.Max(0.0001f, parentLossy.x), rot = Quaternion.Euler(0f, 0f, angle);
slotLossy.y / Mathf.Max(0.0001f, parentLossy.y), scale = new Vector3(sx, sy, 1f);
slotLossy.z / Mathf.Max(0.0001f, parentLossy.z));
} }
internal void SnapInternal() internal void SnapInternal()