Refactor, cleanup code and add documentaiton
This commit is contained in:
322
Assets/Scripts/CardSystem/DragDrop/BoosterPackVisual.cs
Normal file
322
Assets/Scripts/CardSystem/DragDrop/BoosterPackVisual.cs
Normal file
@@ -0,0 +1,322 @@
|
||||
using Pixelplacement;
|
||||
using Pixelplacement.TweenSystem;
|
||||
using UI.DragAndDrop.Core;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace UI.CardSystem.DragDrop
|
||||
{
|
||||
/// <summary>
|
||||
/// Visual representation for BoosterPackDraggable.
|
||||
/// Displays the booster pack sprite and handles opening animations.
|
||||
/// </summary>
|
||||
public class BoosterPackVisual : DraggableVisual
|
||||
{
|
||||
[Header("Booster Pack Visual")]
|
||||
[SerializeField] private Image packImage;
|
||||
[SerializeField] private Sprite packSprite;
|
||||
[SerializeField] private ParticleSystem glowEffect;
|
||||
[SerializeField] private Transform glowTransform;
|
||||
|
||||
[Header("Opening Animation")]
|
||||
[SerializeField] private float openingScalePunch = 0.5f;
|
||||
[SerializeField] private float openingRotationPunch = 360f;
|
||||
[SerializeField] private float openingDuration = 0.5f;
|
||||
|
||||
private BoosterPackDraggable _boosterDraggable;
|
||||
|
||||
// Effect tracking
|
||||
private int _glowRotationTweenId = -1;
|
||||
private float _defaultGlowRate = 10f;
|
||||
|
||||
public override void Initialize(DraggableObject parent)
|
||||
{
|
||||
base.Initialize(parent);
|
||||
|
||||
_boosterDraggable = parent as BoosterPackDraggable;
|
||||
|
||||
// Get pack image if not assigned
|
||||
if (packImage == null)
|
||||
{
|
||||
packImage = GetComponentInChildren<Image>();
|
||||
}
|
||||
|
||||
// Set initial sprite
|
||||
if (packImage != null && packSprite != null)
|
||||
{
|
||||
packImage.sprite = packSprite;
|
||||
}
|
||||
|
||||
// Subscribe to booster events
|
||||
if (_boosterDraggable != null)
|
||||
{
|
||||
_boosterDraggable.OnBoosterOpened += HandleBoosterOpened;
|
||||
_boosterDraggable.OnTapped += HandleTapped;
|
||||
}
|
||||
|
||||
// Start glow effect if available
|
||||
if (glowEffect != null && !glowEffect.isPlaying)
|
||||
{
|
||||
glowEffect.Play();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void UpdateVisualContent()
|
||||
{
|
||||
// Update glow rotation for visual interest (skip if effects suppressed)
|
||||
if (glowTransform != null && !_effectsSuppressed)
|
||||
{
|
||||
glowTransform.Rotate(Vector3.forward * 30f * Time.deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleBoosterOpened(BoosterPackDraggable booster)
|
||||
{
|
||||
PlayOpeningAnimation();
|
||||
}
|
||||
|
||||
private void HandleTapped(BoosterPackDraggable booster, int currentTap, int maxTaps)
|
||||
{
|
||||
PlayShakeAnimation(currentTap, maxTaps);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Play progressive shake animation based on tap intensity
|
||||
/// This is always allowed, even when effects are suppressed
|
||||
/// </summary>
|
||||
public void PlayShakeAnimation(int intensity, int maxIntensity)
|
||||
{
|
||||
float normalizedIntensity = (float)intensity / maxIntensity;
|
||||
float shakeAmount = Mathf.Lerp(5f, 30f, normalizedIntensity);
|
||||
float shakeDuration = 0.15f;
|
||||
|
||||
// Shake rotation
|
||||
Vector3 shakeRotation = new Vector3(
|
||||
Random.Range(-shakeAmount, shakeAmount),
|
||||
Random.Range(-shakeAmount, shakeAmount),
|
||||
Random.Range(-shakeAmount, shakeAmount)
|
||||
);
|
||||
|
||||
Tween.Rotation(transform, transform.eulerAngles + shakeRotation,
|
||||
shakeDuration, 0f, Tween.EaseOutBack,
|
||||
completeCallback: () => {
|
||||
Tween.Rotation(transform, Vector3.zero,
|
||||
shakeDuration, 0f, Tween.EaseInBack);
|
||||
});
|
||||
|
||||
// NOTE: Scale pulse is handled by BoosterPackDraggable.OnPointerUpHook()
|
||||
// We don't need a duplicate scale tween here - it would conflict!
|
||||
|
||||
// Extra glow burst on final tap (only if effects not suppressed)
|
||||
if (intensity == maxIntensity && glowEffect != null && !_effectsSuppressed)
|
||||
{
|
||||
var emission = glowEffect.emission;
|
||||
emission.rateOverTimeMultiplier = 50f;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Play the booster pack opening animation
|
||||
/// </summary>
|
||||
public void PlayOpeningAnimation()
|
||||
{
|
||||
// Scale punch
|
||||
Vector3 targetScale = transform.localScale * (1f + openingScalePunch);
|
||||
Tween.LocalScale(transform, targetScale, openingDuration / 2f, 0f, Tween.EaseOutBack,
|
||||
completeCallback: () => {
|
||||
Tween.LocalScale(transform, Vector3.one, openingDuration / 2f, 0f, Tween.EaseInBack);
|
||||
});
|
||||
|
||||
// Rotation
|
||||
Tween.Rotation(transform, transform.eulerAngles + Vector3.forward * openingRotationPunch,
|
||||
openingDuration, 0f, Tween.EaseOutBack);
|
||||
|
||||
// Glow burst
|
||||
if (glowEffect != null)
|
||||
{
|
||||
glowEffect.Stop();
|
||||
glowEffect.Play();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the booster pack sprite
|
||||
/// </summary>
|
||||
public void SetPackSprite(Sprite sprite)
|
||||
{
|
||||
packSprite = sprite;
|
||||
if (packImage != null)
|
||||
{
|
||||
packImage.sprite = packSprite;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPointerEnterVisual()
|
||||
{
|
||||
base.OnPointerEnterVisual();
|
||||
|
||||
// Extra glow when hovering (skip if effects suppressed)
|
||||
if (glowEffect != null && !_effectsSuppressed)
|
||||
{
|
||||
var emission = glowEffect.emission;
|
||||
emission.rateOverTimeMultiplier = 20f;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPointerExitVisual()
|
||||
{
|
||||
base.OnPointerExitVisual();
|
||||
|
||||
// Restore normal glow (skip if effects suppressed)
|
||||
if (glowEffect != null && !_effectsSuppressed)
|
||||
{
|
||||
var emission = glowEffect.emission;
|
||||
emission.rateOverTimeMultiplier = _defaultGlowRate;
|
||||
}
|
||||
}
|
||||
|
||||
#region Effect Management Overrides
|
||||
|
||||
protected override void OnEffectsSuppressed()
|
||||
{
|
||||
base.OnEffectsSuppressed();
|
||||
|
||||
// Stop glow effect
|
||||
if (glowEffect != null)
|
||||
{
|
||||
glowEffect.Stop();
|
||||
}
|
||||
|
||||
// Cancel glow rotation tween if tracked
|
||||
if (_glowRotationTweenId != -1)
|
||||
{
|
||||
Tween.Stop(_glowRotationTweenId);
|
||||
_glowRotationTweenId = -1;
|
||||
}
|
||||
|
||||
// Reset glow rotation to zero
|
||||
if (glowTransform != null)
|
||||
{
|
||||
glowTransform.localRotation = Quaternion.identity;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnEffectsResumed()
|
||||
{
|
||||
base.OnEffectsResumed();
|
||||
|
||||
// Resume glow effect
|
||||
if (glowEffect != null && !glowEffect.isPlaying)
|
||||
{
|
||||
glowEffect.Play();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnEffectsReset()
|
||||
{
|
||||
base.OnEffectsReset();
|
||||
|
||||
// Stop glow effect
|
||||
if (glowEffect != null)
|
||||
{
|
||||
glowEffect.Stop();
|
||||
}
|
||||
|
||||
// Reset glow rotation
|
||||
if (glowTransform != null)
|
||||
{
|
||||
glowTransform.localRotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
// NOTE: Tap pulse scale is handled by BoosterPackDraggable, not here
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Handler Overrides (Block when in Opening Slot)
|
||||
|
||||
protected override void HandleDragStarted(DraggableObject draggable)
|
||||
{
|
||||
// Don't call base if effects are suppressed (in opening slot)
|
||||
if (_effectsSuppressed)
|
||||
return;
|
||||
|
||||
base.HandleDragStarted(draggable);
|
||||
}
|
||||
|
||||
protected override void HandleDragEnded(DraggableObject draggable)
|
||||
{
|
||||
// ALWAYS reset canvas sorting, even when effects are suppressed
|
||||
if (canvas != null)
|
||||
{
|
||||
canvas.overrideSorting = false;
|
||||
}
|
||||
|
||||
// Skip other drag end effects if suppressed (in opening slot)
|
||||
if (_effectsSuppressed)
|
||||
return;
|
||||
|
||||
base.HandleDragEnded(draggable);
|
||||
}
|
||||
|
||||
protected override void HandlePointerEnter(DraggableObject draggable)
|
||||
{
|
||||
// Don't call base if effects are suppressed (in opening slot)
|
||||
if (_effectsSuppressed)
|
||||
return;
|
||||
|
||||
base.HandlePointerEnter(draggable);
|
||||
}
|
||||
|
||||
protected override void HandlePointerExit(DraggableObject draggable)
|
||||
{
|
||||
// Don't call base if effects are suppressed (in opening slot)
|
||||
if (_effectsSuppressed)
|
||||
return;
|
||||
|
||||
base.HandlePointerExit(draggable);
|
||||
}
|
||||
|
||||
protected override void HandlePointerDown(DraggableObject draggable)
|
||||
{
|
||||
// Don't call base if effects are suppressed (in opening slot)
|
||||
// This allows the BoosterPackDraggable to handle tap pulse itself
|
||||
if (_effectsSuppressed)
|
||||
return;
|
||||
|
||||
base.HandlePointerDown(draggable);
|
||||
}
|
||||
|
||||
protected override void HandlePointerUp(DraggableObject draggable, bool longPress)
|
||||
{
|
||||
// Don't call base if effects are suppressed (in opening slot)
|
||||
// This allows the BoosterPackDraggable to handle tap pulse itself
|
||||
if (_effectsSuppressed)
|
||||
return;
|
||||
|
||||
base.HandlePointerUp(draggable, longPress);
|
||||
}
|
||||
|
||||
protected override void HandleSelection(DraggableObject draggable, bool selected)
|
||||
{
|
||||
// Don't call base if effects are suppressed (in opening slot)
|
||||
if (_effectsSuppressed)
|
||||
return;
|
||||
|
||||
base.HandleSelection(draggable, selected);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
|
||||
if (_boosterDraggable != null)
|
||||
{
|
||||
_boosterDraggable.OnBoosterOpened -= HandleBoosterOpened;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user