Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 5

Chương 5

NHIỀU MÀN CHƠI


Tạo màn chơi mới
Tiếp theo ta sẽ tạo ra nhiều màn chơi, quản lý màn chơi, tạo điểm để qua màn.
1. Kiểm tra 1 số đối tượng như MainCamera, Player, Coin, Enemy, Tilemap… đã được lưu vào
Prefabs chưa, nói chung là lôi hết vào Prefabs (Lưu ý là giờ ta làm gì các đối tượng cũng nên cập
nhật nó xuống Prefabs).
2. Vào Assets/Scenes. Chọn scene mặc định và sửa tên thành Level1.
3. Nhân bản Level1 bằng cách chọn nó rồi nhấn ctr+D (command+D trên mac). Sửa tên thành
Level2. (Tương tự có thể nhân bản thành level3,4,5…)

4. Đến đây ta đã có 2 scene giống hệt nhau, mở scene Level2 lên thiết kết lại tilemap (hoặc đơn
giản đổi nền hay làm gì đó để phân biệt).
5. Để project hiểu được các scene phải thêm Level2 vào build, chọn File -> Build Settings. Kéo
scene Level2 vào cửa sổ Build Settings rồi đống cửa sổ lại (chú ý giá trị index ở cuối, nó là thứ tự
của các scene, ta có thể chọn và kéo lên xuống để sắp xếp thứ tự index của các scene).

Tạo điểm exit qua màn


1. Kiếm 1 hình ảnh để qua màn (vi dụ hình cánh cửa, lá cờ….). Kéo vào Hierarchy và sửa tên thành
Exit. Kéo đến vị trí ta muốn qua màn, thêm cho nó 1 BoxCollider2d, check vào isTrigger.

2. Tạo 1 script mới đặt tên NextLevel và áp nó cho đối tượng Exit.
Ở đây ta có thể viết va chạm trong đối tượng Player nhưng tui thích viết script trong đối tượng Exit để
chẻ code ra cho rõ ràng hơn. Ta sẽ viết khi exit chạm vào player thì qua màn, nhưng sẽ có độ trễ 1 giây
trước khi qua màn.
Để tạo ra độ trễ ta dùng Coroutine. Ta tìm hiểu nó 1 tí:
Để 1 hàm sẽ chạy với độ trễ ta gọi hàm đó trong StartCoroutine.
Trong hàm ta dùng IEnumerator ở đầu, bên trong ta dùng yield return new WaitForSecondsRealtime và
truyền vào thời gian muốn trễ, bên dưới lệnh yield ta sẽ viết các lệnh xử lý của hàm như hình bên dưới.

3. Mở script NextLevel, viết các hàm OnTriggerEnter2D và LoadNextLevel như sau:


private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.tag=="player")//va cham voi player
{
StartCoroutine(LoadNextLevel());//goi ham voi do tre
}
}
IEnumerator LoadNextLevel()
{
yield return new WaitForSecondsRealtime(1f);//tre 1 giay
//lay index cua scene hien tai
int currentindex = SceneManager.GetActiveScene().buildIndex;
int nextindex = currentindex + 1; //scene tiep theo

//vuot khoi so scene dang co


if(nextindex==SceneManager.sceneCountInBuildSettings)
nextindex = 0;//hoac xu ly ket thuc game...

SceneManager.LoadScene(nextindex);
}
4. Nhớ nhúng using UnityEngine.SceneManagement;
5. Chạy và test Player chạm Exit sẽ delay 1 giây rồi qua màn.
6. Kéo đối tượng Exit vào Prefabs để lưu lại.

GAME SESSION
Game Session
Mục tiêu tiếp theo là: Người chơi có số mạng cố định, khi người chơi chết sẽ giảm mạng và restart lại
màn chơi hiện tại. Khi hết mạng thì sẽ gameover, khi đó game sẽ reset lại từ đầu cả mạng và điểm số.
Vấn đề là:
Game có nhiều scene, khi người chơi chết thì restart lại màn chơi sẽ reset lại luôn mạng, điểm. Vấn đề
tiếp theo là duy trì điểm và mạng giữa các màn chơi. Ta phải tạo ra dữ liệu được giữ xuyên suốt trong
toàn bộ game.
Để giải quyết vấn đề trên ta dùng Game Session (một dạng của mẫu Design Pattern tên Singleton), nó sẽ
được tạo ra 1 lần duy nhất và duy trì suốt giữa các màn chơi cũng như toàn game và nó sẽ lưu trữ các
giá trị như điểm, mạng…
1. Trong Hierarchy tạo 1 đối tượng mới và đặt tên là GameSession.
2. Tạo 1 script mới đặt tên là GameSession và gán script GameSession cho đối tượng GameSession.
3. Mở script GameSession, bỏ hàm Start và Update mặc định và viết thêm hàm Awake như bên
dưới. Hàm này sẽ lấy số lượng đối tượng GameSession đang có, nếu có rồi nó sẽ hủy để không bị
clone thành 1 bảng nữa, còn chưa có thì nó không cho hủy khi load lại. Tức là nó sẽ sinh ra 1 lần,
rồi không cho hủy cũng như không cho tạo thêm.
private void Awake()
{
//so luong doi tuong GameSession
int numbersession = FindObjectsOfType<GameSession>().Length;
//neu no co nhieu hon phien ban thi se huy no
if (numbersession > 1)
Destroy(gameObject);
else
DontDestroyOnLoad(gameObject); //khong cho huy khi load
}

