Bài viết nằm trong chuỗi Hướng Dẫn Hiện Thực Game Zero Với Unity, cung cấp kiến thức trong việc xây dựng 1 game trên Unity, đồng thời biết cách tổ chức project hiệu quả trong Unity.
Trong phần 3 này sẽ hướng dẫn hoàn thiện gameplay với các tính năng thú vị hơn với người chơi là hiển thị điểm số hiện tại và thời gian (Progress Timer).
Lưu trữ điểm số và hiển thị
Static.s_score
Điểm số trong Zero được sử dụng duy nhất trong Gameplay, do Zero không hỗ trợ các tính năng như Leaderboard (bảng xếp hạng), hay Statistic (bảng thống kê các số liệu người chơi đạt được), … nên hoàn toàn có thể lưu trữ điểm số ở GameManager. Tuy nhiên, khuyến khích hiện thực theo hướng tổng quát hoá, có thể tái ứng dụng trong các trò chơi khác có quy mô lớn hơn.
Để hiện thực tổng quát, đặt biến lưu trữ điểm số tại lớp Static (dòng 13, Statics.cs):
public static int s_score;
Thuộc tính này có thể truy cập ở bất cứ nơi nào trong project. Do lớp Static
được đặt trong namespace Stdio
nên cần lưu ý dòng code sau (dòng 2, GameManager.cs):
using Stdio;
namespace Stdio
phải đượcimport
trước khi sử dụng bất cứ thành phần nào chứa trong nó.s_score
sẽ được cập nhật lại khi người chơi vượt qua 1 level.
Hàm CheckAnswer
thuộc script ButtonManager như sau:
public void CheckAnswer() { GameManager manager = GameObject.FindGameObjectWithTag("GameManager").GetComponent<GameManager>(); if(gameObject.name == "BtnRight") { if (manager.IsRightAnswer()) manager.GenerateNextCalculation(); else Static.S_Debug("You're wrong!"); } else { if (!manager.IsRightAnswer()) manager.GenerateNextCalculation(); else Static.S_Debug("You're wrong!"); } }
Với mỗi button đều có 2 trường hợp xảy ra. Nếu s_score
được cập nhật trực tiếp ở mỗi button, cần sao chép đoạn code đó sang vị trí tương ứng ở button còn lại, chưa kể đến 2 phím mũi tên được gắn chức năng của 2 button đã hiện thực ở bài viết trước. Do đó hiện thực theo cách này sẽ khá bất tiện và kém hiệu quả.
Nếu để ý, sẽ thấy với mỗi trường hợp trả lời đúng, hàm GenerateNextCalculation
sẽ được gọi để tạo thử thách tiếp theo, bất kể là với phím hay button nào. Do đó, thêm đoạn code xử lý s_score
vào hàm GenerateNextCalculation
như sau (dòng 90, GameManager.cs):
Static.s_score++;
Nếu xem xét kĩ hàm Start
tại GameManager.cs sẽ thấy khởi tạo giá trị cho s_score
bằng -1
. Do ngay khi game bắt đầu, cho tạo 1 thử thách đầu tiên dẫn đến việc tăng s_score
lên khi chưa bắt đầu chơi. Đây chỉ là 1 mẹo nhỏ nhưng cần lưu ý để hiện thực game được hiệu quả hơn.
Hiển thị điểm số ra màn hình
Để đưa s_score
hiển thị lên màn hình game, sử dụng UI Text. Trước khi thao tác với UI, cần import thư viện như sau (dòng 3, GameManager.cs):
using UnityEngine.UI;
Khởi tạo 1 thuộc tính có kiểu Text để tiện xử lý (dòng 19, GameManager.cs). Sau khi cập nhật điểm số, thuộc tính này cũng được thay đổi theo như sau (dòng 91, GameManager.cs):
m_scoreText.text = Static.s_score.ToString();
Đến đây, có thể chạy thử và xem thành quả đạt được.
Hiện thực Progress Timer
Progress Timer trong Zero được biểu diễn dưới dạng Clock (đồng hồ). Khoảng thời gian đã trôi qua của 1 level được thể hiện bằng tỉ lệ phần được vẽ của Clock.
Unity hỗ trợ hiện thực đúng như mong muốn với UI Image. Các bước hiện thực Progress Timer:
- Tạo UI Image, đặt tên là
ProgressTimer
. - Kéo sprite
spr_clock
từ spritesheet vào thuộc tínhSource Image
của Progress Timer. - Chọn
Image Type
làFilled
. Các thông số còn lại được thiết lập như sau:
Chú ý thuộc tính Fill Amount. Thuộc tính này quyết định tỉ lệ hình sẽ được hiển thị, 0 tương ứng với hình hoàn toàn không được hiển thị và 1 tương ứng với toàn bộ hình đều được hiển thị.
Đồng bộ Progress Timer với thời gian thực của game
Progress Timer tạo ra ở trên chỉ là hình ảnh hiển thị của thời gian chơi trong game, quản lý thời gian với Script.
Để quản lý thời gian, sử dụng 2 thuộc tính CurrentTime và LevelTime.
- CurrentTime là thời gian hiện tại, tính từ thời điểm 1 level mới được bắt đầu.
- LevelTime chính là thời gian tối đa người chơi có được trong level đó.
Ngoài ra, để thay đổi tỉ lệ vẽ của ProgressTimer, sử dụng thêm 1 thuộc tính UI Text. Khai báo các thuộc tính trên như sau (dòng 21-23, GameManager.cs):
private float m_currentTime; private float m_levelTime; public Image m_progressTimer;
Tương tự như phần hiển thị điểm số đề cập ở trên, phải import thư viện UnityEngine.UI trước khi sử dụng Image.
Tại hàm Start
, thêm phần khai báo giá trị ban đầu cho các thuộc tính trên như sau (dòng 39-40, GameManager.cs):
m_levelTime = 1.5f; m_currentTime = 0f;
Quản lý thời gian và cập nhật Progress Timer (dòng 49-53, GameManager.cs):
m_currentTime += Time.deltaTime; if (m_currentTime >= m_levelTime) m_currentTime = 0f; m_progressTimer.fillAmount = m_currentTime / m_levelTime;
Thuộc tính fillAmount
của Progress Timer truyền vào từ Unity Editor sẽ được cập nhật lại tương ứng với currentTime.
Lưu ý :
fillAmount
sẽ thay đổi trong khoảng(0, 1)
currentTime
thay đổi trong khoảng(0, levelTime)
.
Do đó chúng ta sẽ điều chỉnh lại currentTime
theo tỉ lệ phù hợp trước khi gán vào fillAmount
.
Cuối cùng, để currentTime
cập nhật lại từ đầu sau mỗi level, thêm dòng sau vào hàm GenerateNextCalculation
(dòng 93, GameManager.cs):
m_currentTime = 0f;
Đến đây cơ bản gameplay đã hoàn thiện. Bạn có thể chạy thử và xem thành quả đạt được. Nếu vẫn còn thắc mắc hoặc khó khăn, bạn đọc có thể xem thêm project đính kèm.
Download Project
Bài chung series
- Hiện Thực Game Zero Với Unity - Phần 1 - Nhận Sự Kiện Button.
- Hiện Thực Game Zero Với Unity - Phần 2 - Hiện Thực Gameplay.
- Hiện Thực Game Zero Với Unity - Phần 3 - Điểm Số Và Progress Timer.
- Hiện Thực Game Zero Với Unity - Phần 4 - Scene Và Popup.
- Hiện Thực Game Zero Với Unity - Phần 5 - Âm Thanh Và Effect.