Tải bản đầy đủ (.docx) (72 trang)

Đồ án tìm hiểu xây dựng cấu trúc trò chơi trong unity

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (4.41 MB, 72 trang )

ĐẠI HỌC QUỐC GIA THÀNH PHỐ HỒ CHÍ MINH

TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN
KHOA CÔNG NGHỆ PHẦN MỀM

ĐỒ ÁN 1

Tìm hiểu xây dựng cấu trúc trị chơi trong Unity
______________________________________________________________

Giáo viên:

Ths. Huỳnh Hồ Thị Mộng Trinh

Sinh viên:

Tưởng Thành Long - 18520227
Nguyễn Nhật Long - 18520304

Thành phố Hồ Chí Minh, tháng 6 năm 2021


NHẬN XÉT CỦA GIÁO VIÊN
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...


………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...
………………………………………………...………………………………………………...


………………………………………………...………………………………………………...
………………………………………………...……………..
……… , ngày …… tháng…… năm 2021
Người nhận xét
(Ký tên)


LỜI CÁM ƠN
Những trang đầu tiên của báo cáo này chúng em xin gửi lời biết ơn sâu sắc
và chân thành nhất từ nhóm chúng em đến giáo viên Ths Huỳnh Hồ Thị
Mộng Trinh vì đã tận tình hướng dẫn chúng em hồn thành đồ án này tốt

nhất có thể, nếu khơng có sự hướng dẫn của cơ có lẽ chúng em sẽ khơng
thể hồn thành được tốt đến vậy.
Trong q trình hồn thiện sản phẩm cũng như báo cáo khó tránh khỏi
những sai sót, mong nhận được góp ý từ các thầy cơ để chúng em có thể
cải thiện bản thân trong những dự án lần sau. Một lần nữa xin chân thành
cám ơn mọi người đã ủng hộ chúng em trong dự án lần này.

- Nhóm thực hiện -


MỤC LỤC
Chương 1: Tổng quan đề tài

1

1.1. Giới thiệu đề tài……………………………………………………………………………...1
1.2. Mục tiêu đề tài………………………………………………………………………………..1
1.3. Đối tượng nghiên cứu……………………………………………………………………. 1
1.4. Các nghiên cứu liên quan………………………………………………………………. 2
1.5. Ý nghĩa khoa học & thực tiễn của đề tài………………………………………….2
Chương 2: Tổng quan Unity

3

2.1 GameEngine là gì?………………………………………………………………………….. 3
2.2 Unity……………………………………………...………………………………………………..5
2.2.1. Mono……………………………………………...……………………………………... 6
2.2.2. Unity……………………………………………...………………………………………. 6
2.2.2.1. Scene……………………………………………...……………………………… 7
2.2.2.2. GameObject……………………………………………...…………………….7

2.2.2.3. Component……………………………………………...……………………..8
2.2.2.4. Các Component có sẵn…………………………………………………... 8
2.2.2.5. Quản lý tài nguyên…………………………………………………………..9
2.2.2.6. Luồng game…………………………………………………………………..10
2.3. Các game làm bằng Unity……………………………………………………………..11
2.4. Các vấn đề trong Unity………………………………………………………………….11
Chương 3: Vấn đề mẫu - Tetris

12

3.1. Cách thực hiện thông thường.……………………………………………………...12
3.1.1. Cấu trúc……………………………………………………………………………….. 12
3.1.1.1. Cell prefab……………………………………………………………………. 12
3.1.1.2. Block…………………………………………………………………………….. 12
3.1.1.3. Spawner……………………………………………………………………….. 15
3.1.1.4. NormalTetrisController…………………………………………………16
3.1.2. Hoạt động……………………………………………………………………………..17
3.1.3. Kết luận………………………………………………………………………………...19
3.2. Sử dụng kiến trúc MVC.……………………………………………………………….. 19
3.2.1. Cấu trúc……………………………………………………………………………….. 19


