Trong chương này bạn sẽ học cách tạo một script, viết một số mã nguồn đơn giản, sau đó liên kết script này với một đối tượng game.Bạn đã cài đặt MonoDevelop cùng với Unity trong Chương 1
Trang 1là nơi ghép nối bố cục cảnh của bạn bằng cách đặt các đối tượng trong đó Còn MonoDevelop là trình soạn thảo script nơi bạn sẽ viết mã nguồn Mã nguồn này sẽ cho các đối tượng game biết cách hành xử, ví dụ như cách phản hồi thao tác đầu vào của người chơi hoặc phản hồi lẫn nhau Script mã nguồn của bạn được đưa vào game khi bạn liên kết nó với một đối tượng game Trong chương này bạn sẽ học cách tạo một script, viết một số mã nguồn đơn giản, sau đó liên kết script này với một đối tượng game.
Bạn đã cài đặt MonoDevelop cùng với Unity trong Chương 1 Có lẽ bạn đã thấy trình soạn thảo này trong thư mục Applications Unity (Hình 2-1), ngoài ra bạn có thể truy cập MonoDevelop trực tiếp từ Trình soạn thảo Unity Đây là lựa chọn mặc định nằm dưới mục External Script Editor trong mục Unity Preferences External Tools (Hình 2-2)
Hình 2-1 Biểu tượng MonoDevelop.app và menu Finder của gói Unity đã tải về
Trang 2Hình 2-2 Menu Unity Preferences
Với dự án AngryBots đã mở sẵn, trong Bảng Project hãy mở thư mục Assets Scripts Animation và nhấn vào biểu tượng PlayerAnimation (Hình 2-3)
Hình 2-3 Biểu tượng script PlayerAnimation trong Bảng Project
Trong bảng Inspector bạn sẽ thấy thông tin bổ sung về nội dung của script PlayerAnimation (Hình 2-4) Bạn có thể mở script này trong MonoDevelop bằng cách nhấn đúp vào file script hoặc nhấn nút Open… (Hình 2-5)
Trang 3Hình 2-4 Biểu tượng script PlayerAnimation trong Bảng Inspector3
Trang 4Hình 2-5 Script PlayerAnimation đã sẵn sàng cho việc chỉnh sửa trong MonoDevelop
AngryBots là trò chơi thú vị và có thể dùng làm công cụ hữu ích để giới thiệu về Unity
và MonoDevelop, nhưng bây giờ đã đến lúc để bắt đầu học cách phát triển game của riêng bạn
Bạn sẽ bắt đầu từ đầu, vì vậy hãy tiếp tục và đóng cửa sổ MonoDevelop lại Nếu
có thông báo nhắc nhở, thì đừng lưu bất cứ thay đổi nào cả Từ menu trên cùng của Trình soạn thảo Unity hãy chọn mục File New Project để mở Project Wizard (Hình 2-6)
Hình 2-6 Menu Unity File New Project và Project Wizard
Đừng lưu bất cứ thay đổi nào đối với AngryBots nếu bạn được nhắc nhở Hãy đặt một cái tên cho dự án mới của bạn và nhấn Create Project Unity sẽ đưa ra một vị trí
và tên dự án mặc định cho bạn Nút Set… sẽ mở ra một cửa sổ Create New Project
để bạn có thể sử dụng làm phương tiện tùy chọn đặt tên và đặt lại vị trí của dự án mới nếu như bạn thấy thế tiện lợi hơn Hãy đặt một cái tên mang tính mô tả cho dự
án của mình nếu bạn thích; bạn có thể đặt lại tên sau này Bạn có thể thấy các gói tài nguyên riêng trong thư mục Standard Packages đã tải về với Unity, nhưng đừng
Trang 5chọn bất kỳ gói nào tại thời điểm này Hãy chắc chắn rằng tab Create new Project được chọn, hãy để thiết lập mặc định là 3D, và tạo dự án mới.
Dự án mới sẽ xuất hiện như mô tả trong Hình 2-7
Hình 2-7 Sự xuất hiện của dự án mới trong giao diện Trình soạn thảo Unity
Chương này cung cấp phần giới thiệu về lập trình Nếu bạn đã có một số kinh nghiệm lập trình thì cũng đừng nên bỏ qua phần này – các ví dụ chứa một số biến và hàm dành riêng và thường dùng trong Unity mà bạn sẽ sử dụng trong các chương tiếp theo
MonoDevelop
Khi Unity tạo ra một dự án mới, trình soạn thảo này sẽ cung cấp cho bạn bộ khung xương (skeleton) của game Bộ khung xương này có các yếu tố cần thiết cơ bản của bất kỳ game nào, vì vậy khi bạn nhấn vào nút Play thì một game trống rỗng sẽ khởi động và sau đó dừng lại khi bạn bỏ chọn nút Play Việc phát triển game là “đắp thịt” vào bộ khung xương này với nội dung kỹ thuật số và sự tương tác với các đối tượng game, môi trường, và các script
Ở menu trên cùng, hãy chọn mục GameObject Create Empty (Hình 2-8)
Hình 2-8 Menu trên cùng của Unity GameObject Create Empty
Trang 6Bạn sẽ thấy đối tượng GameObject mới được liệt kê ra trong khung nhìn Hierarchy, gizmo chuyển đổi của đối tượng trong khung nhìn Scene, và các chi tiết sâu hơn trong mục Inspector (Hình 2-9).
Hình 2-9 Đối tượng GameObject mới trong Trình soạn thảo Unity
Trong mục Inspector, nhấn vào nút Add Component, sau đó chọn mục New Script
từ menu hiện ra Hãy đặt tên cho script là HelloWorld, và đảm bảo rằng ngôn ngữ được chọn là Java Script, sau đó nhấn vào Create and Add để liên kết script này với đối tượng game rỗng (Hình 2-10) Theo quy tắc thì tên này nên mang tính chất mô
tả, và nên được viết hoa chữ cái đầu và không chứa các ký tự đặc biệt hay khoảng trắng, tuy vậy thì dấu gạch dưới vẫn được cho phép sử dụng
Hình 2-10 Cửa sổ xổ ra Add Component để thêm vào một script mới
Script này bây giờ được liệt kê trong Inspector dưới dạng một thành phần của đối tượng GameObject, và bạn sẽ thấy một biểu tượng của script này xuất hiện trong thư mục Assets (Hình 2-11)
Trang 7Hình 2-11 Script mới trong bảng Inspector dưới dạng một thành phần và trong mục Assets của Bảng Project dưới dạng một
biểu tượng
Nhấn một lần lên biểu tượng này để chọn và xem nội dung của script trong Inspector (Hình 2-12)
Hình 2-12 Nội dung của script mới trong bảng Inspector
Bạn có thể mở script này trong MonoBehavior bằng cách chọn mục Open trong Inspector hoặc nhấn đúp lên biểu tượng của script trong thư mục Assets (Hình 2-13)
Trang 8Hình 2-13 Script HelloWorld đã sẵn sàng chỉnh sửa trong MonoDevelop
Tương tự Unity, MonoDevelop cũng có các phím tắt và bạn có thể xem các phím này trong mục MonoDevelop Unity Preferences KeyBindings (Hình 2-13)
Hình 2-14 Menu MonoDevelop Unity Preferences Key Bindings của các phím tắt
Trang 9Khi bạn tạo một script mới, Unity sẽ tự động thêm vào một số thành phần #pragma strict sẽ được thêm vào đầu tất cả các script của bạn Dòng này báo cho trình biên dịch biết rằng các biến phải có khai báo kiểu, bạn sẽ được học chi tiết hơn
về khai báo kiểu trong chương này Unity cũng sẽ tạo ra các hàm Start() và Update() rỗng Bây giờ, hãy tiếp tục và xóa hàm Update() đi, nhớ xóa cả các dấu đóng mở ngoặc đi kèm:
function Update () {
}
Khi script mới được liên kết với đối tượng game, thì hàm Start() sẽ được gọi mỗi khi đối tượng game này tham gia vào một cảnh Trong dự án mẫu này, đối tượng game xuất hiện trong cảnh, vì vậy hàm Start() của đối tượng đã được gọi ngay khi việc chơi game bắt đầu Hãy gõ dòng mã nguồn đầu tiên của bạn giữa hai dấu ngoặc của hàm Start() để xem cách đối tượng này hoạt động
Hình 2-15 Đầu ra “Hello World!” của lệnh print trong bảng Console
Một cách nữa để in ra thông báo trên bảng Console là sử dụng Debug.Log “Gỡ lỗi” (debugging) là quá trình tìm và sửa các lỗi được gọi với tên “lỗi” (bug) trong mã nguồn của bạn Bạn sẽ học chi tiết hơn về cách sử dụng lớp Debug và các hàm (function) của lớp này trong Chương 10 Hãy thay đổi dòng mã của bạn giống như sau:
function Start () {
Debug.Log(“Hello World!”);
}
Lưu lại, chạy đoạn mã này trong Trình soạn thảo Unity bằng cách nhấn vào nút Play,
và nhìn vào bảng Console, bạn cũng sẽ nhìn thầy dòng chữ “Hello World!” như cũ kèm theo một đoạn chú thích nhỏ khác (Hình 2-16)
Hình 2-16 Đầu ra Hello World! của Debug.Log trong bảng Console.
Trang 10Phát triển Game là một quá trình học hỏi liên tục Các bậc tiền bối tại Unity vẫn đang tiếp tục bổ sung nhiều năng lực mới và nền tảng mới để bạn có thể cài đặt game của mình Thậm chí các nhà phát triển dày dạn nhất cũng phải cập nhật những thay đổi
và bổ sung mới nhất một cách thường xuyên nhất bằng cách tham khảo tài liệu hỗ trợ được cung cấp Mỗi dự án game mới có thể có những thứ mà bạn không quen dùng hoặc có thể bạn muốn kiểm tra cẩn thận những thay đổi Như vậy cách tốt nhất với bạn để học UnityScript là tự tạo ra những ví dụ trong cuốn sách này trên Unity và MonoDevelop, bạn sẽ làm quen với việc tham khảo tài liệu hỗ trợ một cách nhanh nhất thông qua việc sử dụng chúng
Hãy dừng game này lại và trở về đoạn script trong MonoDevelop (⌘+Tab là một phím tắt hữu ích khi bạn đang làm việc giữa hai cửa sổ.) Nhấn vào bất cứ đâu trên mục Debug, rồi nhấn ⌘+‘ để mở phần tham khảo viết script Debug.Log trong trình duyệt web của bạn (Hình 2-17)
Hình 2-17 Mô tả về Debug.Log trong phần Scripting Reference của Unity
Bạn sẽ thấy mô tả rằng Debug.Log ghi ra một thông báo tới bảng Console, theo sau là một dòng mã tương tự như dòng mã bạn đã viết
Có một mô tả thứ hai nữa với mã nguồn mẫu cung cấp cho bạn nhiều thông tin hơn trong tình huống có lỗi Thay đổi dòng mã của bạn bằng cách thêm vào tham chiếu tới đối tượng gameObject: Debug.Log("HelloWorld!", gameObject); nhấn
⌘+S để lưu lại, và nhấn vào Play trong Trình soạn thảo Unity Bây giờ thông báo
“Hello World!” sẽ xuất hiện cùng với một số thông tin bổ sung khác do Debug.Log tạo ra (Hình 2-18)
Trang 11Hình 2-18 Đầu ra của Debug.Log trong bảng Console kèm theo phạm vi Object
Bạn sẽ học thêm về gỡ lỗi và cách sử dụng những thông tin này trong các phần sau của cuốn sách Bây giờ thì như thế là đủ vì bạn đã thử nghiệm thành công đoạn mã mẫu từ tài liệu hỗ trợ này
Việc phát triển Game là một quá trình tương tác, bao gồm phương pháp thử và sai
cổ điển Tài liệu hỗ trợ này chứa mã nguồn mẫu đầy đủ Sẽ có lúc các phần diễn giải được viết có thể không dễ hiểu ngay đối với bạn, nhưng khi bạn xem mã nguồn mẫu hoạt động thì bạn sẽ hiểu rõ hơn Đừng ngại thử làm những điều nhỏ nhặt này!Một mẹo nhỏ trong quá trình thử nghiệm đó là: Trong mục Preferences Key Bindings bạn sẽ thấy rằng MonoDevelop cũng sử dụng các phím tắt như ⌘+Z để Undo và Shift+⌘+Z để Redo giống như bạn thấy bảng các phím nóng của Unity bên dưới mục Edit
Khi bạn gõ mã nguồn của mình, bạn có thể thấy rằng MonoDevelop luôn cố gắng trợ giúp bạn với chức năng tự động điền (autocomplete) Hãy lựa chọn và nhấn phím Tab, khi đó MonoDevelop sẽ tự điền phần còn lại (Hình 2-19) Đây là chức năng hữu ích giúp tăng tốc và đặc biệt là tăng độ chính xác bằng cách giảm khả năng lỗi chính
tả gây ra các lỗi nhỏ phiền toái
Hình 2-19 Những gợi ý xổ ra của tính năng tự động điền trong MonoDevelop
Ngoài ra MonoDevelop còn trợ giúp bạn xác định các lỗi Hãy thử tạo một lỗi bằng cách bỏ qua dấu chấm phẩy ở cuối dòng lệnh và lưu lại Trong Trình soạn thảo Unity, bạn sẽ thấy một cảnh báo được hiển thị trong bảng console, kèm theo gợi ý trợ giúp
từ Unity để sửa lỗi này (Hình 2-20)
Hình 2-20 Cảnh báo lỗi trong bảng Console
Trang 12Nếu bạn cố tình nhấn vào Play, thì Unity sẽ liên tục nhắc bạn sửa lỗi này (Hình 2-21).
Hình 2-21 Cảnh báo lỗi bổ sung trong bảng Console sau khi cố tình nhấn Play trong tình trạng còn lỗi
Biểu tượng cảnh báo lớn màu đỏ thật khó chịu, vì vậy hãy tiếp tục và sửa mã nguồn, sau đó lưu lại
Biến và Hàm
Máy tính chỉ làm theo những gì bạn bảo Chúng sử dụng các biến để chứa dữ liệu,
và làm theo các chỉ thị để điều khiển và xử lý dữ liệu mà bạn đưa vào các hàm.Hãy thay đổi mã nguồn của bạn giống như sau:
đó Vậy nên bạn và các đồng đội của mình hãy học cách xây dựng một thói quen tốt
đó là viết chú thích mã nguồn trong quá trình làm việc
Chú ý Việc chú thích mã nguồn luôn hữu ích trong quá trình gỡ lỗi Bạn có thể vô
hiệu hóa đoạn mã bằng cách chuyển chúng thành chú thích thay vì xóa chúng đi, sau
đó bạn có thể dễ dàng kích hoạt lại khi cần thiết.
Với chú thích trên nhiều dòng, bạn hãy đặt ký tự /* ở đầu và */ ở cuối chú thích hay đoạn mã Hãy thử kiểu chú thích này trong hàm Start()
Trang 13Biến (variable) được dùng để lưu trữ và truy xuất (lấy) dữ liệu Đây là cách mà
chương trình game ghi nhớ những thứ cần thiết cho việc quản lý gameplay
Hãy nhìn vào dòng mã sau:
var myVar : int = 8;
Chia dòng mã thành các phần sau:
(1) (2) (3) (4) (5) (6) (7)
var myVar : int = 8 ;
1 Khai báo biến với lệnh var
2 Tên biến Tên biến nên mang tính mô tả, điều này sẽ giúp cho mã nguồn của bạn dễ đọc hơn Bạn có thể sử dụng bất kỳ ký tự nào trong bảng chữ cái và dấu gạch dưới, nhưng không được dùng dấu chấm hay các ký tự đặc biệt khác Một thói quen tốt giúp cho mã nguồn của bạn dễ đọc hơn đó là tuân thủ các quy ước lập trình chuẩn Quy ước chuẩn trong việc đặt tên biến đó
là nếu ký tự đầu tiên của tên biến là một chữ cái thì nó không được viết hoa
3 Dấu hai chấm phân tách tên biến và kiểu dữ liệu
4 Kiểu dữ liệu của biến, trong trường hợp này int là kiểu số nguyên (integer)
5 Toán tử gán, được dùng để gán giá trị cho biến mà bạn vừa khai báo và đặt tên Bạn có thể không cần gán giá trị cho một biến kiểu integer khi khai báo
6 Giá trị được gán cho biến, trong trường hợp này là kiểu integer Integer là toàn bộ các số bao gồm cả số âm (được biểu thị bằng dấu trừ ở trước) Dấu phẩy và dấu cách không được cho phép – ví dụ 24, 0, và –3 là các số integer hợp lệ nhưng 2,500 thì không, còn 2500 thì được
7 Dấu chấm phẩy báo hiệu kết thúc lệnh Tất cả các lệnh phải kết thúc bằng một dấu chấm phẩy
Trong hàm Start(), thông báo mà Debug.Log đã in ra bảng Console chính là giá trị của biến myVar Lưu và nhấn play để xác nhận điều này
Biến chứa dữ liệu, còn hàm thì thực hiện một công việc gì đó Các chỉ thị cho quá trình thực hiện hàm được chứa bên trong cặp dấu ngoặc Hãy xem những thành phần của hàm Start():
Trang 141 Khai báo hàm với từ khóa dành riêng function.
2 Đặt tên hàm Tên hàm bắt đầu bằng các chữ cái in hoa
3 Các đối số mang thông tin được truyền tới hàm Các dấu đóng mở ngoặc là bắt buộc, vì vậy nếu không có đối số thì chúng sẽ được để rỗng
4 Dấu mở ngoặc nhọn báo hiệu bắt đầu nội dung của hàm
5 Các chỉ thị của hàm tuân theo định dạng của các câu lệnh – trong ví dụ này,
là lệnh Debug.Log
6 Dấu đóng ngoặc nhọn báo hiệu kết thúc hàm Vì đây là điểm kết thúc hàm chứ không phải là lệnh, do vậy không cần sử dụng dấu chấm phẩy ở đây.Lưu ý rằng MonoDevelop đã lùi đầu dòng lệnh Debug Việc lùi đầu dòng này giúp cho mã nguồn dễ đọc hơn Theo đó, bạn có thể dễ dàng xác định riêng từng khối
mã MonoDevelop sẽ thực hiện việc này tự động cho bạn, nhưng đôi khi bạn nhận thấy rằng mình cần sắp xếp lại mã nguồn cho dễ đọc hơn Trong mục MonoDevelop Preferences Key Bindings Edit bạn sẽ thấy các phím tắt z+] để lùi đầu dòng hoặc ⌘+[ bỏ lùi đầu dòng (tiến ra ngoài), các phím này sẽ di chuyển khối lệnh có kích thước bất kỳ nào được bạn bôi đậm Hãy thử điều này với lệnh Debug, sau đó với toàn bộ hàm Start Thật dễ dàng, đúng không nào?
Để xem nhanh các toán tử số học (Bảng 2-1), hãy thay dòng mã Debug trong hàm Start bằng các dòng sau:
Trang 15Hình 2-22 Kết quả đầu ra từ các toán tử số học
Bạn có thể đã biết bốn toán tử đầu tiên Toán tử lấy phần dư là một phương tiện cho phép bạn lấy phần dư, trong ví dụ trên là phần dư của phép chia 6 cho 2 Thử thay đổi 6 thành 5, lưu, và nhấn play Lần này thì dòng cuối cùng của đầu ra là 1, chính
là phần dư của phép chia 5 cho 2
Tương tự hầu hết các ngôn ngữ lập trình khác, UnityScript cũng tuân theo thứ tự chuẩn của các phép toán, trong đó phép nhân và phép chia được ưu tiên hơn phép cộng và phép trừ
Chỉnh sửa hàm Start về như sau:
print(6+2*4);
Đọc từ trái qua phải, tổng của 6 và 2 là 8, nhân với 4 là 32 Lưu và nhấn nút play,
và bạn sẽ thấy rằng Unity nhân 2 với 4 trước thành 8, sau đó cộng với 6 để trả về đầu ra là 14
Bạn có thể thay đổi thứ tự tính toán bằng cách sử dụng các dấu đóng mở ngoặc Các toán tử trong dấu đóng mở ngoặc có thứ tự cao hơn Thay đổi dòng mã đó như sau:
kiểu dữ liệu, gồm string, boolean, và nhiều kiểu dữ liệu phức tạp hơn Thực ra, bạn
đã sử dụng kiểu chuỗi trong những dòng mã nguồn đầu tiên của mình:
print("Hello World!");
Chuỗi ở trong dòng lệnh trên là các ký tự chứa trong dấu nháy kép Phép nối
(concatenation) là thuật ngữ dùng cho việc ghép hai chuỗi độc lập với nhau thành một chuỗi duy nhất Hoặc diễn đạt theo một cách khác là bạn đã “cộng” các chuỗi với nhau, nhưng điều quan trọng là bạn học được các thuật ngữ chính xác khi được
Trang 16giới thiệu, và điều này sẽ giúp bạn thuận lợi hơn khi thực hiện tìm kiếm trợ giúp trên diễn đàn trong mục Unity Answers hoặc sáng suốt hơn khi rơi vào những nơi hỗn độn Hãy chỉnh sửa mã nguồn của bạn như sau:
#pragma strict
// khai báo biến myVar kiểu integer và gán giá trị bằng 8
var myVar : int = 8;
var myString1 : String = “Hello “;
var myString2 : String = “World!”;
var myNewString: String;
Lệnh String.Concat giống với Debug.Log ở chỗ chúng đều chứa toán tử dấu
chấm (dot operator) Toán tử dấu chấm này là một dạng cú pháp viết mã, trong đó
dấu chấm phân tách các từ mã Concat là một thành phần của String, tương tự Log là một thành phần của Debug Bạn có thể sử dụng phím tắt quen thuộc ⌘+’ trên lệnh String và Debug để xem thêm các thành phần của chúng trong phần Unity Scripting Reference
Hàm Start là ví dụ khá tốt để chứng minh các lý thuyết cơ bản này, nhưng bây giờ bạn cần sẵn sàng để viết hàm riêng của mình Hàm (function) nhận vào các thông
tin, được gọi là đối số (argument), và thực hiện một số thao tác với những thông tin
này, sau đó trả về kết quả tùy theo đó
Xóa các khai báo biến kiểu chuỗi đi và sửa hàm Start như sau:
var myVar : int = 8;
function AddFive (numberFromStartFunction : int) {
var newVar : int;