확장하기 02: 줄 사라짐 이펙트
💬 이 실습을 하기 전에
이번에는 코루틴에 더해 “콜백” 이라는 말이 나옵니다. 어렵게 느껴져도 괜찮습니다.
콜백은 “나중에, 그때 가서 이 함수를 한 번 불러 줘“라고 미리 적어 두는 것이라고 생각하면 됩니다. 여기서는 “줄 지우기 이펙트가 다 끝난 뒤에 점수 올리고 다음 블록 나오게 해 줘”라고 넘기는 용도로 씁니다.
코드는 설명된 순서대로 복사해서 넣고, 한 번에 이해가 안 되어도 0.2초 대기 후 줄이 사라지는 것만 먼저 확인해 보세요.
📌 이 실습은?
가득 찬 줄을 지울 때, “바로 사라지기” 대신 잠깐(0.2초) 대기한 뒤 사라지게 하는 연습입니다.
🎯 목표 (한 줄 요약)
- 가득 찬 줄을 바로 지우지 않고 0.2초 기다린 뒤 지운다.
- 그 이펙트가 끝난 뒤에만 점수(AddScore)와 다음 블록 스폰(SpawnNext)을 하도록 한다.
🔷 “콜백”이 뭔가요? (어렵다면 넘겨도 됩니다)
지금 ClearFullRows() 는 “지운 줄 개수”를 바로 반환합니다.
이펙트를 넣으면 0.2초를 기다린 뒤 지우기 때문에, 기다리는 동안에는 아직 “몇 줄 지웠는지”를 알 수 없습니다. 그래서 코루틴이 다 끝났을 때 “이제 줄 개수를 알려 줄게, 그때 점수랑 다음 블록 처리해 줘”라고 **콜백(Action
비유: “밥 10분 끓인 뒤에 나한테 전화해 줘”라고 하면, 10분 뒤에 전화하는 것이 콜백입니다. 여기서는 “0.2초 대기 후 줄 다 지운 뒤, 이 함수(linesCleared 넘겨서) 한 번 불러 줘”가 콜백입니다.
🛠️ 1. GameBoard 수정
GameBoard.cs 파일을 열고, 아래를 추가합니다. (기존 ClearFullRows 는 그대로 두고, ClearFullRowsWithEffect 와 코루틴을 새로 만듭니다.)
할 일 요약:
- 파일 맨 위에 using System; 과 using System.Collections; 가 있는지 확인. 없으면 추가.
- 클래스 안쪽 맨 아래(다른 메서드들 다음)에 ClearFullRowsWithEffect 메서드와 ClearFullRowsRoutine 코루틴을 통째로 복사해서 넣기.
색 바꾸기는 생략해도 됩니다. “0.2초 대기 후 제거”만 해도 이펙트로 충분합니다.
GameBoard.cs 추가분 (기존 코드 아래에 추가)
using System;
using System.Collections;
// ... 기존 using ...
public class GameBoard : MonoBehaviour
{
// ... 기존 멤버와 메서드 전부 유지 ...
/// <summary>가득 찬 행을 찾아 잠깐 대기(이펙트) 후 지우고, 지운 줄 개수를 콜백으로 전달.</summary>
public void ClearFullRowsWithEffect(Action<int> onComplete)
{
StartCoroutine(ClearFullRowsRoutine(onComplete));
}
IEnumerator ClearFullRowsRoutine(Action<int> onComplete)
{
int linesCleared = 0;
for (int y = 0; y < height; y++)
{
if (IsRowFull(y))
{
// 잠깐 대기 (0.2초) — 나중에 여기서 색 깜빡임 등 추가 가능
yield return new WaitForSeconds(0.2f);
ClearRow(y);
MoveRowsDown(y);
y--;
linesCleared++;
}
}
onComplete?.Invoke(linesCleared);
}
}
파일 맨 위에 using System; 과 using System.Collections; 가 있는지 확인하세요.
🛠️ 2. TetrisBlock 수정 (LockPiece에서 이펙트 버전 호출)
TetrisBlock.cs를 열고, LockPiece() 메서드 전체를 아래 “교체 후” 코드로 바꿉니다.
바꾸는 이유만 쉽게 말하면:
- AddToGrid 까지는 그대로.
- this.enabled = false; 로 “이 블록은 이펙트 동안 더 이상 움직이지 마”라고 막아 둠.
- ClearFullRows() 대신 ClearFullRowsWithEffect( … ) 를 부르고, 괄호 안에 “끝났을 때 할 일”을 적어 줌 → 그 안에서 점수, 다음 블록, Destroy 처리.
TetrisBlock.LockPiece() 교체
기존:
public void LockPiece()
{
gameBoard.AddToGrid(this);
int linesCleared = gameBoard.ClearFullRows();
FindObjectOfType<GameController>().AddScore(linesCleared);
FindObjectOfType<Spawner>().SpawnNext();
Destroy(gameObject);
}
교체 후:
public void LockPiece()
{
gameBoard.AddToGrid(this);
this.enabled = false; // 이펙트 동안 낙하·입력 멈춤
gameBoard.ClearFullRowsWithEffect((linesCleared) =>
{
FindObjectOfType<GameController>().AddScore(linesCleared);
FindObjectOfType<Spawner>().SpawnNext();
Destroy(gameObject);
});
}
✅ 동작 확인
- 줄이 가득 차서 블록이 고정되면, 약 0.2초 뒤에 줄이 사라지고, 그다음 점수가 올라가고 다음 블록이 나와야 합니다.
- this.enabled = false 때문에 이펙트 동안에는 해당 블록이 더 이상 내려오지 않습니다.
❓ 막혔을 때 확인해 보세요
| 증상 | 확인할 것 |
|---|---|
| 컴파일 에러 (Action, IEnumerator) | GameBoard.cs 맨 위에 using System; 과 using System.Collections; 가 있는지 확인. |
| 줄이 안 사라지거나 점수가 안 올라감 | TetrisBlock의 LockPiece() 를 전체 교체했는지 확인. 기존 ClearFullRows() 호출이 남아 있으면 안 됨. |
| 블록이 이상하게 움직이거나 두 개 나옴 | this.enabled = false; 를 AddToGrid(this) 다음 줄에 넣었는지 확인. |
💡 (선택) 줄이 사라지기 전 색 깜빡이기
가득 찬 행의 칸들에 잠깐 노란색을 주려면, ClearFullRowsRoutine 안에서 IsRowFull(y) 인 경우:
- 그 행의 grid[x, y] 에 있는 Transform에서 Renderer (또는 SpriteRenderer)를 가져온다.
- material.color 를 노란색으로 바꾼다. (예:
Color.yellow) - yield return new WaitForSeconds(0.2f); 후 ClearRow(y) 를 호출한다.
(Renderer가 없거나 2D 스프라이트라면 SpriteRenderer.color 로 바꿀 수 있습니다. 재질 인스턴스가 생길 수 있으므로, 초심자 단계에서는 “0.2초 대기”만 해도 충분합니다.)
💡 정리
- **ClearFullRowsWithEffect(Action
onComplete)** 로 "이펙트가 끝난 뒤 줄 개수를 넘겨 주는" 흐름을 만들었다. - 코루틴 안에서 yield return new WaitForSeconds(0.2f) 로 “잠깐 보여 준 뒤 제거”를 했다.
- LockPiece에서는 ClearFullRows() 대신 ClearFullRowsWithEffect(콜백) 을 쓰고, 콜백 안에서 AddScore, SpawnNext, Destroy 를 호출했다.
| ← 01 게임 시작 카운트다운 | 확장하기 목차 | 코루틴 개념 |