fix(tarot): 塔罗逆位用本地 Z 旋转避免镜像闪变
Made-with: Cursor
This commit is contained in:
@@ -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
|
||||
|
||||
/// <summary>
|
||||
/// 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°).
|
||||
/// </summary>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// 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°) 不等价造成镜像闪变。
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>正立/逆位统一用本地 Z(0° / 180°),scale.y 恒为正。</summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>仅处理旧版负 scale.y:改为正 scale 并在本地绕 Z 补 180°,不覆盖扇形等已有 localRotation。</summary>
|
||||
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<SpriteRenderer>();
|
||||
|
||||
Reference in New Issue
Block a user