목차
1. Block Movement and Rotation
Each Tetromino (Tetris piece) is controlled by player input and reacts to game events like collisions.
using UnityEngine;
public class Tetromino : MonoBehaviour
{
private float fallTime = 1.0f; // Time for each block to fall
private float fallTimer;
void Update()
{
HandleInput();
HandleFall();
}
private void HandleInput()
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
Move(Vector3.left);
if (Input.GetKeyDown(KeyCode.RightArrow))
Move(Vector3.right);
if (Input.GetKeyDown(KeyCode.UpArrow))
Rotate();
if (Input.GetKeyDown(KeyCode.DownArrow))
Move(Vector3.down);
}
private void HandleFall()
{
fallTimer += Time.deltaTime;
if (fallTimer >= fallTime)
{
Move(Vector3.down);
fallTimer = 0;
}
}
private void Move(Vector3 direction)
{
transform.position += direction;
if (!IsValidPosition())
transform.position -= direction; // Revert if invalid
}
private void Rotate()
{
transform.Rotate(0, 0, -90);
if (!IsValidPosition())
transform.Rotate(0, 0, 90); // Revert if invalid
}
private bool IsValidPosition()
{
foreach (Transform child in transform)
{
Vector2 pos = RoundVector(child.position);
if (!GridManager.IsInsideGrid(pos) || GridManager.IsOccupied(pos))
return false;
}
return true;
}
private Vector2 RoundVector(Vector2 vector)
{
return new Vector2(Mathf.Round(vector.x), Mathf.Round(vector.y));
}
private void OnCollision()
{
GridManager.AddToGrid(this);
GameManager.Instance.SpawnNewBlock();
enabled = false; // Disable script on collision
}
}
2. Grid Management
The grid tracks the position of blocks, manages row clearing, and handles collision detection.
using UnityEngine;
public class GridManager : MonoBehaviour
{
public static int width = 10;
public static int height = 20;
private static Transform[,] grid = new Transform[width, height];
public static bool IsInsideGrid(Vector2 position)
{
return position.x >= 0 && position.x < width && position.y >= 0;
}
public static bool IsOccupied(Vector2 position)
{
return grid[(int)position.x, (int)position.y] != null;
}
public static void AddToGrid(Tetromino block)
{
foreach (Transform child in block.transform)
{
Vector2 pos = RoundVector(child.position);
grid[(int)pos.x, (int)pos.y] = child;
}
CheckForCompleteRows();
}
public static void CheckForCompleteRows()
{
for (int y = 0; y < height; y++)
{
if (IsRowComplete(y))
{
ClearRow(y);
MoveRowsDown(y);
y--; // Recheck the same row after moving
}
}
}
private static bool IsRowComplete(int y)
{
for (int x = 0; x < width; x++)
{
if (grid[x, y] == null)
return false;
}
return true;
}
private static void ClearRow(int y)
{
for (int x = 0; x < width; x++)
{
Destroy(grid[x, y].gameObject);
grid[x, y] = null;
}
}
private static void MoveRowsDown(int clearedRow)
{
for (int y = clearedRow + 1; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (grid[x, y] != null)
{
grid[x, y - 1] = grid[x, y];
grid[x, y] = null;
grid[x, y - 1].position += Vector3.down;
}
}
}
}
private static Vector2 RoundVector(Vector2 vector)
{
return new Vector2(Mathf.Round(vector.x), Mathf.Round(vector.y));
}
}
3. Game Manager
The game manager initializes the game, spawns Tetrominoes, and handles scoring and game over logic.
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager Instance;
public GameObject[] tetrominoPrefabs;
public Transform spawnPoint;
public int score = 0;
private void Awake()
{
if (Instance == null)
Instance = this;
else
Destroy(gameObject);
}
private void Start()
{
SpawnNewBlock();
}
public void SpawnNewBlock()
{
int randomIndex = Random.Range(0, tetrominoPrefabs.Length);
Instantiate(tetrominoPrefabs[randomIndex], spawnPoint.position, Quaternion.identity);
}
public void AddScore(int linesCleared)
{
int points = 100 * linesCleared;
score += points;
Debug.Log("Score: " + score);
}
public void CheckGameOver()
{
for (int x = 0; x < GridManager.width; x++)
{
if (GridManager.IsOccupied(new Vector2(x, GridManager.height - 1)))
{
Debug.Log("Game Over!");
Time.timeScale = 0; // Pause the game
break;
}
}
}
}
Additional Setup
- Create Prefabs for Tetrominoes:
- Design the 7 standard Tetromino shapes (I, O, T, S, Z, L, J) as prefabs using Unity’s editor.
- Attach the
Tetromino
script to each prefab.
- Grid and Spawner Setup:
- Add the
GridManager
script to an empty GameObject in the scene. - Add the
GameManager
script to another GameObject and set thetetrominoPrefabs
array andspawnPoint
.
- Add the
- Scene Hierarchy:
- Ensure you have a clean hierarchy with properly assigned scripts and prefabs.
Features Included in This Implementation
- Block Movement and Rotation: Smooth and collision-aware.
- Row Clearing: Fully functional with dynamic row adjustments.
- Random Block Spawning: Randomized yet modular for reuse.
- Scoring: Reward players for clearing lines.
- Game Over Detection: Ensures game ends when blocks overflow.
By following this guide, you can create a functional Tetris game in Unity that is highly modular and extensible!