3.1.1.1. Model…………………………………………………………………………….19
3.1.1.2. View……………………………………………………………………………... 22
3.1.1.3. Controller……………………………………………………………………… 26
3.1.2. Hoạt động……………………………………………………………………………. 27
3.1.3. Kết luận……………………………………………………………………………….. 29
3.3. So sánh và đánh giá…………………………………………………………………….. 31
3.3.1. Tính đầy đủ………………………………………………………………………….. 31
3.3.2. Tính dễ hiểu…………………………………………………………………………. 31

3.3.3. Tính kết dính………………………………………………………………………… 32
3.3.4. Tính tái sử dụng…………………………………………………………………… 32
3.3.5. Tính hiệu quả………………………………………………………………………. 32
3.3.6. Chỉ số………………………………………………………………………………….. 33
3.4. Quy trình thực hiện……………………………………………………………………… 37
3.4.1. Timeline………………………………………………………………………………. 37
3.4.2. Phân chia công việc……………………………………………………………... 37
3.4.3. Công cụ………………………………………………………………………………... 38
3.4.4. Kết quả………………………………………………………………………………….39
3.5. Kết luận……………………………………………………………………………………….. 39
Chương 4: Một số kiến trúc phần mềm đã nghiên cứu

41

4.1. Entity Component System.…………………………………………………………. 41
4.1.1. Giới thiệu…………………………………………………………………………….. 41
4.1.2, Vấn đề ECS giải quyết:…………………………………………………………. 43
4.1.3. Cách sử dụng…………………………………………………………………….... 45
4.1.4. Ưu điểm / nhược điểm………………………………………………………… 45
4.1.5. Kết luận………………………………………………………………………………...46
4.2. Empty Game Object Manager……………………………………………………… 46
4.2.1. Giới thiệu……………………………………………………………………………... 46
4.2.2. Vấn đề Empty Game Object Manager giải quyết………………….. 47
4.2.3. Cách sử dụng……………………………………………………………………….. 48
4.2.4. Kết luận………………………………………………………………………………...49
4.3. Model View Controller…………………………………………………………………. 49
4.3.1. Giới thiệu……………………………………………………………………………. 49
4.3.2. Cách sử dụng……………………………………………………………………… 50
4.3.3. Kết luận………………………………………………………………………………. 52



Chương 5: Một số design pattern hữu ích.

53

5.1. Observer pattern…………………………………………………………………………. 53
5.2. Command pattern……………………………………………………………………….. 54
5.3. Singleton……………………………………………………………………………………... 55
5.4. Service Locator……………………………………………………………………………..56
5.5. Object Pooling……………………………………………………………………………… 58
KẾT LUẬN

59

TÀI LIỆU THAM KHẢO

61


MỤC LỤC HÌNH ẢNH
Các game engine phổ biến hiện nay …………………………………………………………3
Mơi

trường

phát

triển

game


……………………………………………………………………..4
Giao diện chính của Unity ………………………………………………………………………...6
Tab Scene của Unity (ở chính giữa) …………………………………………………………...7
Inspector của Unity …………………………………………………………………………………. 8
Component SpriteRenderer ……………………………………………………………………. 8
Component Rigidbody …………………………………………………………………………….. 9
Component Camera ………………………………………………………………………………….9
Luồng game của Unity …………………………………………………………………………….10
Hình Cell Prefab ……………………………………………………………………………………...12
Thông tin Block ……………………………………………………………………………………….12
7 BLock trong gameTetris …………………….……………………………………………….. 13
Script blockComponent…………………………………………………………………………...13
Sơ đồ luồng xử lý rơi ………………..……………………………………………………………. 14
BlockComponent lưu từng Cell trong mảng 2 chiều Transform[,] …………. 15
Script điều kiển loại block spawn ……………………………………………………..……. 15
Thông số của NormalTetrisController ……………………………………………….….. 16
Sơ đồ luồng Update của GameController ……………………………………………… 17
Luồng hoạt động của GameController …………………………………………………...17
Hình ảnh game và cấu trúc bên dưới ………………………………….….
…………..…. 18
Ảnh minh hoạ cơ chế kick của Tetris ……………………………………..……….
…...... 20
7 khối cơ bản của Tetris …………………………………………….
………………………….. 21
Khởi tạo viên Tetris ……………………………………………………………………….………. 22


Script được chia tách thành nhiều file ………………………………………….……….. 24
Component Button …………….…………………………………………………………………. 25

