-
Xin chào Tên tôi là Mark. Trong nhiều năm, tôi đã muốn tạo ra những trò chơi điện tử của riêng mình bằng cách sử dụng phần mềm
-
như Unity. Unity là công cụ phát triển trò chơi mạnh mẽ đằng sau các tựa game như Cuphead, Neon White, Tunic,
-
Outer Wilds, Hearthstone, Firewatch và thậm chí cả phiên bản làm lại của Pokemon Diamond.
-
Nhưng tôi luôn thấy rằng những hướng dẫn dài dòng, nhiều phần, quanh co khiến tôi buồn ngủ. Tôi
-
không thể học bằng cách quan sát người khác - tôi phải thực hành và tự mình tìm ra mọi thứ.
-
Và vì vậy năm ngoái tôi đã phát triển một giải pháp thực sự hiệu quả. Đó là một kỹ thuật ba bước
-
nơi bạn:một, người ta chỉ cần tìm hiểu những điều cơ bản tuyệt đối về Unity. Sau đó, hai, củng cố những bài học đó bằng những
-
bài tập. Và sau đó, thứ ba, hãy tìm hiểu phần còn lại khi bạn tiếp tục. Và nó hoàn toàn có tác dụng! trong không gian
-
trong khoảng một năm, tôi đã chuyển từ việc sao chép các trò chơi iPhone sang làm việc trên nền tảng giải đố của riêng mình
-
về nam châm. Và tôi đã xuất bản một bài luận video tương tác có hơn 100.000 lượt xem.
-
Nhưng chờ đã, tôi nghe bạn nói! Bạn thực hiện bước một như thế nào? Làm thế nào để bạn học những điều cơ bản,
-
khi phần mềm quá phức tạp để tìm ra?
-
Đối với tôi đó là việc viết ra một danh sách những điều tôi cần biết,
-
bất kể tôi định làm trò chơi gì. Những thứ như làm thế nào để một nhân vật xuất hiện và
-
di chuyển chúng xung quanh màn hình. Làm thế nào để làm cho nội dung xuất hiện và sau đó xóa lại
-
sau đó. Làm thế nào để có va chạm và kết thúc trò chơi cũng như hoạt ảnh và hiệu ứng âm thanh.
-
Sau đó, tôi học được tất cả những điều đó bằng cách tìm kiếm các hướng dẫn dài dòng, đọc tài liệu Unity,
-
Tìm kiếm những từ bí truyền trên Google và thử nghiệm rất nhiều
-
và lỗi. Và mục đích chung của video này là giúp bạn tránh khỏi rắc rối đó.
-
Video này là hướng dẫn mà tôi ước mình có được khi học Unity.
-
Vậy trong 40 phút tới chúng ta sẽ sử dụng công cụ này để tạo Flappy Bird. Không phải vì chúng ta muốn
-
để tạo ra Flappy Bird, nhưng vì để làm lại trò chơi iPhone gây nghiện này, chúng tôi cần
-
để tìm hiểu về cơ bản mọi thứ tôi vừa liệt kê, từ các vật thể sinh sản cho đến kết thúc trò chơi.
-
Hướng dẫn này sẽ đề cập đến từng bước từ tải xuống Unity đến tìm hiểu giao diện người dùng,
-
để viết dòng mã lập trình đầu tiên, để xây dựng một trò chơi mà bạn có thể chia sẻ cùng
-
nhưng ngươi bạn của bạn. Sau đó, khi phần hướng dẫn kết thúc, tôi sẽ chia sẻ một số bước cụ thể tiếp theo mà bạn có thể
-
thực hiện để tiếp tục tự học phần còn lại. Nghe được không? Sau đó hãy bắt đầu.
-
Được rồi, hãy bắt đầu bằng cách tải Unity từ trang web. Tải xuống và cài đặt Unity Hub.
-
Và sau đó bạn sẽ cần tạo một tài khoản miễn phí để thực sự sử dụng nó. Khi xong việc đó,
-
bạn sẽ được yêu cầu cài đặt Unity Editor - Tôi đang sử dụng phiên bản 2021.3 cho hướng dẫn này,
-
nếu bạn đang quan sát một triệu năm sau trong tương lai và tự hỏi tại sao
-
mọi thứ đều khác. Hãy giả vờ như tôi có internet nhanh - Neeooowwwwmm.
-
Chúng ta vẫn chưa xong việc. Trong phần cài đặt, nhấn biểu tượng bánh răng trên Unity Editor và chọn modules.
-
Bạn sẽ thấy Microsoft Visual Studio đã được đánh dấu - đây là phần mềm chúng ta sẽ sử dụng
-
để viết mã lập trình. Vì vậy nhấn tiếp tục. Và cài đặt Visual Studio. Trên màn hình này,
-
cuộn xuống và đánh dấu vào phần phát triển trò chơi bằng Unity và bỏ chọn Unity Hub,
-
bởi vì chúng tôi đã có nó rồi. Không sao đâu. Chúng tôi không cần tạo tài khoản để sử dụng Visual Studio,
-
vì vậy hãy bỏ qua điều đó. Và đừng bận tâm chạy nó, chúng tôi sẽ mở nó sau.
-
Được rồi, bây giờ mọi chuyện đã xong. Vì vậy, trong Unity Hub, hãy chọn dự án mới. Chọn tất cả các mẫu. Và sử dụng 2D,
-
Cốt lõi. Đây là một dự án trống, có một vài cấu hình để phù hợp
-
cho các trò chơi 2D. Đặt tên cho dự án của bạn, nhấn tạo và bắt đầu tạo trò chơi.
-
Ở bước một, chúng ta sẽ làm quen với giao diện người dùng Unity mặc định. Và
-
khi chúng ta khám phá các bảng khác nhau, chúng ta sẽ làm cho chú chim xuất hiện trên màn hình.
-
Phải. Vì vậy, đây là bố cục màn hình mặc định cho Unity và nó được chia thành bốn bảng.
-
Trước hết, ở dưới đây là bảng Project. Điều này sẽ chứa mọi thứ có trong trò chơi của chúng tôi
-
như hình ảnh (sprites), hiệu ứng âm thanh, các kịch bản (scripts), gạch (tiles), phông chữ (fonts), và những thứ khác.. Một số thứ này sẽ được thực hiện
-
trong Unity khi chúng tôi đi cùng. Nhưng chúng ta cũng có thể chỉ cần kéo và thả tệp từ nơi khác trên máy tính của mình.
-
Giống như, tôi đã tạo một số họa tiết cho con chim và cái ống trong Photoshop và tôi sẽ
-
nhập chúng vào dự án của tôi như vậy. Tôi khuyên bạn nên tự làm - điều đó luôn tốt hơn
-
thú vị - nhưng nếu bạn không có khả năng nghệ thuật thì hãy kiểm tra mô tả của những nội dung này.
-
Bảng tiếp theo là hệ thống phân cấp. Phần này chứa tất cả nội dung có trong cảnh hiện tại - trong đó,
-
trong hầu hết các trò chơi, sẽ là một màn chơi. Chúng ta sẽ bắt đầu bằng việc tạo ra con chim,
-
vì vậy hãy nhấp chuột phải và chọn Tạo trống. Điều này đã tạo ra một GameObject trống... vậy đó là gì?
-
Chà, GameObject về cơ bản là một vật chứa vô hình. Nó có một vị trí trong không gian, một sự xoay (rotation),
-
và một tỷ lệ (scale). Sau đó, bạn có thể điền đầy hộp đó bằng các thành phần (components) - để thêm các tính năng bổ sung.
-
Ví dụ: nếu chúng ta thêm thành phần Sprite Renderer, chúng ta có thể đưa hình ảnh con chim vào GameObject.
-
Tuyệt đối mọi thứ trong cấp độ của chúng ta sẽ là GameObject với các thành phần - con chim,
-
các đường ống, thậm chí cả giao diện người dùng và máy ảnh.
-
Tất cả các phép màu này xảy ra trong bảng điều khiển thứ ba, gọi là "Inspector" - nơi bạn tương tác với các GameObject.
-
Vì vậy, khi chúng ta đã chọn GameObject mới, trống của mình, chúng ta có thể đặt tên vào trường trên cùng - hãy gọi nó là
-
Chim. Và chúng ta có thể xem và thay đổi vị trí, góc xoay và tỷ lệ của GameObject trong phần Biến đổi.
-
Bây giờ chúng ta có thể nhấn Thêm Thành phần, chọn Kết xuất và chọn Trình kết xuất Sprite. Để làm được việc này,
-
chúng ta cần điền vào trường sprite - vì vậy chỉ cần kéo hình ảnh con chim từ
-
bảng điều khiển dự án vào hiện trường và viola, chúng tôi có đồ họa!
-
Điều này, tất nhiên, sẽ hiển thị trong bảng điều khiển thứ tư và cuối cùng,
-
gọi là "scene view" (chế độ xem cảnh). Ở đây, chúng ta có thể xem những gì đang có trong cảnh hiện tại của mình và,
-
nếu bạn muốn, bạn có thể sử dụng các công cụ này để di chuyển các đối tượng, thay đổi tỷ lệ, v.v...
-
Phần này có một tab bổ sung để xem trò chơi, cho chúng ta biết trò chơi sẽ trông như thế nào
-
camera chính khi nó đang chạy. Ngoài ra, từ danh sách thả xuống này, chúng tôi có thể đặt độ phân giải hoặc tỷ lệ khung hình
-
để hiểu rõ hơn về hình ảnh khi chơi - vì vậy tôi sẽ chọn 1920 x 1080.
-
Ôi, con chim chiếm quá nhiều không gian. Chúng ta có thể thu nhỏ nó lại, nhưng thực tế hãy
-
chỉ cần thu nhỏ camera. Như tôi đã nói trước đây, bản thân máy ảnh là một GameObject trong hệ thống phân cấp.
-
Và nó có một thành phần camera với các số liệu thống kê mà chúng ta có thể xử lý. Bằng cách thay đổi kích thước, chúng ta có thể thu nhỏ.
-
Tôi cũng sẽ thay đổi màu nền. Đáng yêu.
-
Bây giờ chúng ta có thể nhấn nút phát ở đây để bắt đầu... trò chơi hay nhất thế giới
-
trò chơi nhàm chán. Được rồi, hãy làm cho nó thú vị hơn một chút.
-
Tóm lại nhanh chóng, Unity mặc định có bốn bảng điều khiển. Bảng "Project" chứa toàn bộ tài liệu trong
-
Bảng "Hierarchy" liệt kê tất cả các GameObject trong màn chơi hiện tại. Bảng "Inspector" cho phép chúng ta xem
-
và thay đổi các GameObject đó. Cuối cùng, chúng ta có thể xem màn chơi trong bảng "Scene view" (chế độ xem cảnh).
-
Và GameObject là một thùng chứa vô hình mà chúng ta có thể lấp đầy bằng các thành phần, giống như trình kết xuất sprite.
-
Ở bước hai, chúng ta sẽ sử dụng nhiều thành phần hơn để biến con chim thành một
-
đối tượng vật lý bị ảnh hưởng bởi trọng lực. Và sau đó chúng ta sẽ
-
viết một số mã lập trình để làm cho con chim bay lên khi chúng ta nhấn phím cách.
-
Vậy hãy thêm một thành phần nữa vào con chim của chúng ta: một Rigidbody 2D. Điều này biến con chim của chúng tôi thành một
-
đối tượng vật lý, với trọng lực. Vì vậy, khi chúng ta nhấn play, con chim rơi xuống và rơi khỏi màn hình. Hay đấy.
-
Chúng ta cũng muốn chú chim này có thể tương tác với các vật thể khác, vì vậy hãy thêm một máy va chạm.
-
Máy va chạm vòng tròn 2D.
-
Quay lại khung cảnh, chúng ta có thể thấy máy va chạm dưới dạng đường viền màu xanh lá cây. Đối với tôi nó hơi lệch tâm một chút,
-
vì vậy tôi sẽ sử dụng phần bù để di chuyển nó. Và một thủ thuật thiết kế trò chơi nhỏ - nếu chúng ta thực hiện
-
máy va chạm nhỏ hơn hình ảnh một chút, nó sẽ cho phép người chơi đi qua các đường ống ngay cả khi họ
-
vừa chạm vào mép. Nó mang lại cho trò chơi một chút khoan dung và khiến nó có cảm giác công bằng hơn.
-
Điều cuối cùng cần thêm ngay bây giờ: một tập lệnh. Về cơ bản, điều này cho phép chúng ta tạo ra tùy chỉnh của riêng mình
-
thành phần - nhưng chúng ta sẽ phải tự viết nó bằng mã lập trình. Chọn tập lệnh mới từ
-
danh sách thành phần. Và gọi nó là BirdScript. Sau khi tải xong, hãy nhấp đúp vào tập lệnh
-
trường để mở nó lên. Thao tác này sẽ mở tệp trong Visual Studio mà chúng tôi đã cài đặt trước đó.
-
Vì vậy, chào mừng bạn đến với lập trình! Nó không quá đáng sợ,
-
hứa. Chúng ta sẽ làm chậm thôi. Chúng ta đang viết bằng C Sharp, đó là ngôn ngữ lập trình.
-
Và điều duy nhất cần lo lắng lúc này là hai phần sau: start và update.
-
"Start" dành cho bất kỳ mã nào sẽ chạy ngay khi tập lệnh này được bật. Và nó
-
chạy chính xác một lần. "Update" sẽ chạy liên tục trong khi tập lệnh được bật. Và nó sẽ chạy
-
từng dòng mã, từng khung hình. Lặp đi và lặp lại
-
Vì vậy, điều chính mà chúng ta sắp làm với mã ngay bây giờ là - à, nếu chúng ta quay lại
-
vào Unity - xem các số và trường văn bản này trong các thành phần không? Và làm thế nào chúng ta có thể thay đổi chúng trong
-
trình soạn thảo Unity? Chúng tôi sẽ viết mã để thay đổi các số liệu thống kê này trong khi trò chơi đang chạy.
-
Chỉ là một ví dụ ngớ ngẩn và chúng tôi sẽ xóa nó sau một giây. Bắt đầu,
-
chúng ta có thể gõ gameObject - nó đề cập đến bit này ở đây. Và sau đó là một dấu chấm. Bạn sẽ thấy một danh sách xuất hiện,
-
và nhiều mục đề cập đến nội dung trong "Inspector", như isStatic,
-
"tag," "layer," và "name." Vậy nên, chúng ta hãy chọn "name" (tên). Sau đó, viết dấu bằng (=). Trong dấu ngoặc kép,
-
đặt tên cho con chim của chúng ta. Cuối cùng, chúng ta phải luôn sử dụng dấu chấm phẩy để đánh dấu cuối của một lệnh..
-
Và chúng ta phải luôn lưu tập lệnh trước khi quay lại Unity.
-
Bây giờ, khi chúng tôi chạy trò chơi... tên của GameObject đã được thay đổi. Được!.
-
Được rồi, xóa mã đó. Đó chỉ là để vui vẻ thôi - nhưng nó cho chúng ta thấy
-
cách sử dụng mã lập trình để tương tác với trò chơi. Chúng ta có thể viết lệnh bằng cách chọn ai đó để
-
nói chuyện với - trong trường hợp này, GameObject - và sau đó là chủ đề của cuộc trò chuyện - đó là
-
tên - và sau đó là một lệnh - đổi nó thành Bob Birdington. Chúng tôi sẽ làm điều này rất nhiều.
-
Vì vậy điều chúng tôi thực sự muốn làm là... trong thành phần của Rigidbody 2D, dưới phần "Info",
-
chúng ta sẽ thấy một trường màu xám cho vận tốc. Và chúng tôi muốn
-
viết một số mã để tăng vận tốc hướng lên trên của con chim khiến nó bay lên không trung.
-
Vấn đề là... ban đầu, một tập lệnh chỉ có thể giao tiếp với bit trên cùng của GameObject và
-
sự biến đổi. Hiện tại, tập lệnh này hoàn toàn không biết về các thành phần khác.
-
Vì vậy, chúng ta cần phải sắp xếp điều đó trước tiên. Chúng ta cần tạo một vị trí đặc biệt trên tập lệnh này cho
-
Rigidbody2D - để sau đó chúng ta có thể nói chuyện với nó và gửi lệnh cho nó. Đây được gọi là một tài liệu tham khảo.
-
Chúng ta sẽ tạo tham chiếu ở đây, giữa tên lớp và
-
chức năng bắt đầu. Chúng tôi sẽ viết public Rigidbody2D myRigidbody.
-
Vì vậy, bây giờ chúng ta có một khe để lưu trữ Rigidbody2D. Và chúng tôi có một cái tên mà chúng tôi có thể tham khảo - để đảm bảo
-
chúng ta đang nói về Rigidbody2D cụ thể này. Và bởi vì chúng tôi đã công khai nó, điều đó có nghĩa là chúng tôi có thể truy cập
-
khe này từ bên ngoài tập lệnh. Vì vậy, nếu chúng ta tiết kiệm. Và quay lại Unity, chúng ta sẽ thấy tập lệnh
-
thành phần hiện có trường dành cho Rigidbody2D. Chúng ta có thể kéo thành phần vào khe đó và viola.
-
Chúng tôi đã thiết lập một đường dây liên lạc giữa tập lệnh và Rigidbody.
-
Được rồi, quay lại Visual Studio. Trong bản cập nhật, chúng tôi có thể nhập myRigidbody. Sau đó chấm. Và
-
bây giờ hãy nhìn vào tất cả những điều chúng ta có thể nói đến. Lực cản góc, thang đo trọng lực,
-
khối lượng - đây là tất cả các thuộc tính trên thành phần. Cái chúng ta muốn là tốc độ.
-
Chúng ta muốn đặt số này thành một số mới và vì vậy, giống như tên trước đây, chúng ta sẽ viết một số bằng.
-
Bây giờ cái chúng ta đang viết ở đây là một vectơ, là hai số, biểu thị một vị trí trong
-
không gian 2D. Và trong trường hợp này, nó được dùng để thể hiện hướng bay của con chim. Chúng tôi muốn
-
con chim đi thẳng lên, nên số 0, dấu phẩy sẽ là số tốt. Tôi sẽ sử dụng Vector2.up,
-
đó là một cách viết tắt tích hợp cho dấu phẩy bằng 0. Và để tăng thêm sức mạnh cho nó, tôi sẽ
-
để nhân vectơ đó với một số. Giả sử, 10, con chim sẽ bay lên trời.
-
Bây giờ, như tôi đã nói trước đây, mọi mã trong bản cập nhật sẽ chạy đi chạy lại,
-
mọi khung hình. Vậy nếu chúng ta lưu kịch bản và nhấn play trong Unity... con chim của chúng ta sẽ bay đi. Tạm biệt!!
-
Đó không phải là điều chúng tôi muốn. Chúng tôi muốn điều này chỉ xảy ra khi người chơi chạm vào phím cách. Vì thế
-
đã đến lúc sử dụng phần mã lập trình cơ bản nhất: câu lệnh if.
-
Câu lệnh if giống như một cánh cổng.
-
Bạn có thể bao quanh một số mã bằng hàng rào và mọi khung mã đó sẽ hoàn toàn được
-
làm ngơ. Trừ khi trò chơi đáp ứng một số điều kiện cụ thể được viết
-
trên cổng - trong trường hợp đó cổng mở và mã được đọc và thực thi.
-
Vì vậy, chúng tôi muốn nói "nếu người chơi chạm vào phím cách thì hãy cộng vận tốc đi lên".
-
Để làm điều này... chúng ta có thể viết nếu, và sau đó trong ngoặc chúng ta có thể viết điều kiện. Thời gian này
-
chúng tôi không nói chuyện với một thành phần, chúng tôi đang nói chuyện với chính Unity - cụ thể là hệ thống đầu vào của nó. Vì thế
-
chúng ta sẽ viết Đầu vào. Sau đó, chúng ta có thể chọn GetKeyDown và trong ngoặc là KeyCode.Space. Điều này yêu cầu Unity
-
nếu thanh dấu cách đã được nhấn trên khung này. Và sau đó chúng ta sẽ kết thúc bằng == true.
-
Ghi chú nhanh về dấu bằng - chúng ta sử dụng một dấu để làm cho thứ ở bên trái giống nhau
-
như thứ ở bên phải. Và chúng tôi sử dụng hai nếu chúng tôi chỉ kiểm tra xem
-
thứ ở bên trái cũng giống như thứ ở bên phải. Hay chứ?
-
Dù sao. Vì vậy, đoạn mã này cho biết... nếu phím cách vừa được nhấn, thì... và sau đó chúng ta sẽ
-
sử dụng dấu ngoặc nhọn - đây là hàng rào trong ví dụ tương tự nhỏ của chúng ta - và đặt mã nắp vào đây.
-
Vì vậy, bây giờ trong bản cập nhật - mọi khung hình trò chơi sẽ đi đến cổng và được hỏi "này,
-
phím cách vừa được nhấn phải không?" Nếu có, mã sẽ kích hoạt và con chim sẽ vỗ cánh. Nếu không,
-
nó sẽ bỏ qua mã trong dấu ngoặc nhọn và thử lại khung tiếp theo.
-
Vì vậy - hãy lưu tập lệnh và quay lại Unity. Bây giờ chúng ta có thể nhấn play và tada:
-
con chim bay lên khi chúng ta nhấn phím cách. Bây giờ chúng tôi có
-
đã tạo một ký tự và làm cho nó phản ứng với đầu vào. Đây là một trò chơi điện tử. Hoan hô!
-
Tuy nhiên, nó có cảm giác như rác rưởi. Nắp không đúng và có cảm giác không giống bản gốc
-
trò chơi iPhone. Vì vậy chúng ta có thể thay đổi con số này. Cứu. Mở sự thống nhất. Chạy trò chơi. Không hoàn toàn đúng. Dừng lại. Thay đổi
-
con số. Cứu. Nhưng điều đó thật chậm chạp và ngu ngốc. Hãy làm điều gì đó thông minh hơn.
-
Đầu tiên, chúng ta sẽ tạo một biến. Hãy quay lại phần đầu của tập lệnh và bên dưới
-
tham chiếu của chúng ta đến Rigidbody, hãy tạo một phao công cộng có tên là flap Strength. Một cái phao
-
là số dấu phẩy động - về cơ bản là số có thể có vị trí thập phân. Và
-
sau đó quay lại mã cập nhật của chúng tôi, chúng tôi sẽ nhân vector2.up với độ mạnh của flap, thay vì 10.
-
Bây giờ, quay lại Unity, bạn sẽ thấy thành phần tập lệnh có một trường mới:
-
flapSức mạnh. Và chúng ta có thể thay đổi điều đó bất cứ khi nào chúng ta muốn trò chơi có cảm giác
-
khác biệt. Chúng ta thậm chí có thể thay đổi nó trong trò chơi, nhưng lưu ý rằng bất cứ điều gì bạn thay đổi trong khi
-
trò chơi đang chạy sẽ không lưu khi bạn nhấn dừng. Điều này có nghĩa là bạn có thể chơi với
-
giá trị theo ý muốn của bạn mà không phải lo lắng về việc làm hỏng trò chơi của bạn.
-
Vì vậy, nếu chúng ta gặp rắc rối với flapStrength cũng như thang đo trọng lực trên
-
Rigidbody, chúng ta hy vọng sẽ đạt được điều gì đó khiến chúng ta cảm thấy thích thú. Ah,
-
đổi số qua lại: bạn à, đó là thiết kế trò chơi!
-
Tóm tắt lại.
-
Chúng ta có thể sử dụng mã để thay đổi thuộc tính của một thành phần trong khi trò chơi đang chạy.
-
Theo mặc định, một tập lệnh không thể giao tiếp với các thành phần khác trên gameobject. Bạn phải
-
tạo một đường dây liên lạc bằng cách lưu trữ một tham chiếu đến thành phần cụ thể đó.
-
Chúng tôi tạo tham chiếu trong mã, sau đó điền nó vào Unity bằng cách kéo và thả.
-
Mã trong "Start" chạy một lần khi tập lệnh tồn tại. Mã trong "Update" chạy liên tục,
-
từng khung hình. Tuy nhiên, chúng ta có thể sử dụng câu lệnh if để bỏ qua một số mã, trừ khi một điều kiện được đáp ứng.
-
Và chúng ta có thể sử dụng các biến công khai để thay đổi một số
-
các giá trị trong thanh tra của Unity - ngay cả khi trò chơi đang chạy.
-
Được rồi, bí mật của Flappy Bird là mặc dù nó trông giống một con chim
-
đang lướt qua một thế giới ống dẫn - thực ra không phải vậy. Con chim
-
hoàn toàn đứng yên và các đường ống di chuyển trên màn hình. Vì vậy ở bước ba chúng ta
-
sẽ làm cho các đường ống xuất hiện trên thế giới, di chuyển trên màn hình và sau đó tự xóa chúng.
-
Chúng ta sẽ bắt đầu bằng cách tạo ra đối tượng mà chúng ta muốn sinh ra. Cái này sẽ
-
hai ống di chuyển trên màn hình, từ trái sang phải.
-
Hãy tạo một GameObject khác có tên là pipe. Đặt nó chính xác lên con chim bây giờ,
-
để có được kích thước phù hợp. Và sau đó chúng ta sẽ tạo một đối tượng khác bên trong đối tượng này,
-
gọi là ống trên. Đây là con của cha mẹ đầu tiên của GameObject. Bằng cách này chúng tôi
-
có thể lồng nhiều GameObject và di chuyển tất cả chúng cùng một lúc chỉ bằng cách di chuyển cha mẹ.
-
Vì vậy, hãy lặp lại những gì chúng ta đã làm cho con chim. Thêm trình kết xuất sprite cho hình ảnh đường ống.
-
Và thêm một Collider - lần này là Box Collider 2D. Chúng tôi không cần RigidBody vì nó sẽ không hoạt động
-
bị ảnh hưởng bởi vật lý. Sau đó chúng ta có thể di chuyển nó lên phía trên con chim - nhưng giữ vị trí X bằng 0.
-
Cuối cùng, chúng ta có thể nhân đôi toàn bộ đối tượng đường ống trên cùng này. Gọi nó là ống đáy. Và lật
-
nó lộn ngược bằng cách thay đổi thang Y thành âm một. Sau đó di chuyển nó xuống bên dưới con chim.
-
Như bạn có thể thấy, nếu chúng ta làm hỏng ống GameObject gốc, cả hai ống sẽ di chuyển, chia tỷ lệ,
-
và xoay cùng với nó, với điểm gốc là điểm xoay. Vậy hãy
-
thêm tập lệnh vào đối tượng của cha mẹ này để làm cho nó di chuyển trên màn hình.
-
Chúng ta sẽ bắt đầu bằng cách tạo một biến cho moveSpeed. Nếu chúng ta cho nó một con số ở đây,
-
nó sẽ điền giá trị này làm giá trị mặc định trong Unity. Nhưng chúng ta luôn có thể thay đổi nó ở đó sau.
-
Sau đó chúng ta sẽ viết mã để di chuyển đối tượng trong bản cập nhật. Bây giờ sẽ thật tuyệt nếu chúng ta có thể
-
gõ Transform.position.x và thay đổi trực tiếp số này - nhưng, không, bạn phải thay đổi
-
toàn bộ Vector trong một lần. Ồ, và lần này chúng ta sẽ phải sử dụng Vector3, thay vì Vector2,
-
vì phép biến đổi có ba số. Mặc dù chúng tôi đang tạo trò chơi ở dạng 2D, Unity vẫn
-
về cơ bản là một công cụ 3D và do đó, nó theo dõi độ sâu của vật thể bằng giá trị Z.
-
Vì vậy, đây là những gì chúng tôi sẽ làm. Chúng ta sẽ lấy biến đổi.position hiện tại. Và sau đó bằng nhau.
-
Chúng ta muốn thêm vào vị trí hiện tại của nó, vì vậy hãy viết lại Transform.position. Và
-
thì cộng. Và cuối cùng, trong ngoặc, chúng ta sẽ thực hiện Vector3.left * moveSpeed.
-
Quay lại Unity, nhấn play và vroooof. Như vậy là quá nhanh. Hiện nay,
-
bạn có thể nghĩ rằng bạn có thể thay đổi biến moveSpeed này thành một biến thực sự
-
số nhỏ như 0,001. Và điều đó sẽ có tác dụng - nhưng đó thực sự không phải là vấn đề ở đây.
-
Bạn thấy đấy, mã trong bản cập nhật chỉ chạy thường xuyên nhất có thể. Trên thực tế, nếu chúng tôi kiểm tra số liệu thống kê trong Chế độ xem trò chơi,
-
chúng ta sẽ thấy trò chơi đang chạy với tốc độ hơn 1.000 khung hình mỗi giây. Này,
-
xin lỗi PlayStation 5. 120 khung hình/giây? Pfft, điều đó không có trên Flappy Bird.
-
Và vấn đề thực sự là trò chơi có thể chạy ở tốc độ khác nhau trên các máy tính khác nhau,
-
và chúng tôi không muốn đường ống di chuyển nhanh hơn hay chậm hơn tùy thuộc vào thiết bị của bạn.
-
Trò chơi thực sự đã mắc sai lầm này - trong Dark Souls 2, độ bền của vũ khí đã từng bị ràng buộc
-
vào tốc độ khung hình, do đó kiếm của bạn sẽ gãy nhanh gấp đôi ở tốc độ 60 FPS, so với 30 FPS. Đó là một điều tuyệt vời.
-
May mắn thay, đó là một sửa chữa khá dễ dàng. Chúng tôi chỉ nhân nó với Time.deltaTime.
-
Điều này đảm bảo phép nhân diễn ra như nhau, bất kể tốc độ khung hình. Chúng tôi đã không
-
cần nó cho mã vận tốc vì vật lý chạy trên chiếc đồng hồ nhỏ của chính nó,
-
nhưng nếu không thì chúng ta sẽ cần nó. nếu bạn muốn biết thêm - về điều này, hay bất cứ điều gì thực sự,
-
tài liệu Unity là một nơi tốt để kiểm tra. Bạn sẽ tìm thấy thông tin và mã mẫu.
-
Được rồi, bây giờ với bản sửa lỗi đó, đường ống của chúng ta sẽ di chuyển trơn tru trên màn hình. Đáng yêu.
-
Tiếp theo, chúng tôi muốn tạo ra một hệ thống liên tục tạo ra các đường ống mới. Để bắt đầu,
-
lấy GameObject gốc từ hệ thống phân cấp và kéo nó vào dự án của bạn. Điều này tạo ra một
-
GameObject đúc sẵn. Hoặc nhà tiền chế. Đây giống như một bản thiết kế cho GameObject và chúng ta có thể tạo mới
-
phiên bản của toàn bộ GameObject này- với tất cả các phần tử con, thành phần và thuộc tính của nó. Ồ,
-
và trước khi tiếp tục, chúng ta có thể xóa bản gốc trong hệ thống phân cấp của mình ngay bây giờ. Tạm biệt.
-
Hãy tạo một GameObject mới có tên là Pipe Spawner.
-
Chúng tôi sẽ đặt nó ở bên phải của máy ảnh. Và chúng tôi sẽ tạo một kịch bản cho nó. Mục đích của việc này
-
kịch bản là tạo ra các phiên bản mới của pipe prefab cứ sau vài giây. Và bởi vì đường ống rồi
-
có mã để di chuyển sang trái, đường ống sẽ tự động di chuyển trên màn hình ngay khi xuất hiện.
-
Chúng ta sẽ viết một số mã để tạo ra prefab mà chúng ta vừa tạo. Vì thế
-
chúng ta sẽ bắt đầu bằng cách tham chiếu đến prefab.
-
Ở đây, chúng ta sẽ gõ Public GameObject pipe.
-
Sau đó, trong Unity, chúng ta sẽ sử dụng cùng một phương pháp kéo và thả để lấp đầy chỗ trống, nhưng lần này,
-
thay vì một thành phần, chúng ta sẽ kéo prefab từ bảng điều khiển dự án.
-
Giờ đây,
Unity có một phương thức tích hợp sẵn tốt cho việc tạo ra các đối tượng.
-
GameObject mới. Chúng ta sẽ nhập Instantiate rồi mở dấu ngoặc. Ở đây, lệnh đang hỏi
-
để biết thêm một số chi tiết. chúng ta thực sự có thể lướt qua những thứ này để tìm các công thức khác nhau, tôi không biết nữa?
-
Tôi đoán? Số 4 có vẻ ổn - nó sẽ tạo một đối tượng ở một vị trí và góc quay xác định.
-
Vì vậy, đối với GameObject, chúng ta có thể gõ pipe. Đối với vị trí
-
chúng ta chỉ cần gõ Transform.position để có được vị trí của đối tượng đang giữ
-
kịch bản này. Điều đó sẽ làm cho nó sinh ra trên đầu sinh sản. Và để xoay,
-
hãy sử dụng Transform.rotation để một lần nữa, nó giống với spawner.
-
Hãy chạy nó và chúa ơi, đó không phải là điều chúng ta muốn. Sinh sản hoạt động tuyệt vời,
-
nhưng chúng xuất hiện trong từng khung hình - và chúng tôi muốn chúng xuất hiện
-
ra trong một khoảng thời gian tốt đẹp mà chúng ta có thể kiểm soát. Vì vậy, hãy quay lại Visual Studio.
-
Những gì chúng ta sẽ làm bây giờ là viết một số mã để tạo bộ đếm thời gian. điều này sẽ được tính cho
-
một số giây được chỉ định, chạy một số mã và sau đó bắt đầu đếm lại. Để làm điều này,
-
chúng ta sẽ cần tạo một vài biến. Tỷ lệ sinh sản là bao nhiêu giây
-
giữa các lần sinh sản. Và sau đó đồng hồ bấm giờ là con số đếm ngược. Chúng ta có thể làm được điều này
-
một cái riêng tư vì chúng tôi sẽ không thay đổi nó trong trình chỉnh sửa hoặc bất kỳ nơi nào khác.
-
Trong bản cập nhật, chúng tôi sẽ thực hiện một câu lệnh if khác. Lần này, nếu bộ đếm thời gian nhỏ hơn spawnRate,
-
sau đó chúng tôi muốn làm cho bộ đếm thời gian đếm lên một. Vì vậy, chúng ta sẽ sử dụng bộ đếm thời gian như hiện tại,
-
và thêm Time.deltaTime vào nó. Điều này tạo ra một con số đếm từng khung hình,
-
và hoạt động như nhau bất kể tốc độ khung hình của máy tính của bạn là bao nhiêu.
-
Chúng ta thực sự có thể rút ngắn điều này bằng cách thay đổi nó thành +=, nhưng, đừng cảm thấy như bạn cần phải tạo mã của mình thành
-
ngắn gọn nhất có thể về mặt con người chỉ để tránh nhận được những bình luận khó nghe trên YouTube. Nếu như
-
time=timer + dễ đọc và dễ nắm bắt hơn, thì điều đó hoàn toàn ổn. Bạn
-
sau này luôn có thể đổi sang phiên bản khác khi bạn cảm thấy tự tin hơn.
-
Bây giờ, trước khi tôi nói câu lệnh if giống như một cánh cổng.
-
Và chúng ta có thể thêm một cổng khác vào bên cạnh nó, với cổng khác. Điều này có nghĩa là,
-
nếu điều kiện không được đáp ứng thì bỏ qua mã - thay vào đó hãy thực hiện mã khác.
-
Vì vậy, chúng tôi sẽ đặt mã sinh sản vào đây và đặt lại bộ đếm thời gian về 0. Vì vậy bây giờ, mỗi khung hình, nó
-
hỏi liệu bộ đếm thời gian có nhỏ hơn tốc độ sinh sản hay không. Nếu đúng thì hãy đếm ngược thời gian. Nếu không - tức là
-
bộ đếm thời gian đã thực sự đáp ứng hoặc vượt quá tốc độ sinh sản, sau đó sinh ra một đường ống và bắt đầu lại bộ đếm thời gian.
-
Đặt cái này vào Unity và - khá tốt. Tôi hạnh phúc với điều đó. Vấn đề duy nhất là... chúng ta phải
-
đợi rất lâu để đường ống đầu tiên được tạo ra. Sẽ tốt hơn nếu điều này xuất hiện ngay lập tức, phải không?
-
Bây giờ, chúng ta có thể sao chép và dán mã sinh sản vào phần bắt đầu, vì vậy nó sẽ xảy ra một lần khi bắt đầu.
-
Và sau đó xảy ra nhiều lần trong bản cập nhật. Nhưng đó là một ý tưởng tồi. Nói chung bạn nên cố gắng
-
tránh có mã giống nhau hoặc thậm chí tương tự ở nhiều nơi. Điều gì xảy ra nếu chúng ta muốn
-
để thay đổi cách hoạt động của quá trình sinh sản? Chúng ta sẽ phải tìm và thay đổi nó ở mọi nơi. Không tốt.
-
Thay vào đó, chúng ta có thể đặt mã sinh sản vào một hàm mới và sau đó chỉ cần chạy mã đó
-
chức năng. Vì vậy, ở đây, phần cập nhật bên dưới - nhưng phía trên dấu ngoặc nhọn cuối cùng - chúng tôi sẽ
-
tạo một hàm gọi là void spawnPipe(). Sau đó cắt và dán mã Instantiate vào đó.
-
Bây giờ chúng ta chỉ có thể viết spawnPipe, với dấu ngoặc trống, trong cả update và start. Điều này sẽ chạy
-
tất cả mã trong hàm đó khi những dòng này được thực thi. Và với điều đó được thực hiện, nó sẽ làm cho
-
một đường ống ngay khi trò chơi bắt đầu và sẽ tạo ra các đường ống mới mỗi khi hết giờ. Hoàn hảo.
-
Tuy nhiên - đây là một trò chơi khá nhàm chán phải không? Các đường ống luôn đi ra ở giữa. chúng tôi muốn họ
-
đi ra ở độ cao ngẫu nhiên. Vì vậy, hãy nhớ rằng khi chúng ta viết mã khởi tạo,
-
chúng ta phải chọn một vị trí để vật thể xuất hiện? Chúng tôi sẽ thay đổi giá trị đó.
-
Hiện tại, các đường ống luôn sinh sản ở cùng vị trí với nơi sinh sản. Chúng tôi muốn giá trị X
-
giống nhau... nhưng đối với Y, chúng tôi muốn chọn một điểm ngẫu nhiên ở đâu đó phía trên hoặc phía dưới nơi sinh sản.
-
Vì vậy, hãy tạo một biến công khai cho HeightOffset, có thể là 10.
-
Và sau đó chúng ta sẽ tạo một float có tên là lowPoint. Bởi vì chúng tôi đang tạo biến này bên trong
-
chứ không phải ở đầu tập lệnh, điều đó có nghĩa là nó chỉ có thể được sử dụng trong hàm. Nhưng,
-
Ngoài ra, điều đó có nghĩa là chúng ta có thể thiết lập nó bằng cách thực hiện một phép tính.
-
vì vậy chúng ta sẽ thực hiện bằng equals transform.position.y - heightOffset. Và sau đó chúng ta sẽ làm một cái khác
-
một cho điểm cao nhất, nhưng lần này là cộng với HeightOffset. Điều đó mang lại cho chúng ta hai con số này.
-
Sau đó, chúng ta sẽ thay thế biến đổi.position trong mã Instantiate.
-
Chúng ta sẽ viết Vector3 mới, chúng ta phải viết điều đó bất cứ khi nào chúng ta chỉ định các số của riêng mình cho một
-
vectơ. và sau đó trong ngoặc, chúng ta sẽ chỉ định các giá trị X, Y và Z là ba số float khác nhau. Đối với X,
-
chúng tôi muốn cái này giống với cái sinh sản, vì vậy chúng tôi sẽ thực hiện Transform.position.x. Nhưng đối với Y,
-
chúng ta có thể làm Random.Range. Và trong ngoặc cho điều đó, chúng ta có thể cung cấp điểm tối thiểu và tối đa
-
để chọn từ. Đó là điểm thấp nhất và điểm cao nhất. Sau đó là số 0 cho Z. Và đóng dấu ngoặc lại.
-
Trở lại Unity.... tuyệt vời! Các đường ống sẽ xuất hiện ở bất kỳ đâu giữa hai số này.
-
Ồ, một điều cuối cùng. Mỗi khi những đường ống này sinh sản, chúng sẽ xuất hiện và di chuyển
-
đã ra đi.... mãi mãi. Đây không phải là cách thực hành hiệu quả - họ ở ngoài màn hình và hoàn toàn không làm gì cả,
-
nhưng chúng vẫn còn trong bộ nhớ và chạy mã ở mọi khung hình. Và nếu có quá nhiều sinh sản, chúng sẽ bắt đầu
-
tràn ra cạnh màn hình và làm bừa bộn bàn làm việc của bạn. Vì vậy, hãy khắc phục điều đó.
-
Bây giờ chúng ta có thể tạo bộ hẹn giờ và xóa đường ống sau vài giây. Nhưng thay vì,
-
chúng tôi sẽ kiểm tra vị trí X của đường ống và xóa nó nếu nó đi qua một điểm nhất định. Chúng ta sẽ mượn
-
con chim để tìm tọa độ X ở bên trái màn hình. Có vẻ như là âm 45. Trong
-
tập lệnh di chuyển đường ống, chúng tôi sẽ thêm một float cho vùng chết. -45. Và sau đó là một câu lệnh if đơn giản - if
-
Transform.position.x nhỏ hơn deadZone, sau đó hủy GameObject chứa tập lệnh này.
-
Chạy nó trong Unity và, bam, nó đã biến mất rồi.
-
Chúng ta hãy làm một điều nữa, như một khoảnh khắc có thể dạy được. Ngay trước đường tiêu diệt,
-
hãy viết Debug.Log và trong ngoặc là Đã xóa đường dẫn. Sau đó, quay lại Unity, bạn sẽ thấy một bảng điều khiển khác
-
Tôi đã bỏ qua phần demo giao diện người dùng - đó là một tab bên cạnh dự án, được gọi là console. Sau đó khi chúng tôi chạy
-
trò chơi... mỗi khi một đường ống bị xóa, tin nhắn của chúng tôi sẽ được gửi đến bảng điều khiển. Đây là một
-
cách cực kỳ hữu ích để gỡ lỗi mã của chúng ta, bởi vì chúng ta có thể tìm ra chính xác mã đó đang làm gì.
-
Tới lúc tóm tắt rồi !
-
GameObject có thể được chuyển thành prefab,
-
bằng cách kéo chúng từ hệ thống phân cấp(hierarchy) và thả chúng vào dự án.
-
Sau đó, bạn có thể kéo chúng vào các cảnh - Tôi sử dụng prefab để tạo cấp độ trong trò chơi giải đố của mình,
-
Ví dụ. Hoặc bạn có thể tạo một cái sinh sản để khởi tạo những cái mới trong trò chơi.
-
Bộ hẹn giờ là một cách tuyệt vời để thực hiện mã trong một khoảng thời gian nhất định,
-
nhưng luôn sử dụng Time.deltaTime để giữ mọi thứ nhất quán trên các máy tính khác nhau.
-
Các câu lệnh if có thể có một cổng khác, để kích hoạt mã nếu điều kiện
-
không được đáp ứng. Bạn cũng có thể dùng else if để tạo các cổng phức tạp hơn.
-
Và bạn nên cố gắng xóa GameObjects nếu chúng không còn cần thiết nữa để giải phóng bộ nhớ.
-
Được rồi, bước tiếp theo của chúng ta là theo dõi điểm số của người chơi,
-
và hiển thị nó cho người chơi trên giao diện người dùng. Sau đó,
-
chúng ta muốn điểm số tăng lên một đơn vị mỗi khi con chim bay qua đường ống.
-
Vì vậy, hãy nhớ rằng GameObject không nhất thiết phải là một vật thể trong trò chơi của bạn
-
thế giới như một nhân vật hoặc kẻ thù - đó có thể là một người quản lý hoàn toàn vô hình
-
đó chỉ là theo dõi các dữ liệu quan trọng như sức khỏe, thời gian hoặc điểm số. Và sau đó,
-
chúng tôi có thể hiển thị thông tin đó cho người chơi bằng giao diện người dùng.
-
Vì vậy, hãy bắt đầu bằng cách tạo giao diện người dùng. Giống như mọi thứ khác, đó là GameObject trong
-
hệ thống phân cấp. Lần này hãy đi xuống giao diện người dùng và chọn văn bản - có thể ở dưới
-
phần legacy. Chúng ta sẽ cần phóng to khung cảnh thật xa để thực sự nhìn thấy giao diện người dùng.
-
Để đảm bảo giao diện người dùng trông giống nhau trên mọi thiết bị, chúng tôi sẽ chọn GameObject canvas mới này
-
và đặt tỷ lệ giao diện người dùng của thành phần trình chia tỷ lệ canvas để chia tỷ lệ theo kích thước màn hình và chọn tỷ lệ hợp lý
-
độ phân giải tham chiếu - Tôi sẽ sử dụng lại 1080p. Sau đó chúng ta có thể di chuyển văn bản của mình xung quanh. Bạn sẽ nhận thấy
-
giao diện người dùng đó có biến đổi trực tiếp, thay vì biến đổi thông thường. Điều quan trọng nhất cần lưu ý là
-
rằng bạn không thực sự muốn gây rối với tỷ lệ của các phần tử - thay vào đó, hãy thay đổi chiều rộng và chiều cao.
-
Sau đó tôi sẽ tăng cỡ chữ và đặt mặc định
-
văn bản thành 0. Và sau đó kiểm tra xem tất cả có đẹp mắt trên chế độ xem trò chơi không.
-
Được rồi, bây giờ chúng ta muốn tạo một tập lệnh lưu trữ điểm của người chơi,
-
và thay đổi số trên giao diện người dùng thành điểm đó.
-
Chúng ta sẽ tạo một GameObject có tên là Logic Manager.
-
Và chúng tôi sẽ cung cấp cho nó một kịch bản. Tập lệnh này sẽ theo dõi thông tin cấp cao
-
như điểm số của người chơi. Và nó sẽ có nhiều chức năng cấp meta khác nhau mà chúng ta có thể chạy.
-
Vì vậy, chúng tôi sẽ xóa phần bắt đầu và cập nhật, chúng tôi không cần chúng trong tập lệnh này. Chúng ta luôn có thể thêm
-
họ sẽ quay lại sau nếu chúng ta đổi ý. Chúng tôi muốn lưu trữ một số cho điểm của người chơi. Thời gian này,
-
chúng tôi không muốn có số float vì chúng tôi chỉ muốn số tròn. Vì vậy hãy thực hiện một phép tính int,
-
thay vì. Đó là một số nguyên. Không có chữ số thập phân.
-
Và bởi vì chúng tôi muốn cập nhật văn bản giao diện người dùng mà chúng tôi vừa tạo, nên như mọi khi, chúng tôi sẽ
-
phải làm tài liệu tham khảo. Ngoại trừ... văn bản dường như không có ý nghĩa gì?
-
À, à. Theo mặc định, tập lệnh chỉ tải nội dung bạn cần cho Unity cơ bản
-
chức năng - nhưng nếu chúng ta lên trên cùng và gõ bằng UnityEngine.UI;, bây giờ chúng ta có thể
-
truy cập nhiều chức năng hơn - trong trường hợp này là nội dung giao diện người dùng. Bây giờ chúng ta có thể tạo một tham chiếu đến văn bản.
-
Chúng ta sẽ cần kéo thành phần văn bản vào trường này trong Unity. Bởi vì chúng tôi đang tham khảo một thành phần
-
trên một GameObject khác - văn bản trên giao diện người dùng - cách tốt nhất để thực hiện việc này là chỉ cần kéo
-
toàn bộ GameObject vào vị trí của chúng tôi. Điều này sẽ tự động tìm thành phần văn bản cho chúng tôi. Khá là tiện dụng.
-
Vì vậy bây giờ chúng tôi muốn tạo một hàm. Và chúng tôi sẽ gọi nó là addScore. Và bởi vì
-
chúng ta sẽ chạy chức năng này từ các tập lệnh khác, chúng ta sẽ đặt nó ở chế độ public void.
-
Chức năng này cần phải làm hai việc. Thêm một vào điểm của người chơi. Vừa đủ dễ,
-
chúng tôi biết làm thế nào để làm điều đó bây giờ. Và thay đổi văn bản trên giao diện người dùng thành số này. Ồ, hộp văn bản là
-
đang tìm kiếm một chuỗi - một chuỗi ký tự - và điểm của chúng tôi là một số nguyên. Chúng trông giống hệt nhau
-
đối với con người chúng ta, nhưng robot lại rất kén chọn. Bạn có thể dễ dàng sửa lỗi bằng cách thêm .toString() vào điểm trò chơi.
-
Để đảm bảo tính năng này hoạt động, chúng ta hãy cấp cho mình khả năng chạy chức năng này
-
từ chính Unity. Tất cả những gì chúng ta cần làm là viết ContextMenu và một tên phía trên hàm.
-
Bây giờ, trong Unity, khi trò chơi đang chạy, hãy nhấn vào các dấu chấm nhỏ trên tập lệnh này và chọn chức năng.
-
Đẹp! Loại điều này thực sự có ích cho việc thử nghiệm.
-
Được rồi, bây giờ chúng ta đã biết hàm này đang chạy, chúng ta đặc biệt muốn chạy nó
-
khi con chim đi giữa các đường ống. Và cách để làm điều này là va chạm.
-
Bây giờ nếu hai vật thể có va chạm, chúng sẽ va vào nhau - thực tế, trong trò chơi của chúng ta,
-
con chim sẽ đâm vào các đường ống vì chúng tôi đã thêm máy va chạm vào cả hai. Tuy nhiên bạn
-
cũng có thể có những máy va chạm vô hình, được gọi là bộ kích hoạt. Chúng không tạo ra một vụ va chạm thực sự,
-
nhưng chúng cho bạn biết rằng hai vật thể đã chạm vào nhau - và bạn có thể chạy mã vào lúc đó.
-
Vì vậy chúng ta sẽ đặt một mốc kích hoạt vào giữa các đường ống,
-
nên chúng ta biết rằng con chim đã bay qua chúng. Và ngay lúc đó, chúng ta sẽ chạy addScore.
-
Hãy mở nhà lắp ghép cho các đường ống. Chúng ta sẽ tạo một GameObject khác có tên là middle - và
-
nó cần một máy va chạm hộp. Hãy làm cho nó có hình dạng như thế này. Và lần này chúng ta sẽ
-
đánh dấu vào ô isTrigger. Cuối cùng, hãy thêm tập lệnh vào GameObject ở giữa mới này.
-
Bên dưới Cập nhật, nhập ontrig và tính năng tự động sửa sẽ giúp chúng tôi nhập OnTriggerEnter2D. Chỉ
-
nhấn tab để tự động điền. Mọi thứ trong hàm này sẽ chạy bất cứ khi nào có đối tượng đầu tiên
-
được kích hoạt. Ngoài ra còn có OnTriggerExit và OnTriggerStay để tham khảo trong tương lai. Và nó ở đây,
-
rằng chúng tôi muốn chạy hàm addscore mà chúng tôi đã viết trước đó... ngoại trừ. Ah. một lần nữa,
-
tập lệnh này không biết về bất kỳ tập lệnh nào khác trong trò chơi cho đến khi chúng tôi tham chiếu đến nó.
-
Vì vậy, chúng ta có thể viết logic LogicScript công khai. Nhưng trở lại Unity, bạn sẽ nhanh chóng nhận ra
-
rằng bạn không thể kéo tập lệnh vào vị trí này. Bạn không thể kéo nó khỏi dự án
-
bảng điều khiển - chúng tôi chỉ có thể nói chuyện với một phiên bản của tập lệnh tồn tại trên GameObject. Nhưng chúng tôi cũng
-
không thể kéo từ hiện trường vào prefab. Đó là vì đường ống chưa tồn tại trong hiện trường,
-
nó sẽ chỉ tồn tại khi trò chơi đang chạy và người sinh sản bắt đầu tạo đường ống.
-
Vì vậy, thay vào đó, chúng ta sẽ cần điền tham chiếu này bằng mã. Và
-
điều này cần phải xảy ra khi đường ống sinh sản lần đầu tiên.
-
Để làm điều này, chúng ta cần giúp mã tìm ra tập lệnh logic. Để làm điều này,
-
lấy đối tượng Game Logic và nhìn vào phần trên của thanh tra:
-
bạn sẽ thấy thẻ. Từ trình đơn thả xuống, chọn thêm thẻ. Tạo một thẻ mới có tên là,
-
Hợp lý. Và hãy đảm bảo bạn quay lại GameObject và thực sự đặt thẻ mới này. Bạn sẽ quên
-
làm điều này khoảng tám nghìn lần trong sự nghiệp Unity của bạn, vì vậy hãy mong chờ điều đó.
-
Bây giờ, quay lại PipeMiddleScript,
-
khi bắt đầu, chúng ta có thể viết logic = GameObject.FindGameObjectWithTag("Logic").
-
thao tác này sẽ tìm GameObject đầu tiên trong hệ thống phân cấp có thẻ,
-
Hợp lý. Trong trường hợp của chúng tôi, sẽ chỉ có một người trong hiện trường,
-
vì vậy chúng tôi biết nó sẽ luôn tìm được kết quả phù hợp - nhưng hãy lưu ý đến điều đó.
-
Và sau đó chúng ta có thể thêm .GetComponent();
-
Vì vậy, ngay khi một đường ống mới xuất hiện, nó sẽ xem qua hệ thống phân cấp để tìm GameObject có
-
thẻ Lôgic. Sau đó, nó sẽ xem qua các thành phần của đối tượng đó để tìm script
-
của lớp LogicScript. Và nếu tìm thấy, nó sẽ đặt nó vào vị trí tham chiếu của chúng tôi.
-
Nó đã thực hiện chính xác thao tác kéo và thả thành phần
-
trong trình chỉnh sửa Unity - ngoại trừ việc nó được thực hiện ngay lập tức trong thời gian chạy. Xuất sắc.
-
Vì vậy, bây giờ, tập lệnh ở giữa của ống có thể tìm và giao tiếp với tập lệnh logic.
-
Và nếu chúng ta viết logic.addScore, mã này sẽ chạy mã đó. Trở lại Unity,
-
nhấn play và nếu chúng tôi làm đúng mọi thứ, điểm sẽ tăng lên một khi chúng tôi vượt qua giữa các đường ống.
-
Ồ, và chỉ để kiểm chứng trong tương lai hay gì đó, hãy đảm bảo rằng đó thực sự là con chim
-
điều đó đã trải qua. Chúng ta sẽ thực hiện việc này bằng cách đặt con chim lên một lớp và kiểm tra xem sự va chạm có
-
đối tượng nằm trên lớp đó. Đi tới GameObject của chú chim và lần này, thay vì thẻ, chúng ta sẽ thay đổi
-
lớp của con chim. Tạo một cái mới, nhớ thực sự gán nó và ghi chú số.
-
Bây giờ, trên tập lệnh ở giữa của ống, chúng ta có thể thêm câu lệnh if xung quanh addScore,
-
và kiểm tra xem vụ va chạm vừa xảy ra có phải là với GameObject trên lớp chim hay không.
-
Thêm một chút bằng chứng trong tương lai, khi chúng ta đang nói về chủ đề này. Trở lại Tập lệnh logic.
-
Và, hãy lấy hàm AddScore và trong các dấu ngoặc trống này, chúng ta sẽ viết int
-
scoreToAdd. Và sau đó thay vì thêm một điểm, chúng ta sẽ thêm ScoreToAdd.
-
Sau đó, trong tập lệnh ở giữa ống, chúng ta có thể viết số 1 trong ngoặc sau addScore. Phải
-
bây giờ điều này thực hiện chính xác giống như chúng ta đã làm trước đây. Nhưng, như bạn chắc chắn có thể đoán được,
-
sau này bạn có thể thêm một số mục tiêu khác trong trò chơi để cộng thêm 5 vào điểm của bạn.
-
Điều này cho phép chúng ta tạo ra một hàm linh hoạt hơn vì nó có thể được sử dụng
-
theo những cách khác nhau, từ những nơi khác nhau. Tôi nghĩ một phần của việc trở thành một lập trình viên giỏi là
-
là làm cho mọi thứ bớt cứng nhắc hơn và giữ cho nó luôn rộng mở cho những ý tưởng trong tương lai.
-
Điều này giúp việc lặp lại thiết kế của bạn dễ dàng và nhanh chóng hơn.
-
Phải! Tóm tắt lại!
-
Giao diện người dùng chỉ là một GameObject khác, nhưng nếu chúng ta muốn tham khảo bất kỳ
-
trong số các thành phần này, chúng ta sẽ cần thêm việc sử dụng UnityEngine.UI vào đầu tập lệnh.
-
GameObject có thể là những thứ hoàn toàn vô hình,
-
chỉ ở đó để theo dõi các quy tắc, logic, điểm số, v.v.
-
Nếu chúng ta muốn tham chiếu đến một thành phần khi một trong các GameObject không có trong cảnh,
-
chúng ta sẽ cần tìm thành phần đó trong thời gian chạy.
-
Một cách để thực hiện việc này là sử dụng thẻ, findGameObject và GetComponent.
-
Một chức năng công khai có thể được chạy từ một tập lệnh khác, miễn là bạn có một tài liệu tham khảo
-
vào kịch bản đó. Và chúng ta thậm chí có thể truyền vào các biến khi hàm đó chạy.
-
Và Va chạm và kích hoạt có thể được sử dụng để khiến mọi thứ xảy ra khi hai vật thể chạm vào nhau.
-
Nói về va chạm, chúng ta hãy chuyển sang bước tiếp theo...
-
Bước cuối cùng là thêm trạng thái lỗi. Khi con chim chạm vào đường ống, trò chơi kết thúc.
-
Chúng tôi sẽ thực hiện việc này bằng cách tạo một trò chơi trên màn hình và để trò chơi đó xuất hiện khi con chim gặp nạn
-
vào một đường ống. Trò chơi trên màn hình sẽ có một nút mà chúng ta có thể sử dụng để thiết lập lại trò chơi.
-
Đầu tiên, hãy tạo trò chơi đó trên màn hình. Trên canvas GameObject,
-
thêm một cái trống mới gọi là trò chơi trên màn hình. Sau đó, trong phần gốc đó, thêm văn bản thông báo trò chơi kết thúc.
-
Và cả nút aa - nút đó cũng thuộc phần legacy. Thay đổi kích thước nó. Và thay đổi
-
văn bản trên nút - văn bản có thể được tìm thấy khi còn nhỏ trên chính nút đó.
-
Vì vậy, hãy quay lại nút GameObject, trên thành phần nút, bạn sẽ thấy
-
bit này có nội dung Khi nhấp chuột. Đây là một sự kiện và nó cho phép chúng ta gọi một
-
chức năng công khai trên GameObject. Vì vậy, hãy tạo một hàm để khởi động lại cấp độ.
-
Chúng ta có thể đặt mã này vào tập lệnh logic,
-
bên dưới chức năng addScore của chúng tôi. Bạn có thể tạo một tập lệnh riêng nếu muốn,
-
nhưng tôi nghĩ điều này ổn. Hãy tạo một hàm công khai khác có tên là restartGame,
-
và ở đây chúng ta sẽ viết mã để khởi động lại cảnh. Giống như trước đây với giao diện người dùng, nếu chúng ta
-
quản lý cảnh thì chúng ta sẽ cần thêm một dòng ở trên cùng - lần này là sử dụng UnityEngine.SceneManagment.
-
Bây giờ, trong hàm của chúng ta, chúng ta sẽ gọi SceneManager và sau đó chấm LoadScene. Cái này
-
đang tìm kiếm tên của một cảnh. Nghĩa đen là tên tập tin. Nhưng bởi vì chúng ta muốn cảnh hiện tại nên chúng ta
-
có thể chỉ cần gõ SceneManager dấu chấm GetActiveScene, dấu ngoặc, tên dấu chấm. Đóng tất cả các dấu ngoặc.
-
Bây giờ quay lại Unity, thêm sự kiện vào nút này.
-
Sau đó kéo logic GameObject vào. và tìm chức năng restartGame.
-
Hãy thử nghiệm và... tuyệt vời. Mỗi lần chúng ta nhấn nút, trò chơi sẽ bắt đầu lại.
-
Bây giờ rõ ràng là chúng tôi không muốn điều này luôn xuất hiện trên màn hình - ngay khi chúng tôi thất bại. Vì thế,
-
chúng ta có thể đưa toàn bộ trò chơi lên màn hình GameObject và tắt nó bằng dấu kiểm này.
-
Sau đó chúng ta sẽ làm cho nó hiện lên khi con chim lao vào đường ống.
-
Hãy viết hàm trước. Một lần nữa trong tập lệnh logic, hãy tạo một hàm công khai cho gameOver.
-
Chúng ta sẽ cần tham chiếu đến trò chơi trên màn hình GameObject.
-
Và điền nó vào Unity.
-
Và sau đó chúng ta có thể chỉ cần gõ gameoverscreen.SetActive true vào hàm này.
-
Vì vậy, chúng tôi muốn chức năng này được kích hoạt khi con chim đâm vào đường ống.
-
Quay lại tập lệnh chim, hãy sử dụng lại mã đó từ trước để truy cập tập lệnh logic
-
từ chữ viết của loài chim. Có, chúng ta có thể kéo và thả tham chiếu trong Unity, nhưng này,
-
chúng tôi đã viết mã này ngay bây giờ. Và sau đó chúng ta sẽ làm điều tương tự với mã kích hoạt, nhưng lần này
-
chúng tôi sẽ sử dụng OnCollisionEnter2D, vì các đường ống là vật thể rắn và không được đặt làm trình kích hoạt.
-
Và khi xung đột đó xảy ra, hãy kích hoạt trò chơi qua tập lệnh bằng logic.gameOver.
-
Quay lại Unity... cách này khá hiệu quả, nhưng chúng ta vẫn có thể chơi trò chơi qua màn hình. Không lý tưởng.
-
Như vậy, tôi đã nói về một số loại biến chính rồi. Float
-
và int là số. Và chuỗi thường dành cho văn bản. Cái quan trọng khác là bool,
-
viết tắt của boolean. Đây là một loại thực sự đơn giản, có thể đúng hoặc sai. TRÊN,
-
hoặc tắt. Có hay không. Đó là một cách tuyệt vời để chỉ cần kiểm tra hoặc thay đổi trạng thái của một cái gì đó.
-
Vì vậy, hãy tạo một bool tên là birdisalive và đảm bảo rằng nó bắt đầu như đúng.
-
Sau đó, khi xung đột xảy ra, chúng tôi sẽ đặt birdisalive thành sai.
-
Và cuối cùng, chúng ta sẽ thêm một điều kiện bổ sung vào câu lệnh if đầu tiên. Sắp tới
-
giả sử nếu phím cách vừa được nhấn và... được viết bằng hai ký hiệu... và birdisalive là
-
bằng với sự thật. Thực ra, chúng ta không cần cộng cái này bằng với giá trị đúng. Nó làm chính xác
-
điều tương tự mà không có nó. Tuy nhiên, một lần nữa, điều đó tùy thuộc vào bạn - có thể đọc phần này dễ dàng hơn với mã đầy đủ được viết ra.
-
Dù sao thì bây giờ, con chim sẽ không vỗ cánh nếu nó chết, điều này đối với tôi có vẻ khá hợp lý.
-
Điều cuối cùng cần làm là xây dựng trò chơi. Điều đó thực sự dễ dàng. Chọn tệp, cài đặt bản dựng và bản dựng. Chọn một thư mục trên
-
ổ cứng của bạn. Và hãy để Unity thực hiện công việc của nó. Sau đó, bạn có thể mở tệp này để chơi trò chơi của mình! Tuyệt vời.
-
Trong một khoảng thời gian rất ngắn, chúng tôi đã tạo ra một trò chơi khá hữu ích.
-
Và hơn thế nữa, chúng tôi đã học được vô số bài học cơ bản về Unity.
-
Chúng tôi đã tạo ra một nhân vật có thể di chuyển theo thao tác của chúng ta. Chúng ta có
-
sinh ra trong các đối tượng mới trên một bộ đếm thời gian. Chúng tôi đã tạo một giao diện người dùng hiển thị điểm số,
-
và làm cho điểm đó tăng lên khi các điều kiện được đáp ứng. Và chúng ta có khả năng kết thúc trò chơi,
-
và bắt đầu lại.
-
Bây giờ, tôi nên lưu ý rằng có nhiều cách khác - và có lẽ tốt hơn để làm hầu hết mọi việc
-
trong hướng dẫn này. Ví dụ: Tôi đã sử dụng cách kiểm tra đầu vào cũ của Unity và công ty
-
kể từ đó đã phát triển một Hệ thống đầu vào tốt hơn rất nhiều. Nhưng nó phức tạp hơn nhiều
-
sử dụng - vì vậy phương pháp đơn giản này hiện rất phù hợp và bạn có thể xem xét hệ thống đầu vào mới sau này
-
dòng, khi bạn cảm thấy tự tin hơn. Đó là cách nó diễn ra với tôi. Ngoài ra còn có TextMeshPro,
-
đã thay thế hệ thống giao diện người dùng cũ - vì vậy, tại một thời điểm nào đó, bạn cũng sẽ muốn chuyển sang hệ thống đó.
-
Dù sao đi nữa, đây là những bài học sẽ hữu ích để tạo ra mọi loại trò chơi.
-
Nhưng... trò chơi vẫn chưa hoàn thành. Vẫn còn một vài điều nữa cần phải tìm hiểu. Mặc dù,
-
Tôi không muốn nói với bạn cách làm mọi thứ. Vì vậy tôi sẽ cho bạn một số gợi ý về cách
-
để kết thúc trò chơi, nhưng tôi muốn bạn thử và tự mình tìm ra.
-
Vì vậy, trước hết, chúng ta cần phải kết thúc trò chơi nếu con chim biến mất khỏi màn hình.
-
Điều đó không quá khó khăn. Ngoài ra còn có một lỗi khiến điểm số có thể tăng lên,
-
ngay cả sau khi trò chơi kết thúc. Hãy cố gắng giải quyết vấn đề đó quá.
-
Chúng tôi cũng muốn có hiệu ứng âm thanh. Tôi muốn bạn thêm thành phần Nguồn âm thanh vào trình quản lý logic.
-
điền nó với một tập tin hiệu ứng âm thanh. Tham khảo nó trên kịch bản. Và cho nó chơi khi điểm số tăng lên.
-
Sau đó, tôi muốn bạn thử nghiệm hệ thống hạt để tạo ra các đám mây trong trò chơi.
-
Tiếp theo, mở cửa sổ hoạt hình và thêm một số cánh đang vỗ cho chú chim.
-
Sau đó tôi muốn bạn thêm một cảnh khác để làm màn hình tiêu đề,
-
vì vậy trò chơi không bắt đầu hành động ngay lập tức. Đây là một manh mối:
-
bạn sẽ cần thêm cảnh mới này vào cửa sổ cài đặt bản dựng.
-
Và cuối cùng, nếu bạn muốn thử thách thực sự - hãy sử dụng PlayerPrefs
-
để lưu điểm cao của người chơi vào ổ cứng và vẽ điểm đó trên giao diện người dùng.
-
Đối với mỗi một trong số này, bạn có thể sẽ muốn tra Google các thuật ngữ có liên quan, đọc tài liệu Unity,
-
xem một số video hướng dẫn nhanh hoặc yêu cầu trợ giúp trong phần bình luận bên dưới.
-
Tiếp theo, bạn có thể mở rộng trên Flappy Bird. Sáng tạo
-
và thêm vào những ý tưởng hoặc thiết kế không có trong trò chơi iPhone gốc.
-
Ví dụ, với một chút lộn xộn, tôi đã cho con chim khả năng bắn ra tên lửa,
-
và sau đó tôi thêm mục tiêu vào đường ống. Bây giờ bạn phải bắn trúng mục tiêu bằng tên lửa để mở
-
một khoảng trống bạn có thể vượt qua. Nó khá thú vị và tăng thêm chiều sâu cho trò chơi đơn giản.
-
Trên thực tế, tôi rất muốn xem bạn có thể mở rộng trò chơi gốc như thế nào. Nếu như
-
bạn tạo ra điều gì đó thú vị, ghi lại một đoạn phim, đưa nó lên YouTube,
-
và thả một liên kết trong các ý kiến. Tôi có thể giới thiệu một số trong số họ trong tương lai.
-
Và cuối cùng, tôi khuyên bạn nên dùng
-
một trò chơi đơn giản khác và thử làm lại nó trong Unity, giống như chúng tôi vừa làm bây giờ.
-
Đây là một kỹ thuật tuyệt vời vì bạn không phải lo lắng về nghệ thuật hay thiết kế...
-
chỉ cần mã. Và những câu đố giải quyết vấn đề mà bạn sẽ gặp phải là một ví dụ hoàn hảo về
-
quá trình phát triển trò chơi thực sự sẽ như thế nào.
-
Những ứng cử viên sáng giá cho điều này bao gồm Pong, Space Invaders, Breakout, Pop the Lock, Angry Birds,
-
nhiều trò chơi nhỏ WarioWare khác nhau và trò chơi khủng long chơi trong Chrome nếu Internet của bạn bị hỏng.
-
Vì vậy, trong video này tôi muốn dạy cho bạn
-
các khái niệm cơ bản đằng sau Unity - tuy nhiên, phần còn lại tùy thuộc vào bạn.
-
May mắn thay, tôi cho rằng đây là phong cách thực hành, tự định hướng, học hỏi từ những sai lầm của bạn.
-
học tập là cách thú vị và hiệu quả nhất để làm cho mọi thứ trở nên gắn bó. Nhưng chúng ta sẽ thấy!
-
Hãy cho tôi biết bạn đã tiếp tục như thế nào trong phần bình luận bên dưới. Và nếu bạn
-
muốn xem câu chuyện phát triển trò chơi của tôi - vẫn đang tiếp diễn,
-
lời hứa - sau đó bấm vào đây để xem tập một của Đang phát triển.
-
Cảm ơn Patreons của tôi rất nhiều - họ là lý do chúng ta không có
-
quảng cáo chèn giữa trong một video dài như thế này. Bạn có thể giúp hỗ trợ GMTK tại Patreon.com.