Skip to content

Animation System

Overview

BlocKIT uses DOTween for smooth, professional animations. Every action has visual feedback!

Key Animated Elements

1. Shape Dragging

Idle → Grab → Drag → Drop
  ↓      ↓      ↓      ↓
Normal  Scale  Follow  Snap/Return
        up     cursor

Animations: - Scale up when grabbed (1.0 → 1.2) - Smooth follow cursor - Bounce effect on drop - Elastic return if invalid

2. Line Clearing

Line complete
Pulse effect (cells glow)
Fade out
Scale down
Disappear

Duration: ~0.5 seconds total

3. Ghost Preview

Shape over board
Fade in (0 → 0.5 alpha)
Pulse continuously
Change color (green/red)

GhostPulse Component: - Sine wave alpha animation - Smooth color transitions - Always visible but not distracting

4. Floating Score

Points earned
Text appears at position
Float upward
Fade out
Destroy

NewFloatingScore: - Moves up 100 pixels - Fades from 1.0 → 0.0 - Different colors based on value - Queued system (shows one at a time)

5. Game Over

No moves left
Dim background
Scale popup from 0 → 1
Bounce overshoot
Show final score

PopupAnimator: - Elastic scale in - Background fade to dark - Button press effects

Animation Components

GhostPulse

Makes ghost preview pulse smoothly.

// Parameters:
baseAlpha = 0.3f       // Starting opacity
amplitude = 0.2f       // How much it pulses
speed = 2.0f           // Pulse speed

What it does:

Alpha oscillates:
0.3 → 0.5 → 0.3 → 0.5
(Smooth sine wave)

FloatingScore

Animated score popup text.

public void Play(string text, FeedbackType type)
{
    // Set text and color
    // Animate up + fade out
    // Auto-destroy when done
}

NewCleanLine

Handles line clearing animation.

public void AnimateClear(int[] rows, int[] columns)
{
    // 1. Pulse cells
    // 2. Wait briefly
    // 3. Fade out
    // 4. Clear cells
}

Animation Settings

Timing Constants

// In various scripts:
DRAG_SCALE_DURATION = 0.2f
SNAP_DURATION = 0.3f
RETURN_DURATION = 0.4f
CLEAR_DURATION = 0.5f
POPUP_DURATION = 0.3f

Easing Functions

BlocKIT uses different easings:

Effect Easing Feels like
Shape grab OutBack Bouncy
Shape snap InOutQuad Smooth
Shape return OutElastic Springy
Line clear InOutSine Gentle
Popup OutBack Pop!

DOTween Integration

Installation

  1. Get DOTween from Asset Store (free!)
  2. Import to project
  3. Unity will set it up automatically

Basic Usage

// Scale animation
transform.DOScale(1.2f, 0.3f)
    .SetEase(Ease.OutBack);

// Move animation
transform.DOMove(targetPos, 0.5f)
    .SetEase(Ease.InOutQuad);

// Fade animation
image.DOFade(0f, 0.3f)
    .OnComplete(() => Destroy(gameObject));

// Sequence (multiple animations)
Sequence seq = DOTween.Sequence();
seq.Append(transform.DOScale(1.2f, 0.2f));
seq.Append(transform.DOMove(target, 0.3f));
seq.Play();

Custom Animation Examples

Add shake effect when invalid placement

// In NewDraggableShape.cs
void OnInvalidDrop()
{
    transform.DOShakePosition(0.3f, strength: 10f);
    // Shake for 0.3 seconds
}

Add rotation when shape spawns

// In NewShapeSpawner.cs
void SpawnShape(ShapeData data)
{
    var shape = Instantiate(prefab);

    // Start rotated
    shape.transform.rotation = Quaternion.Euler(0, 0, 180);

    // Animate to normal
    shape.transform.DORotate(Vector3.zero, 0.5f)
        .SetEase(Ease.OutBack);
}

Add glow effect on combo

// In NewScoreManager.cs
void OnComboIncrease()
{
    // Pulse combo text
    comboText.transform.DOPunchScale(
        Vector3.one * 0.3f,
        0.5f
    );

    // Change color briefly
    comboText.DOColor(Color.yellow, 0.2f)
        .SetLoops(2, LoopType.Yoyo);
}

Chain animations

// Clear lines one by one
Sequence clearSequence = DOTween.Sequence();

foreach (var line in linesToClear)
{
    clearSequence.AppendCallback(() => 
        AnimateLine(line)
    );
    clearSequence.AppendInterval(0.1f);  // Delay between
}

clearSequence.Play();

Performance Tips

DO:

✅ Reuse tweens when possible ✅ Kill tweens on destroy ✅ Use SetRecyclable(true) for pooled objects ✅ Limit simultaneous animations

DON'T:

❌ Create tweens every frame ❌ Forget to kill tweens ❌ Animate too many objects at once ❌ Use very long durations

Cleanup Example

void OnDestroy()
{
    // Kill all tweens on this object
    transform.DOKill();
    image?.DOKill();
}

Juice Settings

Current "Juice" Level: Medium

Want more/less feedback?

Low Juice (minimal):

DRAG_SCALE = 1.0f      // No scale
SNAP_DURATION = 0.1f   // Instant
POPUP_ENABLED = false  // No popups

High Juice (maximum):

DRAG_SCALE = 1.5f      // Big scale
SNAP_DURATION = 0.5f   // Slow, satisfying
ADD_PARTICLES = true   // Extra effects
ADD_SCREEN_SHAKE = true

Animation Events

Components can trigger events for others:

// Example: Play sound when animation completes
shape.transform.DOMove(target, 0.3f)
    .OnComplete(() => {
        SoundManager.Instance.PlaySnap();
        OnAnimationComplete?.Invoke();
    });

Debugging Animations

View all active tweens:

void Update()
{
    if (Input.GetKeyDown(KeyCode.D))
    {
        Debug.Log($"Active tweens: {DOTween.TotalPlayingTweens()}");
    }
}

Slow motion:

// Make everything slow
DOTween.timeScale = 0.5f;  // Half speed

// Reset
DOTween.timeScale = 1.0f;  // Normal

Common Issues

Animations not working

  • ✅ Check DOTween is installed
  • ✅ Check using DG.Tweening; at top of script
  • ✅ Check object not destroyed mid-animation

Animations stuttering

  • ✅ Reduce number of simultaneous tweens
  • ✅ Use simpler easing functions
  • ✅ Check device performance

Animations not stopping

  • ✅ Call .Kill() in OnDestroy
  • ✅ Check for infinite loops
  • ✅ Verify completion callbacks

What's Next?


Game Feel Tip

Good animations = good game feel! Don't skip this. Even simple tweens make huge difference!