Cách gắn OnClick cho Button thông dụng ……………………………………........... 25
OnClick được gán trong script, giảm thiểu thời gian tìm kiếm trên UI ……. 26
Flow xử lý của DropdownController, vòng lặp chính của game ……………… 27
Flow xử lý khi player bấm vào một nút …………………………………………………...27
Sơ đồ các class của bản MVC ……………………………………………………………….. ..28
Cấu trúc dữ liệu bên dưới của board……………………………………………..……....

28

Quy trình chung nên có của các game……………………………………………………..29
Luồng scene chung các game………………………………………………………………….30
Bên trái là view MVC, bên phải là Controller của bản thường…………………..
31
Trạng thái khi profile ..……………………………………………………………………………. 33
Biểu đồ thông số profile ………………………………………………………………………... 34
Biểu đồ thông số profile ………………………………………………………………………... 35
Thông số bộ nhớ bản MVC …………………………………………………………………….. 36
Timeline ………………………………………………………………………………………………... 37
Hình minh hoạ Entity …………………………………………………………………………….. 41
Hình minh hoạ Component …………………………………………………………………... 42
hình tham khảo từ trang GameDev về một bản design component ……… 42
Ví dụ thỏ và cá voi …………………………………………………………………………………. 44
Vấn đề kế thừa kim cương …………………………………………………………………….. 45
Ví dụ về lặp code khi cài đặt cơ chế chung cho scene bình thường ……….. 47
Sử dụng GameLoopManager để thoát khỏi
yêu cầu bắt buộc dùng ECS của Unity ………………………………………………….... 48
Mơ hình MVC …………………………………………………………………………………………. 50
Mơ hình AMVCC, thêm Application và Component ………………………………...51



Hình dung Observer ……………………………………………………………………………….53
Input khơng nên được gán cứng …………………………………………………………….54
Mọi lớp đều có thể truy cập đến Singleton ……………………………………………. 55
Mơ hình Service Locator ……………………………………………………………………….. 56
Hình dung Object pooling ……………………………………………………………………... 58


Chương 1: Tổng quan đề tài
1.1. Giới thiệu đề tài
Đề tài của chúng em là “Tìm hiểu xây dựng cấu trúc trò chơi trong Unity”
Hướng đến cấu trúc tối ưu dễ mở rộng và bảo trì.

1.2. Mục tiêu đề tài
Hầu như khơng có một kiến trúc chương trình game Unity thống nhất.
Đa số các forum đều nói điều này, và kiến trúc game hầu như phụ thuộc
vào kinh nghiệm mà có. Nên chúng em muốn hướng đến xây dựng 1
package khn mẫu chung có thể áp dụng một cách linh hoạt cho mọi loại
game. Tuy nhiên, chúng em biết rằng khơng thể có một giải pháp giải
quyết tất cả vấn đề. Đó là lý do vì sao nhiều kiến trúc tồn tại và chưa bị
thay thế hoàn toàn.

1.3. Đối tượng nghiên cứu
Hướng đến các game developer sử dụng Unity với kinh nghiệm trung
bình. Mục đích là để những lập trình viên có thể phân chia game của mình
ra nhiều mảng để dễ dàng mở rộng, thay đổi, thử nghiệm cũng như bảo trì
khi mà game đã mở rộng ra. Thêm nhiều chức năng, hình ảnh, âm thanh,
…. Game sẽ nở ra và source code bắt đầu xấu đi vì có những tính năng
khơng theo tính tốn ban đầu và cấu trúc code hiện đã q dính nhau để
có thể thay đổi nên dẫn đến code xấu đi rất nhiều và từ đó lỗi (hay bug)
cũng nối đi nhau xuất hiện. Hiện nay các video, khóa học hay hướng dẫn

trên mạng rất nhiều, nhưng đa số chỉ hướng dẫn sử dụng 1 chức năng nhỏ
lẻ chứ khơng nói làm sao để đưa chức năng đó vào hệ thống mà vẫn giữ
cho nó hoạt động trơn tru và hồn hảo nhất, nên để tránh tình trạng áp
dụng những video đó một cách bừa bãi, chúng em sẽ nghiên cứu 1 hệ
1


