From c0b658fee079c22324b0247c8373f0a901701419 Mon Sep 17 00:00:00 2001
From: bottlefish <781230111@qq.com>
Date: Wed, 15 Apr 2026 19:10:04 +0800
Subject: [PATCH] =?UTF-8?q?fix(tarot):=20=E5=A1=94=E7=BD=97=E9=80=86?=
=?UTF-8?q?=E4=BD=8D=E7=94=A8=E6=9C=AC=E5=9C=B0=20Z=20=E6=97=8B=E8=BD=AC?=
=?UTF-8?q?=E9=81=BF=E5=85=8D=E9=95=9C=E5=83=8F=E9=97=AA=E5=8F=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Made-with: Cursor
---
Assets/Scripts/MiniGame/Tarot/TarotCard.cs | 38 +++++++++++++++-------
1 file changed, 26 insertions(+), 12 deletions(-)
diff --git a/Assets/Scripts/MiniGame/Tarot/TarotCard.cs b/Assets/Scripts/MiniGame/Tarot/TarotCard.cs
index 8760a148c..ab3a46c5c 100644
--- a/Assets/Scripts/MiniGame/Tarot/TarotCard.cs
+++ b/Assets/Scripts/MiniGame/Tarot/TarotCard.cs
@@ -66,6 +66,7 @@ namespace AibisDream.MiniGame.Tarot
IsFaceUp = false;
Orientation = TarotOrientation.Normal;
transform.localScale = Vector3.one;
+ transform.localRotation = Quaternion.identity;
}
private void Awake()
@@ -149,7 +150,7 @@ namespace AibisDream.MiniGame.Tarot
///
/// Flip the card to reveal front side with a target orientation.
- /// X-scale: 1 -> 0 (swap sprite) -> 1, then apply orientation via Y-scale.
+ /// X-scale: 1 -> 0 (swap sprite) -> 1, then apply orientation via local Z rotation (0° / 180°).
///
public IEnumerator Flip(TarotOrientation targetOrientation, float duration = 0.5f)
{
@@ -169,10 +170,7 @@ namespace AibisDream.MiniGame.Tarot
else if (IsFaceUp)
Debug.LogWarning("[TarotCard] Front Sprite 未设置,翻牌后无法显示正面。", this);
- Orientation = targetOrientation;
- var s = transform.localScale;
- s.y = Mathf.Abs(s.y) * (targetOrientation == TarotOrientation.Inverted ? -1f : 1f);
- transform.localScale = s;
+ ApplyOrientationToTransform(targetOrientation);
});
seq.Append(transform.DOScaleX(scale.x, half).SetEase(Ease.OutQuad));
@@ -181,7 +179,7 @@ namespace AibisDream.MiniGame.Tarot
///
/// Change orientation of an already face-up card (rotate 180 degrees around local Z).
- /// After animation completes, resets rotation to identity and applies Y-scale for the new state.
+ /// 结束后与翻牌一致:用本地 Z 旋转表示逆位,避免动画末尾用负 scale.y 与 Rz(180°) 不等价造成镜像闪变。
///
public IEnumerator SetOrientationAnimated(TarotOrientation targetOrientation, float duration = 0.4f)
{
@@ -190,6 +188,9 @@ namespace AibisDream.MiniGame.Tarot
_flipTween?.Kill();
_orientationTween?.Kill();
+ // 旧版用负 scale.y 表示逆位时,收束为绕本地 Z 再转 180°,避免与后续 Rz 动画叠加错乱
+ EnsureOrientationUsesRotationNotNegativeScale();
+
// 使用本地旋转,避免 DORotate(世界欧拉)与 localEulerAngles 混用导致几乎不转或乱跳
var endLocal = transform.localRotation * Quaternion.Euler(0f, 0f, 180f);
_orientationTween = transform.DOLocalRotateQuaternion(endLocal, duration)
@@ -198,21 +199,34 @@ namespace AibisDream.MiniGame.Tarot
yield return _orientationTween.WaitForCompletion();
_orientationTween = null;
- Orientation = targetOrientation;
- transform.localRotation = Quaternion.identity;
- var s = transform.localScale;
- s.y = Mathf.Abs(s.y) * (targetOrientation == TarotOrientation.Inverted ? -1f : 1f);
- transform.localScale = s;
+ ApplyOrientationToTransform(targetOrientation);
}
public void SetOrientationImmediate(TarotOrientation orientation)
+ {
+ ApplyOrientationToTransform(orientation);
+ }
+
+ /// 正立/逆位统一用本地 Z(0° / 180°),scale.y 恒为正。
+ private void ApplyOrientationToTransform(TarotOrientation orientation)
{
Orientation = orientation;
+ transform.localRotation = Quaternion.Euler(0f, 0f, orientation == TarotOrientation.Inverted ? 180f : 0f);
var s = transform.localScale;
- s.y = Mathf.Abs(s.y) * (orientation == TarotOrientation.Inverted ? -1f : 1f);
+ s.y = Mathf.Abs(s.y);
transform.localScale = s;
}
+ /// 仅处理旧版负 scale.y:改为正 scale 并在本地绕 Z 补 180°,不覆盖扇形等已有 localRotation。
+ private void EnsureOrientationUsesRotationNotNegativeScale()
+ {
+ var s = transform.localScale;
+ if (s.y >= 0f) return;
+ s.y = Mathf.Abs(s.y);
+ transform.localScale = s;
+ transform.localRotation = transform.localRotation * Quaternion.Euler(0f, 0f, 180f);
+ }
+
public void SetAlpha(float alpha)
{
if (_spriteRenderer == null) _spriteRenderer = GetComponent();