Professional Documents
Culture Documents
Chương 5
Chương 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).
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.
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
}
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.