thống có thể mở rộng và rành mạch để các lập trình viên mới cũng như cũ
có thể tham khảo và áp dụng theo.

1.4. Các nghiên cứu liên quan
Các nghiên cứu kiến trúc của chương trình nói chung, và kiến trúc của
game nói riêng, đều là các nghiên cứu liên quan. Mặc dù Unity là một
framework với những ưu điểm và nhược điểm của nó, việc áp dụng một
cách tự do và theo nhu cầu các kiến trúc khác nhau là một yếu tố quan
trọng của lập trình viên.

1.5. Ý nghĩa khoa học & thực tiễn của đề tài
Unity là một cơng cụ lập trình game tốt, với nhiều chức năng hỗ trợ cho
các vấn đề lập trình game thường gặp phải. Mặc dù có những bất lợi, các
cơng cụ hỗ trợ Unity đem lại chắc chắn sẽ khiến việc prototype cũng như
phát triển game nhanh chóng hơn.
Hiện tại, chưa có một kiến trúc Unity thống nhất, và quy trình phát triển
game với Unity chưa có một tiêu chuẩn rõ ràng, dẫn đến nhiều vấn đề
trong việc phát triển, mở rộng, và bảo trì game. Dường như mỗi dự án phải
thiết kế một hệ thống riêng từ đầu. Với một kiến trúc đa dụng và linh hoạt,
việc sử dụng Unity để xây dựng game sẽ dễ dàng hơn.
Tất nhiên, sẽ khơng bao giờ có một giải pháp thật sự giải quyết vấn đề
“thiết kế chương trình”. Vì vậy văn bản này cũng sẽ cung cấp một số ý
tưởng thiết kế để bạn tự quyết định kiến trúc chương trình của mình.


2


Chương 2: Tổng quan Unity
2.1 GameEngine là gì?

Các game engine phổ biến hiện nay

Một game engine (phần mềm làm game) là một phần mềm được viết để
thiết kế và phát triển video game (trò chơi điện tử), hiểu đơn giản nó là loại
phần mềm trung gian kết nối tương tác của nhiều ứng dụng trong cùng 1
hệ thống với nhau. Có rất nhiều loại game engine dùng để thiết kế trò chơi
cho các hệ máy như hệ consoles hay máy tính cá nhân (PC). Chức năng cốt
lõi của game engine phần lớn nằm trong tiếp xúc với phần cứng hay cơng
cụ dựng hình (kết xuất đồ họa) cho các hình ảnh 2 chiều (2D) hay 3 chiều
(3D), công cụ vật lý (hay cơng cụ tính tốn và phát hiện va chạm), nhập/đọc
tập tin chứa âm thanh và đồ họa, hát âm thanh, nâng cấp hình ảnh động
(hoạt hình), trí tuệ nhân tạo cho những nhân vật trò chơi, phân luồng, tạo
dòng dữ liệu xử lý, quản lý bộ nhớ, dựng ảnh đồ thị, và (nếu cần) kết nối
mạng. Quá trình phát triển trò chơi tiết kiệm được rất nhiều thời gian và
kinh phí vào việc tái sử dụng và tái thích ứng một phần mềm làm game để
tạo nhiều trị chơi khác nhau. (Theo wikipedia)
3


Mơi trường phát triển game

Nói một cách đơn giản hơn, GameEngine là 1 “bộ cơng cụ”, nó có giao
diện, có cấu trúc, có kéo thả và có hệ thống cùng những chức năng đi kèm

để hỗ trợ người lập trình viên làm game. Ví dụ: ai cũng biết rằng khi cho 1
vật có vận tốc, nó sẽ di chuyển theo vận tốc đó mỗi frame, nhưng mỗi khi
code 1 game mới ta phải code lại những phần xử lý đó? Khơng cần vì
gameEngine sẽ hỗ trợ bạn, Unity có “Rigibody” và “Rigidbody2D” hỗ trợ bạn
về những xử lý liên quan tới vật lý (chỉ là mô phỏng thôi). Với những thành
phần có sẵn như vậy, có thể bạn sẽ nghĩ: vậy tơi muốn tự viết thêm thì
sao?
Khơng sao cả, GameEngine sẽ cho bạn viết những script xử lý riêng và
4


