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();