Quản lý mạng chơi, load scene với GameSession


Tiếp theo ta sẽ viết thêm các hàm để quản lý mạng sống, luật là có tổng cộng 3 mạng, nếu đụng quái hay
bẩy thì mất 1 mạng và phải chơi lại Scene (level) đó, còn nếu bị mất hết mạng thì hủy hết và chơi lại từ
đầu. Và các mạng cũng được duy trì qua các Scene vì ta đã dùng Session (Singleton).
4. Khai báo 1 biến mới

public int playerlives = 3;

5. Viết thêm hàm PlayerDeath, hàm này sẽ xét nếu còn mạng sẽ gọi hàm TakeLife để đoạt mạng
còn nếu hết mạng rồi thì sẽ gọi hàm ResetGameSession để reset toàn bộ và chơi lại từ đầu (hàm
này sẽ được các script khác khi chết sẽ truy xuất tới vào gọi)
//khi player chet
public void PlayerDeath()
{
if(playerlives>1)//con mang
{
TakeLife();
}
else
{
ResetGameSession();
}
}

6. Viết tiếp hàm TakeLife, hàm này khi còn mạng, sẽ trừ mạng và nạp lại Scene hiện tại.
//doat mang
public void TakeLife()
{
playerlives--;//giam mang
//lay index cua scene hien tai
int currentsceneindex = SceneManager.GetActiveScene().buildIndex;
//load lai scene hien tai
SceneManager.LoadScene(currentsceneindex);
}

7. Viết thêm hàm ResetGameSession, hàm này khi không còn mạng nào sẽ reset toàn bộ game để
chơi lại từ đầu.
//het mang, reset toan bo, choi lai tu dau
public void ResetGameSession()
{
SceneManager.LoadScene(0);//load lai Scene 0
Destroy(gameObject); //destroy GameSession luon
}
8. Quay lại unity, chạy game, test từ Level1, khi qua Level2 thì mặc dù không có kéo đối tượng
GameSession và nhưng đối tượng GameSession vẫn có vì đã được tạo ở Level1 và duy trì qua
Level2 luôn. Ta chọn GameSession và nhìn thuộc tính ta thấy có biến Playerlive=3.

9. Tiếp theo ta sẽ lưu GameSession và triển khai cho toàn bộ Level, đầu tiên mở Level1 và kéo
GameSession vào Prefabs, sẵn kéo đối tượng Exit vào Prefabs luôn.
10. Mở tiếp Level2 và kéo GameSession từ Prefabs ra Hierarchy. Nếu có nhiều level thì có thể kéo
Exit vào Level2 để có thể qua Level3 luôn.
11. Chạy ct từ Level1, chạy qua Level2 và để ý đối tượng GameSession, bên Level2 có nhưng không
được tạo thêm mà được tạo từ Level1 và duy trì qua Level2, bên Level2 thấy có rồi nên không
tạo nữa.
12. Mở file PlayerController3 , tìm tới hàm Die và bổ sung thêm lệnh. Lệnh này mỗi lần bị Die sẽ tìm
tới đối tượng GameSession và gọi hàm PlayerDeath.
FindObjectOfType<GameSession>().PlayerDeath();

13. Chạy ct, từ Level1 cho Player chết để test biến Playerlives giảm xuống và Reset lại màn hiện tại,
cho player chạy qua Level2 để thấy Playerlives duy trì 2, cho Player chết để thấy Playerlives giảm
còn 1 và reset lại Level2, cho Player chết luôn để thấy game over và reset lại toàn bộ từ đầu.
Quản lý điểm với Game Session
Tương tự như mạng, điểm cũng lưu trong GameSession và khi ta chạm coin sẽ tăng điểm lên.
1. Mở file GameSession bổ sung thêm biến toàn cục
public int score = 0;
2. Viết thêm hàm
public void AddScore(int num)
{
score += num;
}
3. Mở file CoinPickup. Trong if va chạm với player bổ sung thêm lệnh để tăng điểm
FindObjectOfType<GameSession>().AddScore(10);
4. Chạy ct, ăn các coin để thấy điểm score mỗi lần tăng lên 10.

Tự làm: viết thêm để Player đạp đầu enemy thì tăng score lên 5.

You might also like