dùng tronog game của mình nhưng phải theo quy tắc nhất định của
GameEngine mà bạn sử dụng.

Vậy dùng GameEngine có lợi gì và hại gì?

Ưu điểm

Nhược điểm

Triển khai nhanh chóng và dễ dàng

Phải học cách sử dụng GameEngine
đó

Nhiều cơng cụ hỗ trợ

Nhiều lập trình viên dùng cơng cụ
nhưng khơng hiểu cơng cụ đó bên
dưới hoạt động thế nào


Cấu trúc rành mạch, “hình ảnh hóa”
(Visualize) những dịng code khơ
khan ngày trước, kéo thả dễ dàng

Do cấu trúc nhìn có vẻ đơn giản
nên ít ai chú ý và đầu tư vào 1 hệ
thống thật sự để tăng hiệu quả cho
game

2.2 Unity
Unity là một phần mềm làm game đa nền tảng, các nền tảng được hỗ
trợ hiện nay là Android, IOS, Linux, macOS, Windows, Windows Phone, ...
Unity3D cung cấp một hệ thống toàn diện cho các lập trình viên, từ
soạn thảo mã nguồn, xây dựng cơng cụ tự động hóa đến trình sửa lỗi nên
cũng khá dễ sử dụng. Ngơn ngữ lập trình chính của Unity là C#, nhưng cốt
lõi bên dưới lại là C++, ngồi ra cịn có hỗ trợ cho Javascript.
Unity cũng tận dụng chức năng của các thư viện phần mềm như engine
mô phỏng vật lý PhysicX của Nvidia, OpenGL và Direct3D để kết xuất hình
ảnh 3D, OpenAL cho âm thanh, … nên nó hỗ trợ rất mạnh cho cơng việc
lập trình game.

2.2.1. Mono
Mono là phiên bản open-source của .NET framework, được thiết kế đa
5


nền tảng. Chương trình làm từ Mono có thể chạy bất cứ đâu có máy ảo
mono.


2.2.2. Unity

Giao diện chính của Unity

2.2.2.1. Scene

Tab Scene của Unity (ở chính giữa)

Đây là nơi để bạn thao tác và thiết kế các thành phần cho game của mình.
6


Về bản chất là 1 list chứa toàn bộ những gameObject ban đầu cùng những
component chứa trong các component đó. Có nhiều cách thiết lập hệ
thống scene như splashScene load trước để tải addressable hay asset
bundle về.
2.2.2.2. GameObject
Mỗi GameObject sẽ mặc định có 1 component chứa thơng tin vị trí, góc
xoay, độ phóng to (Transform hoặc RectTransform). Bạn cóo thể thêm
gameObject con cũng như các component cho nó tùy thích và tùy vào thiết
kế hệ thống và ý đồ của dự án bạn đang thực hiện.

2.2.2.3. Component

Inspector của Unity

Trong Unity ngơn ngữ sử dụng chính là C#, tuy nhiên để biến nó thành
component, nghĩa là nó có thể kéo vào GameObject và có các hàm chức
năng như Start, Awake,... Tuy nhiên lỗi của những người mới bước chân
vào Unity là biến tồn bộ mọi thứ thành component vì tính tiện dụng của

nó và cơ chế component của Unity.
2.2.2.4. Các Component có sẵn
SpriteRenderer: Hiển thị Sprite
7


Component SpriteRenderer

Rigidbody: Mơ phỏng vật lý

Component Rigidbody

Camera: Thu nhận hình ảnh scene lên màn hình

8


Component Camera

2.2.2.5. Quản lý tài nguyên
Bạn có thể import Atlas chứa nhiều file hình vào Unity, miễn sao kích cỡ
phải luôn là mũ của 2 như 1024, 2048 pixel để Unity có thể nén atlas lại khi
build ra, giảm được đáng kể kích thước của ứng dụng

9


2.2.2.6. Luồng game

Luồng game của Unity


10


2.3. Các game làm bằng Unity
Hiện nay có thể nói Unity là game engine phổ biến nhất thế giới cho người
mới lẫn chun nghiệp. Các game đình đám có thể kể đến như: Superhot,
Outer Wild, Hollow Knight, ...

2.4. Các vấn đề trong Unity
Cấu trúc chương trình cơ bản của Unity, nếu khơng có sự biến đổi
đặc biệt gì, là các thành phần GameObject độc lập với nhau. Theo phân
loại cấu trúc chương trình của Shaw & Garlan [3], cấu trúc chương trình
Unity là 'parallel communicating processes'.
Cấu trúc này có nhiều điểm mạnh cũng như điểm yếu. Tuy nhiên,
một nguyên tắc quan trọng của thiết kế kiến trúc chương trình là tính linh
hoạt, thay đổi theo từng u cầu chương trình. Có nhiều game khơng thể
biểu diễn tốt dưới cấu trúc chương trình này. Cụ thể có một số vấn đề sau:
1: Unknown Order
Người lập trình khơng thể xác định thứ tự các hàm Update và Start của
MonoBehaviour chạy. Mặc dù điều này tốt trong một mơi trường
multithread, thi thoảng có một số đoạn code cần chạy trước mốt số khác,
và Unity không cung cấp một cách để làm điều này.
2: Low cohesion
Các thành phần của Unity được thiết kế làm các thành phần riêng biệt và
tách rời. Mặc dù điều này khiến code tái sử dụng dễ hơn và giảm sự gắn
kết, nó cũng khiến các thành phần khó sử dụng với nhau.
3: Unmanaged Plug-and-Play
Các script của GameObject đều là Plug-and-Play, có thể kéo thả vào
GameObject, nhưng các script này hầu như khơng được kiểm sốt. Muốn

kiểm sốt chúng, phải có một cách để reference các script liên quan.

11


Chương 3: Vấn đề mẫu - Tetris
3.1. Cách thực hiện thông thường.
Ở phiên bản này chúng ta sẽ không áp dụng bất kỳ nguyên tắc hay design
pattern nào, không phân chia rành mạch logic, data hay view gì cả mà sẽ
tận dụng cấu trúc ECS có sẵn của Unity.

3.1.1. Cấu trúc
3.1.1.1. Cell prefab
Đây là ô sẽ cấu tạo nên các block của Tetris
game. Gameobject này chỉ có SpriteRenderer
và Transform để lưu vị trí, vị trí của từng cell
này sẽ được quy đổi ra số nguyên để chuyển
thành vị trí lưu trong grid.

Hình Cell Prefab

3.1.1.2. Block

Thơng tin Block

Khi đã có các cell cơ bản rồi ta chỉ cần tạo hình cho chúng đúng với các
block cơ bản trong game tetris:
12



7 Block trong game Tetris

Ưu điểm của cách làm này là người lập trình có thể sáng tạo nhiều hình
khối dễ dàng bằng cách kéo thả và cân chỉnh bằng tay các khối này mà
không cần biết quá nhiều về cấu trúc bản chất của các khối.

Đi kèm với block này sẽ là 1 script BlockComponent dùng để điều khiển
block

Script BlockComponent

Các thơng số có thể chỉnh trực tiếp cho từng block trong prefab là tâm xoay
của block và thời gian rơi.

public

Vector3

rotationPoint

public

float

fallTime

public static

int


height

public static

int

width

private static

Transform [ , ]

grid

13


Sơ đồ luồng xử lý rơi

Khi block mới được spanw ra, nó sẽ rơi từ từ theo thời gian đã nhập trước
đó trong prefab, đồng thời nhận và xử lý input theo từng frame của người
chơi
Script này đặc biệt có 3 tham số static đó là width, height, và grid là mảng 2
chiều dùng để chứa các GameObject Cell dùng để kiểm tra và

14


BlockComponent lưu từng Cell trong mảng 2 chiều Transform[,]


3.1.1.3. Spawner

Script điều kiển loại block spawn

Đúng như tên gọi spawner sẽ nhận được gọi khi block hiện tại đặt xuống vị
trí cố định và block mới được spawn ngẫu nhiên dựa trên các mẫu prefab
có sẵn, sau khi spawn, currentBlock trong NormalTetrisController sẽ được
cập nhật lại.
15


×