1. Trang chủ
  2. » Luận Văn - Báo Cáo

Luận văn tốt nghiệp Khoa học máy tính: Thiết kế mô hình tri giác và nhận thức cho các NPCS trong stealth game

125 0 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Thiết kế mô hình tri giác và nhận thức cho các NPCs trong Stealth game
Tác giả Phạm Phước Hoài
Người hướng dẫn ThS. Vương Bá Thịnh, ThS. Băng Ngọc Bảo Tâm
Trường học Đại học Quốc gia TP.HCM
Chuyên ngành Khoa học Máy tính
Thể loại Luận văn tốt nghiệp Đại học
Năm xuất bản 2021
Thành phố TP.HCM
Định dạng
Số trang 125
Dung lượng 3,25 MB

Cấu trúc

  • 1.1 NPC là gì? (17)
  • 1.2 Stealth game là gì? (17)
  • 1.3 Bối cảnh (18)
  • 1.4 Động cơ (18)
  • 1.5 Câu hỏi nghiên cứu (19)
  • 1.6 Mục tiêu (19)
  • 1.7 Phương pháp nghiên cứu và cấu trúc luận văn (20)
  • 2.1 Thị giác cho NPC (20)
  • 2.2 Mô phỏng sự lan truyền của âm thanh và thính giác cho NPC (21)
    • 2.2.1 Region Sense Manager (RSM) (22)
    • 2.2.2 Finite Element Model Sense Manager (FEMSM) (23)
    • 2.2.3 Sonic Virtuality (SV) (24)
  • 2.3 Mô tả trạng thái và việc đưa ra quyết định cho NPC bằng Finite State Machine (FSM) (24)
  • 2.4 Những thiếu sót của các nghiên cứu trên (25)
  • 3.1 NavMesh và tìm đường đi ngắn nhất trong Unity (27)
  • 3.2 Né tránh vật cản và RVO (Reciprocal Velocity Obstacles) (31)
  • 4.1 Nhận thức thị giác ở con người (40)
  • 4.2 Mô hình đề xuất cho nhận thức thị giác ở con người (40)
    • 4.2.1 Mô hình thị giác cơ bản (41)
    • 4.2.2 Mô hình thị giác đề xuất (42)
  • 5.1 Nhận thức thính giác ở con người (44)
    • 5.1.1 Sự suy giảm cường độ của âm thanh (44)
    • 5.1.2 Sự nhiễu xạ của âm thanh (Diffraction) (45)
    • 5.1.3 Sự phản xạ âm thanh và âm vang (Reflection and Reverberation) (46)
    • 5.1.4 Binaural sound cues (47)
    • 5.1.5 Định vị nguồn âm thanh dựa vào sự lan truyền của âm thanh (propagation based sound localisation) (48)
  • 5.2 Mô hình đề xuất cho nhận thức thính giác của NPC (49)
    • 5.2.1 Mô hình truyền tín hiệu âm thanh (49)
    • 5.2.1. a Biểu diễn tín hiệu âm thanh (49)
    • 5.2.1. b Emitter (50)
    • 5.2.1. c Broadcaster (50)
    • 5.2.1. d Listener (50)
    • 5.2.1. e Filter (51)
    • 5.2.2 Mô phỏng sự lan truyền của âm thanh trong môi trường (52)
    • 5.2.3 Khả năng xác định vị trí nguồn âm của NPC (53)
    • 5.2.3. a Xác định một NPC có thể nghe được âm thanh phát ra hay không (53)
    • 5.2.3. b Ước tính hướng của nguồn âm (54)
    • 5.2.3. c Ước tính vị trí nguồn âm (55)
    • 5.2.3. d Tổng hợp quá trình hoạt động của mô hình (57)
  • 6.1 Cây hành vi (Behaviour tree) (57)
  • 6.2 Behavior Designer (62)
  • 7.1 Quá trình thiết kế (64)
    • 7.1.1 High Concept Document (64)
    • 7.1.2 Game Design Document (66)
  • 7.2 Quá trình phát triển (77)
    • 7.2.1 Main Camera (77)
    • 7.2.2 Nhân vật (80)
    • 7.2.3 Mô hình nhận thức thị giác (85)
    • 7.2.4 Mô hình nhận thức thính giác (91)
    • 7.2.5 Quân địch (NPC) (98)
  • 7.3 Một số hình ảnh trong game (104)
  • 8.1 Kiểm thử mô hình thị giác (107)
  • 8.2 Kiểm thử mô hình thính giác (111)
  • 8.3 Kiểm thử mô hình hành vi (116)
  • 9.1 Đánh giá (119)
  • 9.2 Hướng phát triển (122)
  • trang 3) (0)
  • trang 16) (0)

Nội dung

NPC là gì?

NPC là một nhân vật không được điều khiển bởi người chơi Thay vào đó, nó thường được điều khiển bởi máy tính thông qua các chương trình được viết sẵn NPC có thể được chia thành ba nhóm tùy theo hành vi của nó đối với người chơi: (1) thù địch, (2) thân thiện, (3) trung lập.

Thông thường, thuật ngữ NPC chỉ đề cập đến các nhân vật không thù địch với người chơi con người, tức là các nhân vật thân thiện hoặc trung lập, có thể giúp đỡ và dẫn dắt người chơi trong game hoặc không có bất kỳ tác động nào đến nhân vật của người chơi và được tạo ra để lấp đầy môi trường trong game ví dụ như là các người dân trong một thành phố.

Luận văn này chủ yếu tập trung vào các NPC thù địch, chẳng hạn như các loại kẻ thù (binh lính, lính canh, kẻ cướp, quái vật) có nhiệm vụ đe dọa, săn lùng hoặc tiêu diệt nhân vật của người chơi.

Hành vi của NPC trong hầu hết các trường hợp, đều được viết theo kịch bản đặt trước hoặc tự động và nó có thể được kích hoạt bởi một số điều kiện nhất định Các hành vi này không thể bị thay đổi nếu ta không thay đổi chương trình được viết cho nó Tuy nhiên, kể từ cuối những năm 1980, trí tuệ nhân tạo để điều khiển NPC đã được được tích hợp vào thiết kế của game để làm cho các hành vi linh hoạt và đa dạng hơn.

Stealth game là gì?

Stealth là một thể loại game mà trong đó người chơi chủ yếu sử dụng các tính năng hỗ trợ cho việc lẩn tránh hoặc vượt qua kẻ địch ví dụ như tàng hình hoặc giả dạng Ý tưởng cơ bản của yếu tố stealth trong game là ẩn nấp và tránh tiếp xúc với kẻ thù có mặt trong game Các game thể loại này thường cho phép người chơi không bị phát hiện bằng cách ẩn nấp, lén lút hoặc sử dụng biện pháp cải trang, giả dạng Một số game cũng cho phép người chơi lựa chọn giữa cách tiếp cận lén lút hoặc tấn công trực tiếp đối thủ nhưng thưởng nhiều hơn cho người chơi khi sử dụng khả năng stealth Thể loại game này thường sử dụng các chủ đề gián điệp, chống khủng bố và giả mạo với các nhân vật chính là lực lượng đặc nhiệm, đặc vụ, gián điệp, tên trộm, ninja hoặc sát thủ Một số game cũng đã kết hợp yếu tố stealth với các thể loại khác, chẳng hạn như game bắn súng góc nhìn thứ nhất và platformer.Một số ví dụ về các game có yếu tố stealth đó là: Pac Man, Metal Gear Solid, Thief: The Dark Project,Dishonored, Hitman, Splinter Cell,

Bối cảnh

Một NPC cần phải biết về môi trường của nó, chẳng hạn như chướng ngại vật ở đâu, kẻ thù ở đâu, đồng đội ở đâu, v.v Chất lượng NPC của chúng ta hoàn toàn phụ thuộc vào thông tin mà nó có thể nhận được từ môi trường. Dựa trên thông tin mà NPC thu thập được, nó có thể quyết định hành động nào sẽ được thực thi để phản hồi lại dữ liệu đó Mà chất lượng này của NPC lại tác động trực tiếp đến người chơi, ví dụ: trải nghiệm và sự thích thú của người chơi sẽ bị ảnh hưởng một cách tiêu cực ngay khi nhìn thấy NPC bị mắc kẹt sau một bức tường.

Giác quan là thứ duy nhất giúp con người nhận thức về môi trường Điều này cũng đúng đối với các NPC Hành động nhìn thấy một vật, cảm nhận một âm thanh, phân tích nội dung và dự đoán vị trí nguồn phát của âm thanh đó cung cấp một lượng dữ liệu phong phú về môi trường xung quanh Các dữ liệu từ giác quan là rất quan trọng để mô phỏng các hành vi tương tự như con người trong game Hầu hết những phát triển gần đây về nhận thức môi trường của NPC có xu hướng mô phỏng các giác quan một cách đơn giản hóa để tập trung tài nguyên vào phần đồ họa và hiệu ứng, ít quan tâm đến bản chất thực tế của các giác quan cũng như là khả năng và hạn chế riêng của từng NPC.Trong CRYENGINE, công cụ phát triển game của Crytek, các nhà phát triển game có thể điều chỉnh độ nhạy thị giác và thính giác của một NPC thông qua một biến scaling, sau đó biến này được thêm vào việc tính toán xem một nhân vật NPC có thể nhìn thấy hay nghe thấy hay không, nhưng những tính toán này không tính đến trạng thái tâm lý và sinh lý hiện tại của nhân vật đó Phương pháp này cũng loại bỏ mọi ảnh hưởng của các âm thanh khác hoặc chướng ngại vật trong môi trường mà những điều này lại có ảnh hưởng không nhỏ đối với sự nhận thức của con người trong thực tế.

Động cơ

Trong các game cổ điển như Pong, sự đơn giản của bối cảnh và môi trường không cung cấp nhiều thông tin để đưa ra một hành vi như con người đối với thanh đánh bóng (paddle) của đối phương, vì các biến duy nhất ở đây là vị trí của quả bóng và vị trí thanh đánh bóng Trong các game gần đây, sự hiện thực của môi trường đã tăng lên rất nhiều, làm cho số lượng các biến được khảo sát bởi NPC cũng tăng lên Trong tựa game Farcry, sử dụng phiên bản sửa đổi của CRYENGINE, Dunia, NPC nhận phản hồi từ môi trường bằng cách quét tất cả các nhân vật và đối tượng có liên quan bằng tầm nhìn, xác định tất cả các âm thanh mà chúng nghe thấy và thông qua một hệ thống phụ trợ được gọi là mưa đạn (bullet rain) để cung cấp thông tin về những viên đạn đi qua gần những NPC này.

Sự phát triển của ngành công nghiệp game đã dẫn đến nhu cầu về độ tin cậy cũng như tính thực tế cao hơn đối với các hành vi và khả năng của các NPC Sự tiến hóa này dẫn đến việc tạo ra các cơ chế để nâng cao nhận thức của NPC về môi trường Trong thế hệ game hiện nay, khả năng nhìn và cảm nhận âm thanh của NPC thường được đơn giản hóa Điều này dẫn đến việc mô phỏng thực tế kém trung thực, ảnh hưởng đến độ chân thực của NPC và thế giới trong game Trong Source engine, âm thanh được phát ra thông qua một thực thể trong game được gọi là ai_sound, cho phép tất cả các NPC nghe thấy âm thanh nếu chúng nằm trong phạm vi nhất định đối với nguồn phát, với yếu tố quyết định duy nhất khác là một nhãn (tag) cho biết NPC có phải thuộc một lớp kẻ thù cụ thể hay không, lớp này có thể không nghe được âm thanh Phương pháp này hoàn toàn không quan tâm đến vật lý và các yếu tố tâm lý, chẳng hạn như NPC bị phân tâm khi thực hiện một nhiệm vụ nhất định hoặc sự tồn tại của âm thanh lớn che đi các âm thanh có cường độ thấp hơn, cả hai yếu tố này trong thực tế đều có thể khiến NPC không thể cảm nhận âm thanh được phát ra Nhận thức được sự không hoàn hảo kể trên là rất quan trọng để mô phỏng chính xác nhất khả năng thị giác và thính giác như con người Do hạn chế về khả năng xử lý của các nền tảng chơi game và những hạn chế khác mà sự không hoàn hảo trong các giác quan của NPC trong những game hiện nay thường bị gạt sang một bên để có lợi hơn cho các khả năng khác đáng chú ý bởi người chơi, như tìm đường đi trong môi trường đông đúc hoặc lựa chọn lộ trình hành động tốt nhất để hoàn thành một công việc nhất định.

Vì vậy, có một sự cần thiết để tìm ra cách mô phỏng tốt hơn khả năng nhìn và cảm nhận âm thanh giống như con người đối với thế hệ game hiện tại Một trong những thách thức chính là sử dụng hiệu quả tài nguyên tính toán sao cho không làm tổn hại đến hiệu suất của game bởi sự tính toán của các giác quan Gánh nặng tính toán này sẽ thậm chí lớn hơn đối với môi trường với nhiều NPC cùng tồn tại, vì vậy sự truyền các tín hiệu giác quan từ môi trường và việc phân tích các tín hiệu đó cần được thực hiện một cách hiệu quả.

Câu hỏi nghiên cứu

Trong bước chuẩn bị cho luận văn này, em đã có nghiên cứu sơ lược về cách mà thị giác và thính giác của con người hoạt động, đồng thời cũng tìm hiểu về các game hiện nay họ giải quyết vấn đề này như thế nào Trong quá trình nghiên cứu đó đã có nhiều câu hỏi nảy sinh Những câu hỏi này cung cấp động lực cốt lõi của toàn bộ quá trình nghiên cứu và phát triển, góp phần hoàn thiện mô hình kết quả Các câu hỏi có liên quan như sau:

• Làm sao để NPC có thể di chuyển được trong môi trường đồng thời né các vật cản hoặc NPC khác trên đường đi?

• Có cách nào để áp dụng cách con người nhìn thế giới xung quanh vào NPC mà ít ảnh hưởng đến hiệu suất của game nhất có thể?

• Làm sao để mô phỏng sự lan truyền của âm thanh trong thế giới của game để từ đó có thể mô phỏng thính giác của NPC một cách thực tế nhất có thể?

• NPC xử lý các thông tin từ môi trường như thế nào và chúng sẽ hành động như thế nào để phản hồi lại những thông tin đó?

Mục tiêu

Mục tiêu chính của luận văn này là thiết kế một mô hình cung cấp các cơ chế để cảm nhận và nhận thức môi trường cho NPC NPC sẽ có thể quan sát được môi trường và nhận biết được âm thanh phát ra và thông qua việc phân tích những thông tin đó và tùy thuộc vào trạng thái tâm lý và thể chất, mà các thông tin trên được xem là cảm nhận được hoặc loại bỏ đi Trên việc nhận thức được thông tin, NPC có thể đưa ra một hành động hợp lý trong ngữ cảnh đó.

Ngoài ra mô hình còn cho phép tùy chỉnh các thông số của mô hình sao cho phù hợp với tựa game đang được phát triển hoặc đối với từng đối tượng NPC để đem lại sự phong phú và đa dạng cho game.

Mô hình này sẽ hiện thực và phát triển bằng Unity engine, là công cụ phát triển game có thị phần và cộng đồng nhà phát triển lớn nhất hiện nay.

Phương pháp nghiên cứu và cấu trúc luận văn

Phương pháp nghiên cứu Khoa học Thiết kế (Design Science research methodology) đã được áp dụng trong quá trình nghiên cứu, phát triển và đánh giá mô hình Phương pháp này có thể được mô tả bằng các bước sau:

• Xác định vấn đề và động lực.

• Định nghĩa các mục tiêu của giải pháp.

• Thiết kế và phát triển.

• Kết luận và hướng phát triển.

Bước chính, liên quan đến việc xác định vấn đề và động lực đã được trình bày trong các phần 1.1 và 1.2 Các mục tiêu đã được đề ra trong phần 1.4, dựa trên câu trả lời cho các câu hỏi đặt ra trong phần 1.3 Phần 2 sẽ đề cập đến những nghiên cứu có liên quan đến mô hình cần thiết kế Từ phần 3 đến phần 6 sẽ phản ánh việc thiết kế và phát triển của từng module trong mô hình: module tìm đường (path-finding), module thị giác, module thính giác và module đưa ra quyết định và hành động Bước áp dụng mô hình đề xuất vào một tựa game cụ thể sẽ được trình bày trong phần 7 Phần 8 sẽ trình bày những kết quả thu được sau khi kiểm thử mô hình trong tựa game đã phát triển và cuối cùng kết luận và định hướng phát triển sẽ được nhắc đến trong phần 9.

2 Các nghiên cứu liên quan

Thị giác cho NPC

Trong các tựa game như Splinter Cell, Deus Ex, Dishonored hay Mark of the Ninja thị giác hay trường tầm nhìn (field of vision) đều được mô phỏng dưới dạng hình nón tầm nhìn (vision cone) Như hình dưới minh họa,trường tầm nhìn được mô hình hóa bằng cách sử dụng một hình nón Hình nón này có thể ở dạng 2D hoặc 3D, tùy theo từng tựa game.

Hình 1: Hình nón tầm nhìn (Vision cone) (Chaudhari, 2018).

Hình trên minh họa khái niệm hình nón tầm nhìn Ở đây, bắt đầu từ nguồn, tức là mắt nhân vật, hình nón to dần, nhưng trở nên kém chính xác hơn theo khoảng cách, thể hiện bằng màu mờ dần của hình nón.

Sự hiện thực của hình nón này trên thực tế có thể đơn giản từ việc xét có nhìn thấy hay không đến một mô hình thực tế phức tạp hơn, bắt chước thị lực của con người Trong một cách hiện thực đơn giản, chỉ cần kiểm tra xem một đối tượng có nằm trong hình nón tầm nhìn hay không, bỏ qua yếu tố khoảng cách hoặc tầm nhìn ngoại vi Một hiện thực phức tạp mô phỏng thị lực của mắt gần thực tế hơn, đó là khi hình nón mở rộng ra khỏi nguồn, trường nhìn sẽ tăng lên, nhưng cơ hội nhìn thấy những thứ về phía các cạnh của hình nón giảm đi so với những vật ở gần trung tâm.

Mô phỏng sự lan truyền của âm thanh và thính giác cho NPC

Region Sense Manager (RSM)

RSM hiện thực việc nhận thức bằng giác quan bằng các vùng hình cầu Việc truyền tín hiệu (ở phương pháp này, có thể là một âm thanh hoặc một mùi hương), xảy ra trong ba giai đoạn riêng biệt.

Trong giai đoạn tổng hợp (aggregation phase), phạm vi tiếp cận tối đa của tín hiệu được tính bằng cách sử dụng cường độ tín hiệu ban đầu và sau đó áp dụng một giá trị suy giảm, giá trị này xác định cường độ của âm giảm đi bao nhiêu hoặc cường độ của mùi suy yếu đi bao nhiêu theo khoảng cách Tất cả các đối tượng trong phạm vi đó đều có tiềm năng để nhận biết được âm thanh hay mùi hương đó.

Hình 2: Các vùng hình cầu của RSM được biểu diễn dưới dạng 2D (Millington & Funge, 2016, trang 607)

Trong giai đoạn kiểm tra (testing phase), mọi đối tượng tiềm năng đều được kiểm tra xem đối tượng đó có thể cảm nhận được tín hiệu hay không Các kiểm tra này giảm dần cường độ của tín hiệu, ở những khoảng cách xác định, từ đó tạo ra các vùng khác nhau xung quanh nguồn Hình 2 biểu diễn một NPC đang được kiểm tra (với một ngưỡng cảm nhận tín hiệu của nó) nằm trong một trong các khu vực mà nó có thể nhận biết tín hiệu Vùng có màu đậm hơn là vùng có cường độ của tín hiệu cao hơn Việc kiểm tra này dựa trên cường độ của tín hiệu ở khu vực mà NPC đang đứng có cao hơn giá trị ngưỡng của NPC đó hay không Nếu cường độ cao hơn ngưỡng, thì NPC có thể nhận biết tín hiệu Các kiểm tra khác cũng có thể được thực hiện trong giai đoạn này, có thể xem xét thêm các chướng ngại vật có thể có giữa nguồn của tín hiệu và NPC hoặc các yếu tố môi trường khác có thể ảnh hưởng đến việc truyền tín hiệu Nếu việc kiểm tra thành công đối với một cặp tín hiệu/NPC nhất định, thông tin liên quan đến cặp này sẽ được lưu trữ trong một hàng đợi Thông tin này mô tả về tín hiệu, NPC và khi nào tín hiệu sẽ được nhận bởi NPC đó Thời gian nhận được tín hiệu của NPC được tính dựa trên thời gian di chuyển từ nguồn tín hiệu đến mục tiêu, giá trị này sẽ thay đổi đối với các loại tín hiệu khác nhau.

Các thông tin được lưu trữ trong hàng đợi sẽ được gửi đi trong giai đoạn thông báo (notification phase) Trong giai đoạn này, các tín hiệu sẽ được gửi đến các NPC đích dựa trên thời gian đã được tính toán ở trên.

Finite Element Model Sense Manager (FEMSM)

Phương pháp FEMSM chia môi trường ảo thành các vùng rời rạc Các vùng này của môi trường được mô tả trong một đồ thị, với mỗi nút mô tả các thuộc tính truyền tín hiệu của vùng đó và các vùng nào là các vùng lân cận. Điều này cho phép mô phỏng sự lan truyền tín hiệu giữa mỗi vùng rời rạc bằng cách duyệt qua đồ thị.

Khi tín hiệu được phát ra, tín hiệu đó bắt đầu ở nút biểu thị vùng không gian, nơi mà nguồn phát đang ở Tín hiệu sau đó được sao chép sang các nút lân cận và cường độ của tín hiệu sẽ suy giảm tương ứng với đặc tính của từng vùng Tín hiệu sẽ ngừng truyền khi cường độ tín hiệu giảm xuống dưới một giá trị ngưỡng xác định Nếu một NPC ở một vùng bất kỳ, nơi tín hiệu có cường độ trên ngưỡng của NPC thì tín hiệu đó được cảm nhận và chuyển đến NPC Hình 3 biểu thị một đồ thị với các vùng không gian riêng biệt và tín hiệu được phát ra trong vùng A Tín hiệu truyền đến vùng B, nơi nó bị suy giảm theo giá trị suy giảm của vùng đó Tín hiệu truyền đến các vùng lân cận, vùng C, nơi nó bị suy giảm hơn nữa Nó ngừng lan truyền ra ngoài vùng C bởi vì khi đến các khu vực lân cận, sự suy giảm làm cho tín hiệu không thể được cảm nhận nữa Có một NPC trong vùng C và nếu cường độ tín hiệu lớn hơn mức ngưỡng của NPC, thì tín hiệu được cảm nhận bởi NPC đó.

Hình 3: Một đồ thị FEMSM với các vùng rời rạc Cường độ tín hiệu được biểu thị bằng màu nền của vùng không gian, với màu tối thể hiện cường độ cao hơn (Millington & Funge, 2016, trang 776).

Fabio Zambetta (Zambetta, 2007) đã mô tả một mô hình tương tự như FEMSM nhưng xoay quanh việc tạo ra đồ thị mỗi khi NPC cần nhận thức hay cảm nhận môi trường Đồ thị được tạo ra dựa trên đồ thị của môi trường ban đầu, với vị trí của NPC là nút đầu tiên và với các nút lá là các vị trí được tính toán dựa trên khoảng cách tối đa mà NPC có thể cảm nhận được tín hiệu.

Khi có nhu cầu nhận thức hay cảm nhận về môi trường, việc tìm kiếm trên đồ thị sẽ được thực hiện cho bất kỳ tín hiệu nào nằm trong đồ thị nhận thức của NPC Mỗi NPC sẽ có một tập hợp các thuộc tính để mô phỏng các khả năng nghe khác nhau cho từng NPC.

Sonic Virtuality (SV)

Mark Grimshaw và các cộng sự (Grimshaw, M et al, 2015) và sau đó là Tom Garner và các cộng sự (Garner,

T et al, 2016) đã mô tả sự biểu diễn của âm thanh cho các môi trường ảo khác xa cách biểu diễn âm thanh cổ điển. Thay vì mô tả âm thanh dưới dạng sóng, SV mô tả âm thanh vừa là một vật thể vừa là một sự kiện Trong thính giác, con người liên hệ âm thanh nghe được với nguồn phát của nó, liên hệ trực tiếp giữa âm thanh với đối tượng phát ra nó, bỏ qua các tính chất vật lý của quá trình truyền âm Định nghĩa này là cơ sở cho SV Trong SV, âm thanh tồn tại trong não và cơ thể của người nghe, với sự nhận thức xuất hiện khi có sự tương tác giữa các kích thích bên ngoài với trạng thái tâm lý và khả năng của người nghe.

Mô tả âm thanh trong SV có tính đến cả các yếu tố bên trong và bên ngoài, chia các thuộc tính của âm thanh thành hai nhóm riêng biệt Nhóm đầu tiên, biểu diễn bởi các yếu tố vật lý như môi trường, cơ thể và não của người nghe, được gọi là exosonus Nhóm thứ hai, được gọi là endosonus, liên quan đến các thuộc tính phi vật chất của trạng thái tâm lý của NPC, được tạo nên bởi cảm xúc và ký ức Sự mô tả này nhằm mục đích phân loại âm thanh để phân tích chúng, xét đến tất cả các tính chất endosonus và exosonus Bằng cách xác định loại của âm thanh nghe được, người nghe có thể dựa vào đó mà có những hành động phù hợp.

Mô tả trạng thái và việc đưa ra quyết định cho NPC bằng Finite State Machine (FSM)

FSM là một mô hình tính toán dựa trên một giả định là một cỗ máy được tạo ra từ một hoặc nhiều trạng thái. Chỉ một trạng thái duy nhất có thể hoạt động cùng một lúc, vì vậy cỗ máy phải chuyển từ trạng thái này sang trạng thái khác để thực hiện các hành động khác nhau.

FSM có thể được sử dụng để định nghĩa các hành vi của NPC nhất định, chẳng hạn như tấn công, né tránh hoặc chạy FSM đã được sử dụng để điều khiển các hành vi của các hồn ma (ghosts) trong game Pac Man Chúng nó chỉ có thể có một chế độ hoạt động tại một thời điểm, đó là săn, bị đuổi, chết hoặc chờ được hồi sinh Sau này, các trò chơi hiện đại hơn, fuzzy logic đã được đưa vào một nền tảng vững chắc là FSM để làm cho người chơi không thể đoán trước hành động của các nhân vật này và làm cho các nhân vật ít "robot" và cứng nhắc hơn.

Ví dụ như trong các game hành động lén lút (stealth) như Commandos, Assassin’s Creed hoặc loạt game Metal Gear nổi tiếng, bất cứ khi nào kẻ thù hay NPC phát hiện ra người chơi, NPC sẽ chuyển từ trạng thái nhàn rỗi sang trạng thái cảnh báo Sau một vài giây, nếu người chơi rời khỏi tầm nhìn của NPC, thì NPC sẽ bắt đầu chủ động tìm kiếm anh ta bằng cách chuyển sang trạng thái hung hăng Sự ngẫu nhiên ở đây thể hiện ở các đường đi của các NPC khi họ đi lang thang xung quanh hoặc những nơi mà các NPC này sẽ tìm kiếm người chơi khi người chơi bị phát hiện hoặc quyết định sử dụng một loại vũ khí bất kỳ chứ không phải vũ khí khác.

Có một dạng hiệu quả hơn của FSM là Hierarchical Finite State Machine (HFSM) Sự khác biệt duy nhất giữaHFSM và FSM là trong HFSM có một hệ thống phân cấp các trạng thái hay lựa chọn, nghĩa là các trạng thái được xem xét ở mức cao trước khi đi vào các trạng thái ở mức thấp hơn.

Ví dụ thay vì các hành vi Tấn công (attack), Chạy (run) và Nhàn rỗi (idle), chúng ta sẽ có một hệ thống phân cấp bắt đầu với hai trạng thái là Tìm thấy kẻ địch (EnemyFound) và Không tìm thấy kẻ địch (EnemyNotFound). Tấn công và Chạy sẽ là con của trạng thái Tìm thấy kẻ địch, trong khi Nhàn rỗi sẽ là con của trạng thái Không tìm thấy kẻ địch Vì chúng ta bắt đầu từ cấp trên cùng mỗi khi xét, nên chúng ta có thể loại bỏ quá trình chuyển đổi sang Nhàn rỗi từ trạng thái Tấn công và Chạy, và chuyển quá trình chuyển đổi này lên trạng thái cha (chỉ viết một lần) Điều này cho phép tổ chức tốt hơn các quá trình chuyển đổi, loại bỏ nhiều code được viết lại, v.v.

Hình 4: Một ví dụ về FSM (Bevilacqua, 2013).

Những thiếu sót của các nghiên cứu trên

Có một vấn đề đã nảy sinh khi sử dụng hình nón tầm nhìn (vision cone) để mô phỏng vùng tầm nhìn của NPC. Khi người chơi ngay bên cạnh NPC người chơi vẫn không bị nhìn thấy, trong khi người chơi cách xa NPC lại bị phát hiện như được minh họa ở hình 5.

Còn đối với RSM và FEMSM thì cả RSM và FEMSM đều có thiếu sót RSM ít đòi hỏi hơn khi nói về tốc độ xử lý, nhưng nó không cung cấp cơ chế để tính toán sự tương tác của âm thanh với các chướng ngại vật Trong RSM, âm thanh vẫn có thể cảm nhận được qua các bức tường và các vật thể khác mà trong thực tế các vật thể này có thể cản không cho âm thanh đi qua Điều này có thể được giải quyết bằng cách sử dụng một tia (raytrace) để phát hiện chướng ngại vật giữa nguồn và đích và sau đó áp dụng sự suy giảm độ lớn của âm thanh theo số lượng chướng ngại vật và độ cản âm của chúng.

Ngoài ra, các phương pháp tiếp cận RSM và FEMSM đều không xem xét đến tâm lý của con người tại thời điểm đó, cũng như những hạn chế về khả năng nghe của người đó Trong các phương pháp này, để xác định xemNPC có nghe thấy một âm thanh cụ thể hay không, cường độ của nó được kiểm tra với ngưỡng của NPC Tuy nhiên,

Hình 5: Vấn đề ở vision cone (McIntosh, 2015). âm thanh có thể được đặc trưng bởi nhiều thuộc tính (cường độ, tần số, v.v .), vì vậy việc kiểm tra dựa trên cường độ khá đơn giản và, do đó, mô phỏng không thực tế về nhận thức thính giác của con người.

SV, so với RSM và FEMSM, mặc dù với một mục đích khác, nhưng biểu diễn âm thanh theo hướng thực tế hơn, có tính đến trạng thái tâm lý của người nghe Nhưng cách SV biểu diễn âm thanh đã nằm ngoài tầm vực của luận văn này, vì nó nhằm mục đích giải thích âm thanh hơn là nhận thức âm thanh, đồng thời có nhu cầu khá cao về sức mạnh xử lý Sự mô tả của SV về âm thanh siết chặt các mối quan hệ giữa các khía cạnh môi trường, thể chất và tâm lý Việc đơn giản hóa sự mô tả này có thể đóng vai trò là nguồn cảm hứng cho việc mô tả âm thanh trong luận văn này trong tương lai, giúp em chuẩn bị tốt hơn để có thể đưa ra một mô hình nhận thức thực tế hơn.

Cuối cùng, đối với FSM nếu số trạng thái của NPC lớn thì việc quản lý các trạng thái và quá trình chuyển đổi giữa các trạng thái đó trở nên rất phức tạp và cồng kềnh và kết quả là tạo nên một "spaghetti" FSM như được minh họa ở hình dưới.

Hình 6: Một ví dụ về "spaghetti" FSM (Estrada, 2014).

Mặc dù HFSM có thể giải quyết vấn đề trên nhưng cả FSM và HFSM đều có một bất lợi đó là các trạng thái có quan hệ chặt chẽ với nhau, tức là, việc sửa đổi code cho trạng thái Nhàn rỗi sẽ ảnh hưởng trực tiếp đến việc liệu nó có còn đúng để trạng thái này được gọi từ code của các trạng thái khác hay không hoặc có thể có nghĩa là chúng ta sẽ phải cập nhật ngữ cảnh để chuyển trạng thái trên tất cả các code của các trạng thái khác Ví dụ nếu chúng ta sửa đổi code của trạng thái Nhàn rỗi để nhân vật thở gấp sau khi chạy khỏi kẻ thù, thì nếu nó không được gọi từ trạng thái Chạy thì nó sẽ không hợp lý.

3 Mô hình tìm đường đi (path-finding) cho NPC

Vì trong luận văn này, em sẽ tập trung nghiên cứu và thiết kế mô hình nhận thức, thị giác và thính giác choNPC, nên mô hình tìm đường đi này em sẽ sử dụng hệ thống dẫn đường (navigation system) dựa trên NavMesh được xây dựng sẵn trong Unity Hệ thống này sẽ giúp cho một nhân vật AI hay NPC có thể tìm đường đi trong màn chơi đồng thời tránh các vật cản và các nhân vật khác.

NavMesh và tìm đường đi ngắn nhất trong Unity

Hệ thống tìm đường trong Unity cần một cấu trúc dữ liệu riêng để biểu diễn các khu vực mà các nhân vật AI có thể đứng và di chuyển được Trong Unity, các nhân vật AI được mô tả như một hình trụ Khu vực có thể di chuyển được xây dựng tự động từ hình dạng của môi trường trong game bằng cách thử nghiệm các vị trí mà nhân vật AI có thể đứng Sau đó, các vị trí này được kết nối với một bề mặt nằm trên bề mặt của môi trường Bề mặt này được gọi là Navigation Mesh (viết tắt là NavMesh) NavMesh lưu trữ bề mặt này dưới dạng các đa giác lồi Đa giác lồi là một biểu diễn hiệu quả, vì chúng ta biết rằng không có sự cản trở nào giữa hai điểm bất kỳ bên trong một đa giác lồi Ngoài việc lưu trữ các biên của đa giác, Unity còn lưu trữ thông tin về đa giác nào là hàng xóm của nhau Điều này cho phép biểu diễn toàn bộ khu vực có thể di chuyển được bởi các nhân vật AI.

Hình 7: NavMesh (lớp màu xanh nằm trên bề mặt của bản đồ) (Unity Technologies, 2018). Để tìm đường đi giữa hai vị trí trong màn chơi, trước tiên Unity sẽ chuyển đổi vị trí xuất phát và vị trí đích thành đa giác gần nhất của chúng Sau đó, Unity sẽ bắt đầu tìm kiếm từ vị trí bắt đầu, thăm tất cả các đa giác hàng xóm cho đến khi đến được đa giác đích Trong quá trình này Unity cũng lưu lại các đa giác đã thăm cho phép chúng ta tìm được chuỗi các đa giác từ điểm bắt đầu đến điểm đích Thuật toán tìm chuỗi đa giác mà Unity sử dụng làA ∗

VìA ∗ hoạt động trên một đồ thị gồm nhiều nốt, nhưng NavMesh trong Unity lại được biểu diễn bởi một lưới đa giác, cho nên đểA ∗ hoạt động được trên NavMesh thì việc Unity cần làm là với mỗi đa giác, Unity sẽ chọn một vị trí trong đa giác đó để làm vị trí của nốt trong đồ thị Unity không đề cập về cách chọn vị trí này nhưng cách thông dụng nhất là chọn tâm của đa giác.

A ∗ là một giải thuật tìm kiếm có thông tin (informed-search) và còn gọi là tìm kiếm ưu tiên tốt nhất (best-first search).A ∗ hoạt động trên đồ thị có trọng số: bắt đầu từ một nốt bắt đầu cụ thể trên đồ thị, nó sẽ tìm đường dẫn đến nút mục tiêu đã cho với chi phí nhỏ nhất (quãng đường di chuyển ít nhất, thời gian ngắn nhất, v.v.) Nó thực hiện điều này bằng cách xây một cây của các đường đi bắt đầu từ nút xuất phát và mở rộng các đường đi đó mỗi lần một cạnh cho đến khi điều kiện kết thúc của nó được thỏa mãn.

Tại mỗi vòng lặp chính,A ∗ cần xác định đường đi nào cần mở rộng Việc làm này dựa trên chi phí của đường đi và ước tính chi phí cần thiết để mở rộng đường đi cho đến khi chạm mục tiêu Cụ thể,A ∗ chọn đường đi tối thiểu phương trình: f(n) =g(n) +h(n)

Trong đó, n là nốt tiếp theo trên đường đi, g(n) là chi phí của đường đi từ nốt bắt đầu đến nốt n và h(n) là một hàm heuristic ước tính chi phí của đường đi tốt nhất từ nốt n đến nút đích.A ∗ kết thúc khi đường đi mà nó chọn để mở rộng là đường đi từ nốt bắt đầu đến nốt mục tiêu hoặc nếu không có đường đi nào đủ điều kiện để được mở rộng Việc lựa chọn hàm heuristic phụ thuộc vào vấn đề cần giải quyết Nếu hàm heuristic là chấp nhận được (admissible), nghĩa là nó không bao giờ đánh giá quá cao chi phí thực tế để đến được nốt mục tiêu,A ∗ sẽ đảm bảo trả về một đường đi có ít chi phí nhất từ nốt đầu đến nốt mục tiêu.

Các hiện thực thường thấy củaA ∗ sử dụng hàng đợi ưu tiên (priority queue) để thực hiện việc lựa chọn các nốt có chi phí (ước tính) tối thiểu để mở rộng Hàng đợi ưu tiên này được gọi là open set hoặc fringe Tại mỗi bước của giải thuật, nốt có giá trị f(x) thấp nhất bị xóa khỏi hàng đợi, các giá trị f và g của các nốt lân cận của nó cũng được cập nhật tương ứng và các nốt lân cận này được thêm vào hàng đợi Giải thuật tiếp tục cho đến khi một nốt bị loại bỏ (nốt có giá trị f thấp nhất trong số tất cả các nốt trong hàng đợi) là nốt mục tiêu Giá trị f của nốt mục tiêu này cũng là chi phí của đường đi ngắn nhất, vì h tại nốt mục tiêu là 0 khi hàm heuristic là chấp nhận được (admissible).

Giải thuật được mô tả đến đây chỉ cho chúng ta độ dài của đường đi ngắn nhất Để tìm ra trình tự của các bước để đến được nốt mục tiêu, giải thuật có thể dễ dàng sửa đổi để mỗi nốt trên đường đi lưu thông tin về các nốt trước (predecessor) của nó Sau khi giải thuật được chạy, nốt kết thúc sẽ trỏ đến nốt phía trước của nó và cứ như thế, cho đến khi nốt trước của một nốt là nốt bắt đầu.

Ví dụ, khi tìm kiếm tuyến đường ngắn nhất trên bản đồ, h(x) có thể đại diện cho khoảng cách đường thẳng(straight-line distance) đến mục tiêu, vì đó là khoảng cách nhỏ nhất có thể có giữa hai điểm bất kỳ Đối với bản đồ dạng lưới (grid) việc sử dụng khoảng cách Manhattan hoặc khoảng cách ô vuông trở nên tốt hơn tùy thuộc vào các bước di chuyển có thể có (4 hướng hoặc 8 hướng).

Nếu hàm heuristic h thỏa mãn thêm điều kiệnh(x)≤d(x,y) +h(y)với mọi cạnh (x, y) của đồ thị (trong đó d là độ dài của cạnh đó) thì h được gọi là nhất quán (consistent) Với một heuristic nhất quán,A ∗ sẽ đảm bảo tìm ra đường đi tối ưu mà không cần xử lý bất kỳ nốt nào nhiều hơn một lần.

Sau khi đã tìm được chuỗi các đa giác và các điểm đại diện cho chúng từ vị trí đầu đến vị trí mục tiêu, các nhân vật AI sẽ không đi theo các điểm này mà Unity sẽ "làm gọn" lại đường đi đó để đạt được sự di chuyển tự nhiên hơn, không giống như robot Chuỗi các đa giác mô tả đường đi từ đa giác đầu đến đa giác đích được gọi là hành lang (corridor) Nhân vật AI sẽ đến đích bằng cách luôn hướng về phía góc có thể nhìn thấy tiếp theo của hành lang như được mô tả ở hình dưới.

Hình 8: Đường đi của nhân vật AI (Unity Technologies, 2018).

Sau khi tìm hiểu, em đã phát hiện ra một giải thuật làm gọn đường đi thông dụng khi làm việc với navigation mesh và cho ra kết quả tương tự như những gì mà Unity đã mô tả, giải thuật có tên là "String Pulling Algorithm". Giải thuật này giúp chúng ta tìm được đường đi ngắn nhất (danh sách các điểm cần phải đi qua) từ danh sách các tam giác đã tìm được khi áp dụng giải thuậtA ∗ (các đa giác lồi đều có thể được xây dựng từ các tam giác) Danh sách các tam giác này còn được gọi là "corridor".

Hình 9: String Pulling Algorithm (gamedev, 2018). Ở hình chữ thập trên, nếu chúng ta dùng một sợi dây bao xung quanh chữ thập này và kéo căng nó thì lúc này sợi dây sẽ tạo ra đường đi ngắn nhất và tự nhiên nhất khi đi xung quanh chữ thập này Hình bên dưới giúp chúng ta hiểu rõ hơn về giải thuật này.

Hình 10: Các bước thực hiện của String Pulling Algorithm (gamedev, 2018).

Chúng ta có thể thấy ở bước A, giải thuật bắt đầu bằng việc tạo ra một "funnel" với 1 đỉnh là vị trí bắt đầu trên đường đi và 2 cạnh trái và phải nối từ đỉnh đến 2 đầu mút cạnh chung của tam giác bắt đầu và tam giác liền kề nó, cạnh chung này được gọi là "portal" Các bước từ B đến D là sự di chuyển của 2 cạnh funnel men theo rìa (border) của corridor đến các portal tiếp theo Chú ý rằng sự di chuyển này luôn làm cho 2 cạnh của funnel gần nhau hơn. Ở bước E chúng ta có một vấn đề là nếu cạnh màu cam (cạnh trái) di chuyển về portal tiếp theo thì nó sẽ làm cho 2 cạnh funnel cách xa nhau hơn so với bước trước đó Trong trường hợp này chúng ta sẽ không di chuyển cạnh màu cam nữa mà thay vào đó di chuyển cạnh màu xanh ở bước F.

Thật không may, lúc này chúng ta gặp một vấn đề nữa đó là nếu di chuyển cạnh màu xanh đến portal tiếp theo thì sẽ làm cho 2 cạnh funnel chéo nhau và lúc này chúng ta phát hiện có một góc (corner) trong corridor Lúc này chúng ta cần thêm một điểm vào đường đi cuối cùng của mình đó là đầu mút của cạnh màu cam Ở bước G, chúng ta dời vị trí của funnel sao cho đỉnh của nó trùng với vị trí mà ta vừa thêm vào đường đi và khởi tạo lại 2 cạnh như bước đầu Giải thuật cứ tiếp tục cho đến khi 1 cạnh bất kỳ chạm đến vị trí đích. Để tóm tắt lại, giải thuật gồm có các bước sau:

• Di chuyển 2 cạnh funnel sao cho 2 cạnh càng gần nhau hơn.

• Nếu di chuyển 1 cạnh mà làm cho 2 cạnh xa nhau thì không di chuyển cạnh đó nữa.

Né tránh vật cản và RVO (Reciprocal Velocity Obstacles)

Trên đường đi của nhân vật AI, Unity sẽ lấy vị trí cần đến (corner) tiếp theo và dựa trên đó tìm ra hướng mong muốn và tốc độ cần thiết để đến đó Việc sử dụng vận tốc mong muốn (desired velocity) để di chuyển các nhân vật

AI có thể dẫn đến va chạm giữa các nhân vật với nhau Tính năng tránh chướng ngại vật sẽ chọn một vận tốc mới sao cho cân bằng giữa việc di chuyển theo hướng mong muốn và ngăn ngừa việc va chạm trong tương lai với các nhân vật khác Unity sử dụng Reciprocal Velocity Obstacles (RVO) (van den Berg, J et al, 2008) để dự đoán và ngăn chặn va chạm Để hiểu về RVO đầu tiên chúng ta cần tìm hiểu về Velocity Obstacles.

Vật cản vận tốc (Velocity Obstacles) của vật B đối với một nhân vật A là một tập hợp bao gồm tất cả các vận tốc của nhân vật A mà sẽ dẫn đến va chạm tại một thời điểm nào đó với vật B đang chuyển động với vận tốc nào đó Với định nghĩa đó, mọi nhân vật AI trong môi trường sẽ có thông tin về những vận tốc sẽ dẫn đến va chạm với các nhân vật/chướng ngại vật khác Bằng cách này, nhân vật AI có thể tránh vật cản thành công và đi đến được mục tiêu.

Xét một ví dụ đơn giản: có hai nhân vật AI A và B là hai điểm trong không gian với vị trí và vec tơ vận tốc như hình.

Hình 11: Hai nhân vật AI, A và B đang di chuyển.

Trong ví dụ này, nếu A cứ tiếp tục di chuyển với vận tốc đó, A sẽ va chạm với B Nghĩa là, vật cản vận tốc của

B đối với A đúng bằng vận tốc của A hay:V O A B (v B ) ={v A } Và với bất kỳ vận tốc nào khác ngoài VO, A sẽ không va chạm với B.

Tiếp theo xét một ví dụ phức tạp hơn một chút, ở đây nhân vật AI B có dạng là một hình tròn Trong trường hợp này, vật cản vận tốc sẽ bao gồm một dãy các vận tốc như hình dưới.

Hình 12: Nhân vật A đang di chuyển và nhân vật B hình tròn.

Dãy các vận tốc này là các giá trị sẽ dẫn đến sự cắt nhau giữa các vec tơ vận tốc và nhân vật B (hình tròn) và ở đây vật cản vận tốc của B đối với A sẽ là một tập hợp các vận tốc sẽ dẫn đến va chạm giữa A và B.

Trước khi trình bày mô hình toán học của vật cản vận tốc cho các trường hợp thực tế (các nhân vật có hình dạng tùy ý), chúng ta nên tìm hiểu về Minkowski Sum và ý nghĩa của nó trong điều hướng và lập kế hoạch đường đi.

Minskowki Sum: Trong hình học, tổng Minkowski (còn được gọi là sự giãn nở) của hai tập hợp vec tơ vị trí

(position vector) A và B trong không gian Euclide được xây dựng bằng cách cộng mỗi vec tơ trong A vào mỗi vec tơ trong B.

Lấy ví dụ như hình dưới: hai tập hợp vec tơ vị trí Q1 và Q2.

Hình 13: Một ví dụ về Minskowski Sum (Bonagiri, 2018). Ở đây, chúng ta lấy tổng vec tơ của tất cả các điểm trong hình vuông màu xanh lá cây với tất cả các điểm trong hình vuông màu đỏ Kết quả sẽ là hình vuông màu xanh lam Điều này cũng tương tự như việc trượt góc dưới bên trái của hình vuông màu xanh lá cây dọc theo các cạnh của hình vuông màu đỏ.

Trong các tình huống thực tế, hình dạng vật lý của các tác nhân không phải là một điểm Nhưng đối với việc thiết kế mô hình toán học, nên coi các nhân vật là các điểm, do đó sẽ đơn giản hơn để có được một mô hình tổng quát Lúc này chúng ta đã giảm thiểu bài toán tìm đường đi cho một nhân vật trong môi trường làm việc của nó xuống thành bài toán tìm đường đi cho một điểm trong môi trường cấu hình (configuration space) như được mô tả trong hình dưới.

Hình 14: Môi trường làm việc (workspace) của một nhân vật hình tam giác và môi trường cấu hình (configuration space) của cùng nhân vật đó khi xem nhân vật đó là một điểm (Mount & Eastman, 2018, trang 3). Để có được môi trường cấu hình của một nhân vật ta phải đi tìm các vật cản cấu hình (configuration obstacle hoặc C-obstacle) ứng với các vật cản trong môi trường làm việc sao cho nếu nhân vật không giao với một vật cản bất kỳ trong môi trường làm việc thì điểm mà sau khi đã biến đổi nhân vật đó thành điểm cũng sẽ không giao với vật cản cấu hình tương ứng trong môi trường cấu hình Để đơn giản, chúng ta hãy giả sử rằng điểm tham chiếu cho nhân vật R của chúng ta là tại gốc tọa độ Cho R(p) biểu thị sự dịch chuyển (translate) của nhân vật sao cho điểm tham chiếu của nó nằm tại điểm p Cho một vật cản P, C-obstacle tương ứng với nó được xác định là tập hợp các vị trí của R giao với P:

Hình 15: C-obstacle của vật cản P (Mount & Eastman, 2018, trang 4). Để tìm được C-obstacle của một vật cản P trong môi trường làm việc của một nhân vật R, ta sẽ áp dụng Minskowski Sum giữa tập vec tơ vị trí của P và tập đối của tập vec tơ vị trí của R (xem hình 14), tức là:

Ta thấy rằngq∈C(P)khi và chỉ khi R(q) giao với P, điều này đúng khi và chỉ khi tồn tại một điểmr∈Rvà p∈Psao chop=r+q(xem hình 14 bên trái), điều này tương đương vớiq=p+ (−r), mà−r∈ −Rvàp∈Pnên q∈P⊕(−R)(xem hình 14 bên phải) Đến đây ta cóq∈C(P)khi và chỉ khiq∈P⊕(−R), vì vậyC(P) =P⊕(−R).

Hình 16: C-obstacle và Minskowski Sum (Mount & Eastman, 2018, trang 5).

Tiếp theo, chúng ta có một cách biểu diễn quỹ đạo của một nhân vật bằng toán học nếu biết trước vị trí p và vec tơ vận tốc v của nó: λ(p,v) ={p+tv,t>0} Ở đây, quỹ đạo là tập hợp các vị trí của nhân vật theo thời gian trên đường đi của nó.

Và cuối cùng chúng ta có một định nghĩa chính thức của vật cản vận tốc của vật cản B so với nhân vật A như sau:

V O A B (v B ) ={v A |λ(p A ,v A −v B )∩B⊕(−A)6=/0} Ở đây, nếuv A ∈V O A B (v B ), A và B sẽ va chạm tại một thời điểm nào đó trong tương lai Nếuv A nằm ngoài vật cản vận tốc của B, cả hai vật sẽ không bao giờ va chạm Nếuv A nằm trên ranh giới của vật cản vận tốc, nó sẽ chạm (touch) với B vào một lúc nào đó trong tương lai Vật cản vận tốc là một hình nón như được mô tả ở hình dưới.

Hình 17: Vật cản vận tốc của nhân vật hình tròn B đang di chuyển với vận tốcv B đối với một nhân vật hình tròn A di chuyển với vận tốcv A (van den Berg et al, 2008, trang 142).

Từ định nghĩa đó, ta có những tính chất của vật cản vận tốc như sau:

• Tính bất biến khi dịch chuyển (Translation Invariance) v A ∈V O A B (v B )⇔v A +u∈V O A B (v B +u)

∈/V O A B (v B )nếuv A nằm trong nửa mặt phẳng bên trái củaV O A B (v B )vàv A −→

∈/V O A B (v B )nếuv A nằm trong nửa mặt phẳng bên phải củaV O A B (v B )như được mô tả như hình 18 Dấu∈của các tính chất vừa kể có thể được tự do thay thế bằng∈,/ −→

Hình 18: Vật cản vận tốc và hai nửa mặt phẳng trái, phải (van den Berg et al, 2008).

Từ đó ta có tính chất thứ ba (−→

∈/ có thể được tự do thay thế bằng←−

Nhận thức thị giác ở con người

Thị giác của con người là một chức năng quan trọng và không thể thiếu Nó giúp chúng ta nhận biết được sự vật, sự việc xung quanh Nói về thị giác của người sẽ có rất nhiều khía cạnh khác nhau, nhưng ở đây sẽ chỉ nói đến những đặc tính có thể sử dụng được trong mô hình. Điều tất nhiên mà ai cũng biết đó là con người có 2 mắt, nhờ vào 2 mắt này mà con người có thể nhìn được trong phạm vi200 ◦ Mắt tập trung ánh sáng vào mặt sau của mắt, sử dụng các tế bào hình que và tế bào hình nón để phát hiện ánh sáng và màu sắc Thị lực lớn nhất sẽ nằm ở vùng chính giữa phía trước và giảm dần khi cách rời xa trung tâm Các tế bào hình nón tập trung dày đặc trong trung tâm võng mạc, nó chịu trách nhiệm phân biệt màu sắc tạo nên tầm nhìn trung tâm (central vision) Ngược lại các tế bào hình que cho phép nhìn sự vật trong điều kiện thiếu ánh sáng và nhận biết chuyển động tạo nên tầm nhìn ngoại vi (peripheral vision).

• Central Vision: là phần quan trọng nhất ở thị giác của con người Nó cho phép con người có thể nhìn thấy hình dạng, màu sắc, và các chi tiết một cách rõ ràng và sắc nét.

• Peripheral Vision: là thị giác giúp con người có khả năng phát hiện chuyển động bên ngoài tầm nhìn trực tiếp Nó chịu trách nhiệm việc phát hiện sự vật ở điều kiện ánh sáng yếu, hoặc ban đêm nhưng lại không nhạy cảm với màu sắc - ngược lại với tầm nhìn trực tiếp.

Central Vision sẽ được tập trung mô phỏng trong mô hình và Peripheral Vision sẽ không được mô phỏng Vì để giảm tính phức tạp của mô hình và giảm sự nhập nhằng trong việc phát hiện người chơi của NPC Tức là nếu mô phỏng Peripheral Vision thì NPC sẽ có thể phát hiện người chơi bằng những chuyển động nhỏ nhất kể cả khi NPC không thực sự nhìn thấy người chơi, điều này gây ra các trường hợp người chơi bị phát hiện nhưng không rõ lý do, tạo cảm giác thiếu công bằng cho người chơi Ngoài ra, giác quan thứ sáu (khả năng cảm nhận có người sau lưng) cũng sẽ được mô phỏng để khắc phục hạn chế như đã đề cập ở phần 2.4.

Mô hình đề xuất cho nhận thức thị giác ở con người

Mô hình thị giác cơ bản

Trước khi đi đến mô hình đề xuất, thì cần giới thiệu về mô hình thị giác cơ bản được sử dụng phần lớn trong các trò chơi ngày nay Bao gồm ba phần chính đó là: "view distance", "view cone" và "line-of-sight".

Hình 22: Mô hình thị giác cơ bản (Rabin & Delp, 2008) Ở mô hình này, người chơi được cho là bị NPC phát hiện khi thỏa mãn đủ 3 điều kiện đó là:

1 Vị trí của người chơi nhỏ hơn khoảng cách nhìn (view distance) của NPC.

2 Vị trí của người chơi nằm trong vùng nhìn nón (view cone).

3 Tồn tại một đường thẳng (line-of-sight) nối liền giữa người chơi và NPC mà không đi qua một vật cản nào.

Kiểm tra đầu tiên là khoảng cách giữa người chơi và NPC sẽ tính toán như khoảng cách giữa hai điểm Tuy nhiên, sẽ hiệu quả hơn nếu chúng ta chỉ so sánh khoảng cách bình phương thay vì khoảng cách thực để tránh tính toán căn Ví dụ, nếu NPC có tầm nhìn là 10, chọn vị trí gốc tọa độ (0,0,0) và người chơi đang ở tọa độ (6,7,0) Việc kiểm tra chỉ đơn giản là so sánh giữa10 2 0và6 2 +7 2 +0 2 Do đó NPC có thể nhìn thấy được người chơi (85 Walk to Door (thành công) -> Nút chuỗi (đang chạy) -> Open Door (thành công) -> Nút chuỗi (đang chạy) -> Walk through Door (thành công) -> Nút chuỗi (đang chạy) -> Close Door (thành công) - > Nút chuỗi (thành công) -> lúc này nút chuỗi sẽ trả về Success cho cha của nó Nếu một nhân vật không thể đi đến cửa, có lẽ do lối đi bị chặn, thì việc mở cửa hoặc đi qua cửa không còn phù hợp nữa. Nút chuỗi sẽ trả về Failure ngay tại thời điểm mà việc đi đến cửa không thành công và nút cha của nút chuỗi này sau đó có thể xử lý lỗi đó.

Ngoài ứng dụng như đã nói đến ở trên nút chuỗi còn có một ứng dụng đặc biệt khác Hãy xem xét ví dụ dưới:

Hình 38: Một ví dụ khác về nút chuỗi (Sequence) (Simpson, 2014).

Trong ví dụ trên, nút chuỗi không chỉ định nghĩa một chuỗi các hành động mà còn có cả các kiểm tra điều kiện(tests) Các nút con kiểm tra xem nhân vật có đói không, có thức ăn không, có kẻ thù xung quanh không và chỉ khi tất cả những điều này trả về Success cho nút chuỗi, nhân vật đó mới ăn thức ăn Sử dụng các chuỗi như thế này cho phép chúng ta kiểm tra một hoặc nhiều điều kiện trước khi thực hiện một hành động Tương tự với câu lệnh if và với cổng AND trong vi mạch Vì tất cả các nút con cần phải thành công và những nút con đó có thể là bất kỳ tổ hợp nào của các nút kết hợp (composite), nút trang trí(decorator) hoặc nút lá (leaf), nó cho phép chúng ta thực hiện việc kiểm tra điều kiện khá dễ dàng trong bộ não của NPC.

Behavior Designer

Mô hình hành vi của NPC sẽ được hiện thực bằng cách sử dụng Behavior Designer Behavior Designer là một asset có thể tải về từ Unity Asset Store Behavior Designer cung cấp một editor trực quan với một API mạnh mẽ cho phép chúng ta dễ dàng xây dựng một cây hành vi từ đơn giản đến phức tạp Asset này đã bao gồm hàng trăm hành vi được định nghĩa sẵn, giúp chúng ta có thể tạo ra các AI phức tạp mà không cần phải viết một dòng code nào, nếu muốn chúng ta có thể tự viết code cho hành vì mới hoặc chỉnh sửa các hành vi sẵn có tùy theo ý muốn của mình.

Hình 40: Cửa sổ editor của Behavior Designer (Opsive, n.d).

7 Ứng dụng mô hình vào game cụ thể

Mô hình đề xuất ở trên sẽ được ứng dụng vào các NPC cụ thể ở đây là kẻ thù (emnemy) cho tựa game DyingHope do em tự thiết kế và phát triển Quá trình thiết kế và phát triển sẽ được trình bày chi tiết trong phần này.

Quá trình thiết kế

High Concept Document

High Concept document là tài liệu ghi chép lại những gì tổng quát nhất của game: ý tưởng chính, chức năng chính, Tài liệu bao gồm những ý tưởng được trình bày một cách ngắn gọn, súc tích Toàn bộ tài liệu chỉ mất 1 đến 2 phút để đọc Mục đích của tài liệu này là để trình bày với Producer hay Publisher Nếu được cho phép, thì ý tưởng trong tài liệu này sẽ được phát triển thành một game hoàn chỉnh Nó giống như CV cho game để thuyết phục Publisher cho phép phát triển game.

Dying Hope là một game chiến thuật mang yếu tố stealth, thách thức người chơi lập kế hoạch và giải quyết vấn đề với những công cụ mình có.

• Game có góc nhìn top-down, người chơi có thể tùy thích zoom in, zoom out.

• Game lấy bối cảnh là một thế giới hoang tàn sau đại dịch Zombie.

• Người chơi sẽ điều khiển 1 hoặc nhiều nhân vật cùng lúc, mỗi nhân vật có bộ kỹ năng khác nhau.

• Mỗi màn chơi sẽ có 1 nhiệm vụ chính, người chơi sẽ vượt qua màn chơi nếu hoàn thành nhiệm vụ này.

• Trong màn chơi sẽ có những "setup" của quân địch là những puzzle mà người chơi cần giải quyết để có thể hoàn thành nhiệm vụ.

• Mỗi kẻ địch là một nhân vật AI thông minh, với các đặc tính khác nhau theo từng loại và người chơi phải tận dụng những kỹ năng nhân vật của mình để tiêu diệt kẻ địch. Động lực của người chơi

Trong mỗi màn chơi, người chơi sẽ điều khiển nhân vật của mình vượt qua kẻ địch để hoàn thành nhiệm vụ của màn đó và sẽ tiến tới các sự kiện tiếp theo trong cốt truyện.

Thể loại game nhập vai có yếu tố chiến thuật và stealth

Người chơi muốn nhắm đến

Game nhắm đến những người chơi thích suy nghĩ theo lối chiến thuật, giải quyết vấn đề bằng những công cụ có sẵn và những người chơi thích đắm mình vào thế giới sau đại dịch zombie.

Những điểm nổi bật trong game

• Các kẻ thù có độ thực tế cao.

• Tri giác của AI được mô phỏng một cách thực tế.

• Đồ họa chi tiết, thế giới rộng lớn.

• Điều khiển dễ dàng, trơn tru.

• Hành vi của các nhân vật phải thực tế.

• Cốt truyện gay cấn, hấp dẫn.

• Thế giới chi tiết, chân thực.

Game Design Document

Game Design document là bản thiết kế của toàn bộ game với tất cả các khía cạnh Từng chi tiết nhỏ nhặt nhất cũng phải được đề cập ở đây.

Mục I - Tổng quan về game Ý tưởng game

Dying Hope là một game chiến thuật thời gian thực (real time strategy) với lối chơi lén lút (stealth) ở đó người chơi sẽ tính toán, lập kế hoạch cho riêng mình để vượt qua các thử thách và hoàn thành nhiệm vụ cuối cùng ở mỗi màn chơi.

Dying Hope sẽ lấy bối cảnh trong một thành phố hoang tàn sau đại dịch zombie Thành phố này nằm trên một hòn đảo được nối với đất liền thông qua một cây cầu duy nhất, do phát hiện có đại dịch nên cây cầu này đã bị phá hủy làm cho hòn đảo tách biệt với thế giới bên ngoài.

• Thế giới rộng lớn, chi tiết.

• Nhân vật sống động, dễ dàng điều khiển.

• AI có hành vi chân thực giống con người.

• Game sẽ diễn biến theo cốt truyện Cốt truyện sẽ được chia làm nhiều chương, mỗi chương sẽ gồm nhiều màn chơi, mỗi màn chơi ứng với một nhiệm vụ nhất định mà người chơi phải hoàn thành để qua màn kế.

Dying Light là một game chiến thuật thời gian thực kết hợp với lối chơi lén lút Game sử dụng đồ họa 3D với góc hình từ trên xuống (top-down) Xuyên suốt game sẽ là một câu chuyện trải dài, ở đó người chơi sẽ điều khiển các nhân vật chính dần dần vượt qua các màn và đi đến kết truyện.

Người chơi muốn nhắm đến

Dyling Hope sẽ phù hợp với những game thủ thích thử thách, thích giải đố (puzzle solving) Đồng thời người chơi cũng cần có suy nghĩ logic, chiến thuật để đưa ra những lời giải cho bài toán trước mắt và lập kế hoạch để hoàn thành nhiệm vụ cuối cùng của màn chơi.

Người chơi sẽ đóng vai như là một người chỉ đường, để điều khiển và dẫn dắt các nhân vật trong game hoàn thành nhiệm vụ của họ ở mỗi màn chơi Người chơi sẽ phải liên tục suy nghĩ, thử nghiệm nhiều cách khác nhau để tìm được giải pháp tốt nhất để dẫn dắt các nhân vật vượt qua các thử thách trong màn chơi dưới dạng những câu đố (puzzle).

Khi vào game người chơi sẽ thấy được màn hình Menu chính của game Ở đây người chơi có thể chọn chơi màn mới hoặc chơi lại các màn hình đã lưu, xem các màn đã lưu, chỉnh sửa các setting trong game và thoát game. Khi người chơi chọn một màn chơi mới hoặc chọn một màn chơi mình đã lưu, người chơi sẽ vào màn hình chơi game chính, nơi người chơi sẽ điều khiển nhân vật đề hoàn thành nhiệm vụ.

Trong màn hình Setting, người chơi có thể điều chỉnh âm thanh, ánh sáng cũng như những setting liên quan đến đồ họa và các phím để điều khiển nhân vật.

Trong màn hình Pause khi chơi game, người chơi có thể chọn chơi màn chơi mới, chơi các màn chơi mình đã lưu, hoặc lưu màn hiện tại Ngoài ra người chơi cũng có thể vào màn hình Setting hoặc trở về màn hình Menu chính.

Các asset 3D trong game sẽ dùng theo dạng low poly do đó không yêu cầu cấu hình cao để chạy Ngoài ra, do game lấy bối cảnh thế giới hoang tàn nên màu sắc và âm thanh trong game sẽ được thiết kế để gợi cảm giác buồn, trống vắng và một chút tăm tối.

Do hạn chế về thời gian và nhân lực, bên cạnh đó mục đích chính của game là để test mô hình đã được thiết kế trong môi trường game nên game chỉ có một màn chơi Màn chơi này là một phần của một thành phố Số lượng nhân vật trong màn chơi là 2 và số lượng NPC xấp xỉ 30 Mỗi nhân vật sẽ có 2 hành động cơ bản và 4 kỹ năng riêng biệt.

Mục II - Gameplay và Mechanic

Game sẽ diễn biến theo cốt truyện Cốt truyện sẽ được chia làm nhiều chương, mỗi chương sẽ gồm nhiều màn chơi, mỗi màn chơi ứng với một nhiệm vụ nhất định mà người chơi phải hoàn thành để qua màn kế Nhiệm vụ có thể là tiêu diệt các kẻ thù chỉ định hoặc giúp các nhân vật đi đến một vị trí nhất định trên bản đồ,

Mỗi màn chơi sẽ là một bản đồ khá rộng, các kẻ thù (enemy) là bọn Decayer và Zombie sẽ được bố trí theo từng khu vực trên bản đồ dưới dạng những câu đố (puzzle) Người chơi có thể hoàn thành nhiệm vụ bằng nhiều con đường khác nhau trên bản đồ Ngoài ra trên bản đồ còn có vật phẩm mà người chơi có thể nhặt được ví dụ: đạn, dao.

Nhiệm vụ của người chơi là điều khiển các nhân vật của mình với những kỹ năng riêng biệt của họ, để tiêu diệt hoặc không để kẻ thù phát hiện mình và hoàn thành nhiệm vụ Người chơi không cần tiêu diệt hết tất cả kẻ thù trên bản đồ để hoàn thành nhiệm vụ Ngoài ra, người chơi cũng có khả năng điều khiển camera để thuận tiện cho việc quan sát kẻ thù.

Mỗi màn chơi, người chơi có thể điều khiển 1 hoặc nhiều nhân vật cùng lúc, mỗi nhân vật sẽ có 3 máu, nếu bất kỳ nhân vật nào mất hết 3 máu này thì coi như nhiệm vụ thất bại, lúc này người chơi có quyền lựa chọn bắt đầu lại màn chơi từ đầu hoặc bắt đầu lại từ các lần lưu trước đó.

Quá trình phát triển

Main Camera

Những gì camera này thấy được cũng là những gì mà người chơi thấy trên màn hình Như trong thiết kế, camera sẽ có góc nhìn top-down với góc nghiêng 45 độ theo trục x của nó, với phép chiếu perspective Camera này được gắn một script CameraController do em tự viết để người chơi có thể điều khiển camera này (di chuyển, xoay, zoom)

Hình 42: Class diagram của CameraController.

• Instance: CameraController là một singleton vì trong mỗi màn chơi chỉ tồn tại duy nhất 1 instance của class này Biến Instance này giúp các class khác có thể tham chiếu đến instance duy nhất của class này.

• panSpeed: tốc độ khi di chuyển camera (có giá trị là 30).

• panBorderThickness: độ dày các biên của màn hình mà khi người chơi di chuyển con trỏ chuột trong các biên này thì camera sẽ bắt đầu di chuyển (có giá trị là 10).

• scrollSpeed: tốc độ di chuyển của camera khi zoom in, zoom out (có giá trị là 20).

• rotationSpeed: tốc độ khi xoay camera (có giá trị là 30).

• yPanLimit: giới hạn zoom của camera, với x là cận dưới, y là cận trên (có giá trị là x: 10, y: 30).

• lookAt: là vị trí tâm camera, khi xoay thì camera sẽ lấy vị trí này làm tâm xoay Vị trí này sẽ thay đổi khi di chuyển camera.

Khi màn chơi bắt đầu CameraController sẽ raycast để lấy vị trí trung tâm của view trong màn chơi và gán vào biến lookAt Ở mỗi frame, nó sẽ xét xem có nhận được input từ người chơi không Nếu có và input này là để di chuyển camera thì camera sẽ di chuyển theo input của người chơi, khi di chuyển nó sẽ xét xem view của camera có nằm trong diện tích màn chơi không, nếu không thì camera sẽ ngừng di chuyển Tương tự, khi input là xoay thì camera sẽ xoay xung quanh điểm lookAt và khi input là zoom thì camera sẽ thay đổi khoảng cách của mình so với điểm lookAt và khi thay đổi sẽ xét điều kiện là tọa độ y của camera phải nằm trong khoảng của yPanLimit nếu nằm ngoài khoảng này camera sẽ không thay đổi.

Ngoài ra, Main camera cũng được gắn một script MouseControls để quản lý các input của nút chuột và các phím bấm khác Cụ thể là khi người chơi trỏ chuột vào những đối tượng không tương tác được, icon của con trỏ sẽ thay đổi để người chơi biết đồng thời sẽ bỏ qua bất kỳ input của nút chuột Song song đó, script này cũng kiểm tra và xử lí input về các tác vụ phụ trợ như đóng, mở Pause menu, đóng, mở Mission menu, highlight kẻ địch, quicksave, quickload, chọn nhân vật trong màn chơi.

Hình 43: Class diagram của MouseControls.

Nhân vật

Nhân vật, như đã được mô tả, có thể được điều khiển bởi người chơi để thực hiện các hành động và kỹ năng: đi, chạy, ngồi, Sự di chuyển của nhân vật trong màn chơi được thực hiện bằng NavMesh của Unity và các animation sẽ được quản lí bởi Animator để chạy các animation thích hợp cho từng hành động Hành vi của nhân vật sẽ được quản lí bởi script CharacterControlling.

Hình 44: Class diagram của CharacterControlling.

Các thuộc tính và hàm quan trọng:

• slotMapping: để map từng hành động và kỹ năng của nhân vật với các slot hành động thích hợp, để khi nhân vật thực hiện hành động hoặc kỹ năng thì các slot này sẽ thay đổi các chỉ số cũng như UI thích hợp, ví dụ: sau khi thực hiện kỹ năng bắn súng thì kỹ năng sẽ cooldown và slot của kỹ năng này sẽ thực hiện đếm ngược trên UI để người chơi biết là kỹ năng đang cooldown và chưa dùng được.

• characterStats: là các thuộc tính riêng biệt của từng nhân vật, ví dụ: tên, avatar, màu nền avatar, màu khi highlight, Được dùng để thay đổi UI khi nhân vật được chọn.

• walkSpeed, crouchWalkSpeed, runSpeed: có giá trị lần lượt là 2, 1, 3.5 cho tất cả nhân vật.

• HealthPoints: là một property dùng để quản lí máu của nhân vật Khi máu của nhân vật thay đổi thì nó cũng thực hiện việc gọi hàm callback để thay đổi UI của máu nhân vật và gọi hàm thực hiện hành động chết của nhân vật khi máu giảm về 0.

• currentAction: là hành động hoặc kỹ năng mà nhân vật đang thực hiện.

• CheckInput(): kiểm tra input từ các phím hành động và kỹ năng.

• ToggleSkill(string key): được gọi trong hàm CheckInput để thực hiện hành động thích hợp với phím đã bấm.

• MoveTo(Vector3 destination, MoveState state): ra lệnh cho NavMeshAgent di chuyển đến vị trí destination, với trạng thái state (có 3 giá trị: walk, run, crouchwalk), nhờ vào trạng thái này mà script sẽ thay đổi vận tốc di chuyển và animation cho phù hợp Khi các animation của nhân vật đang chạy thì một số có gọi các hàm để phát ra âm thanh của hành động ứng với nó (hành động đi sẽ gọi hàm PlayFootstepSound để phát ra âm thanh của bước chân).

• EndCurrentAction(): dừng hành động đang thực hiện và trở về trạng thái trước đó (nếu trước khi hành động nhân vật đang đứng thì sau khi dừng hành động nhân vật sẽ đứng, điều tương tự cũng áp dụng cho ngồi).

Khi màn chơi bắt đầu CharacterControlling sẽ gán máu của người chơi bằng với MAX_HEALTH_POINT và gán các giá trị thích hợp cho các field và property Ở mỗi frame, nếu nhân vật đang rảnh rỗi (idle) nó sẽ xét xem có nhận được input nhấp phím trái chuột của người chơi không, nếu có thì nó sẽ thực hiện chuyển đổi vị trí mà người chơi mới nhấp chuột thành vị trí trên NavMesh mà NavMeshAgent của nhân vật đi được, sau đó cho nhân vật đi đến vị trí đó Tương tự, khi người chơi bấm phím kỹ năng bất kỳ, thì nhân vật sẽ thực hiện kỹ năng đó cùng với thay đổi UI và animation cho người chơi biết được nhân vật đang thực hiện kỹ năng đó.

Như đã đề cập, mỗi nhân vật sẽ có 6 hành động có thể thực hiện ứng với 6 phím bấm (ngồi, nhặt đạn và 4 kỹ năng) Những hành động này sẽ có hành vi và các thuộc tính riêng biệt, nhưng để quản lý tốt hơn chúng đều sẽ được kế thừa từ một abstract class CharacterAction Mỗi hành động sẽ được gắn vào một game object rỗng và gán làm con của game object của nhân vật để dễ dàng cho việc thêm hoặc bớt các hành động mà không làm ảnh hưởng đến các thành phần khác của nhân vật.

Hình 45: Cách tổ chức game object của nhân vật Doc McCoy trong Unity Editor.

Hình 46: Class diagram của CharacterAction.

• coolDownTime: thời gian chờ giữa 2 lần thực hiện hành động.

• description: mô tả hành động (để người chơi mới dễ dàng sử dụng).

• limitNumber: số lần tối đa để thực hiện hành động (nếu có giá trị bằng 0 thì hành động không có giới hạn số lần thực hiện).

• coolDownAmount: lượng đếm ngược hiện tại, có giá trị từ 0 đến 1 Khi hành động đang đếm ngược (cooldown) thì biến này sẽ có giá trị là 1 giảm dần về 0 Nếu bằng 0 xem như việc đếm ngược đã hoàn tất.

• currentNumber: số lần thực hiện còn lại của hành động.

• isDisable: hành động có đang bị vô hiệu hóa không (hành động bị vô hiệu hóa khi số lần thực hiện bằng với limitNumber hoặc khi hành động đang đếm ngược hay coolDownAmount > 0).

• StartAction(), ActionInProgress(), EndAction(): mỗi hành động sẽ được chia thành 3 giai đoạn (bắt đầu, đang thực hiện và kết thúc) Ở giai đoạn bắt đầu, script ứng với hành động sẽ thay đổi UI, animation cũng như bật các skill indicator (các hiệu ứng để người chơi dễ dàng chọn mục tiêu), sau khi chọn mục tiêu xong sẽ chuyển sang giai đoạn đang thực hiện (hành động ngồi không cần chọn mục tiêu) Trong giai đoạn đang thực hiện, nếu mục tiêu nằm ngoài tầm thực hiện hành động thì nhân vật sẽ di chuyển đến mục tiêu và thực hiện hành động lên mục tiêu, nếu mục tiêu nằm trong tầm thực hiện thì nhân vật sẽ thực hiện hành động lên mục tiêu ngay Sau khi thực hiện hành động xong sẽ chuyển sang giai đoạn kết thúc Ở giai đoạn kết thúc, script sẽ tiến hành đếm ngược (cooldown) hành động, kiểm tra xem đã hết số lần thực hiện chưa để vô hiệu hóa hành động và thay đổi UI đề người chơi biết được những điều đó và cuối cùng là thay đổi animation và trạng thái của nhân vật trước khi thực hiện hành động Ví dụ: hành động Stealth Kill, khi bắt đầu thì con trỏ chuột sẽ thay đổi để người chơi biết là hành động đang chờ chọn mục tiêu, sau khi chọn mục tiêu phù hợp thì nhân vật sẽ đi đến sau lưng mục tiêu, khi đã đến sau lưng thì nhân vật thực hiện tiêu diệt mục tiêu và sau khi mục tiêu đã bị tiêu diệt thì hành động bắt đầu cooldown và nhân vật trở về trạng thái trước đó.

Từ abstract class ở trên, em đã tạo ra các class con tương ứng với các hành động như đã được mô tả trong thiết kế của game Các class con này sẽ có những điểm tương đồng với nhau là các thuộc tính và hàm mà nó thừa kế từ class cha nhưng đồng thời chúng cũng sẽ có những điểm riêng biệt tùy theo hành động mà nó mô tả, bởi các hành động có bản chất khác nhau Các class con này được mô tả như sau:

• CrouchAction: tương ứng với hành động ngồi chung của các nhân vật Hành động ngồi không có thời gian chờ cũng không có giới hạn số lần sử dụng Khi kích hoạt hành động ngồi, nhân vật sẽ dừng bất cứ hành động nào hiện tại bằng cách gọi hàm EndAction của hành động đó và biến currentAction của nhân vật sẽ được gán thành CrouchAction Trong khi hành động ngồi đang được kích hoạt, nhân vật được tự do di chuyển như khi đang idle nhưng hình thức di chuyển là crouch walk Ngoài ra, nhân vật cũng có thể chạy bằng cách nhấn đúp chuột vào vị trí thích hợp trong màn chơi nhưng khi này hành động ngồi sẽ bị hủy.

Hình 47: Các class CharacterAction con.

• InteractAction: là hành động nhặt vật phẩm chung của các nhân vật Các vật phẩm có thể nhặt được là: đạn (từ các thùng đạn), túi bẫy (kỹ năng Bait Bag của nhân vật Doc McCoy) Riêng các con dao từ kỹ năng Throw Knife của nhân vật John Cooper thì chỉ cần di chuyển lại gần là nhân vật sẽ tự động nhặt, do con dao có kích thước quá bé gây khó khăn trong việc chọn mục tiêu để nhặt Mỗi nhân vật chỉ nhặt được các vật phẩm phù hợp với mình, ví dụ: John Cooper chỉ nhặt được đạn pistol và dao mà không nhặt được đạn sniper và túi bẫy của Doc McCoy Khi thực hiện hành động này, nhân vật cũng được tự do di chuyển như đang idle. Khi người chơi chọn vật phẩm để nhặt, nếu khi chọn nhấn 1 lần chuột thì người chơi sẽ đi (walk) về vị trí của vật phẩm và thực hiện nhặt còn khi nhấn đúp chuột thì nhân vật sẽ chạy lại và nhặt, còn khi nhân vật đang ngồi thì sẽ crouch walk mà nhặt Trong lúc di chuyển lại vị trí vật phẩm, người chơi có thể hủy hành động bằng kích hoạt bất kỳ hành động nào khác kể cả hành động này Sau khi nhặt xong bộ đếm số vật phẩm sẽ tăng lên và nhân vật sẽ trở về trạng thái lúc trước khi hành động.

• StealthKillAction: là hành động tiêu diệt địch từ sau lưng của các nhân vật Hành vi của hành động này cũng tương tự như hành động nhặt đạn nhưng thay vì chọn vật phẩm thì ở đây người chơi sẽ chọn một kẻ thù bất kỳ miễn là kẻ thù đó đang không phát hiện nhân vật Sau khi chọn mục tiêu xong, nhân vật sẽ di chuyển về vị trí sau lưng của kẻ thù và tiêu diệt hắn Sau khi thực hiện xong nhân vật sẽ trở về trạng thái lúc trước khi hành động.

Mô hình nhận thức thị giác

Mô hình thị giác gồm hai thành phần đảm nhiệm hai chức năng khác nhau: DetectSystem cung cấp cho NPC khả năng phát hiện nhân vật và các đối tượng khác (xác chết, Bait Bag), FieldOfView vẽ ra các vùng tầm nhìn của NPC để người chơi dễ dàng quan sát.

Hình 48: Hai vùng nhìn của NPC.

DetectSystem cung cấp các cơ chế cho việc nhìn thấy và phát hiện (detect) các đối tượng Khi màn chơi khởi động DetectSystem sẽ lấy các thông số của các NPC (clearViewDistance, viewDistance, độ rộng Field of view, ) để xử lí và căn cứ vào những thông số này để điều chỉnh việc phát hiện phù hợp với từng loại NPC DetectSystem sẽ hoạt động trên hai vùng nhìn như đã thiết kế: vùng nhìn gần sẽ phát hiện được các đối tượng với bất kỳ độ cao nào, vùng nhìn xa chỉ phát hiện được các đối tượng có chiều cao cao ngang tầm mắt của NPC (vùng nhìn phía sau một vật chắn có chiều cao thấp hơn NPC cũng là vùng nhìn xa) DetectSystem vận hành như sau:

• Nhìn và phát hiện nhân vật: ở mỗi khung hình (frame), DetectSystem sẽ xét xem có nhân vật nào nằm trong vùng nhìn (field of view hay fov) của mình không bằng cách xét xem khoảng cách giữa nhân vật và NPC có nhỏ hơn khoảng cách nhìn (viewDistance) của NPC không và xét xem độ lớn của góc tạo bởi (1) đoạn thẳng nối từ nhân vật đến NPC và (2) đoạn thẳng ở chính giữa fov (chia fov thành 2 phần bằng nhau) có nhỏ hơn 1/2 độ rộng của fov không Nếu các điều kiện này thỏa thì xem như có nhân vật nằm trong vùng nhìn của NPC và lúc này sẽ tiếp tục xét xem nhân vật đang nằm ở vùng nhìn gần hay vùng nhìn xa bằng cách so sánh khoảng cách giữa nhân vật và NPC với khoảng cách của vùng nhìn gần (clearViewDistance).

Hình 49: Người chơi đang nằm trong vùng nhìn (gần) của NPC.

– Nếu nhân vật đang ở vùng nhìn gần, ta sẽ thực hiện raycast từ vị trí của NPC đến vị trí ngực của nhân vật với độ dài của ray là clearViewDistance Trong Unity, raycast là việc bắn một tia từ vị trí bất kỳ, hướng bất kỳ và độ dài bất kỳ để xét xem trên đường đi của tia có va chạm với đối tượng nào không. Khi raycast đến ngực nhân vật, nếu ray đó chạm nhân vật thì xem như NPC đã nhìn thấy và phát hiện nhân vật Nếu ray hit một vật chắn có chiều cao thấp hơn NPC thì tiếp tục xét xem nhân vật có đang ngồi (crouch) hay không Nếu nhân vật đang ngồi thì NPC không phát hiện nhân vật, nếu ngược lại thì NPC phát hiện nhân vật Nếu ray chạm một vật cản có chiều cao cao hơn NPC thì xem như không phát hiện nhân vật.

– Nếu nhân vật đang ở vùng nhìn xa, ta sẽ thực hiện raycast từ vị trí của NPC đến vị trí ngực của nhân vật với độ dài của ray là viewDistance Khi raycast đến ngực nhân vật, nếu ray đó chạm nhân vật hoặc một vật chắn có chiều cao thấp hơn NPC thì tiếp tục xét xem nhân vật có đang ngồi hay không Nếu nhân vật đang ngồi thì NPC không phát hiện nhân vật, nếu ngược lại thì NPC phát hiện nhân vật Nếu ray chạm một vật cản có chiều cao cao hơn NPC thì xem như không phát hiện nhân vật.

• Nhìn và phát hiện Bait Bag của Doc McCoy và xác chết: mỗi NPC sẽ có một SphereCollider, trong Unity SphereCollider là component có thể được gắn vào bất kỳ đối tượng nào, để phát hiện sự va chạm với các đối tượng khác SphereCollider tạo ra một hình cầu xung quanh NPC với bán kính bằng với viewDistance và khi SphereCollider này va chạm với Bait Bag hoặc xác chết, ta sẽ tiến hành xét tiếp các điều kiện khác Việc sử dụng SphereCollider giúp giảm thiểu sự ảnh hưởng đến hiệu suất của game, thay vì chúng ta phải gọi hàm ở mỗi khung hình để xét xem khoảng cách từ Bait Bag hay xác chết đến NPC có bé hơn viewDistance của NPC không, thì việc dùng SphereCollider sẽ loại bỏ việc gọi hàm ở mỗi khung hình và bây giờ chỉ cần xét SphereCollider có va chạm với các đối tượng hay không và việc này sẽ được hệ thống vật lý bên dưới của Unity đảm nhận, từ đó đảm bảo được hiệu suất của game Khi SphereCollider va chạm với Bait Bag hay xác chết, ta sẽ xét xem các đối tượng này có được các NPC nào khác phát hiện hay chưa bằng cách xét một biến boolean, tránh trường hợp NPC phát hiện một đối tượng nhiều lần và liên tục đưa ra hành động để xử lý Nếu các đối tượng đó chưa được NPC nào phát hiện, thì ta sẽ xét tiếp xem các vật này có đang nằm trong vùng nhìn gần không Nếu có thì ta sẽ raycast đến chúng và nếu ray này chạm chúng thì xem như NPC đã phát hiện và sẽ thay đổi trạng thái của các đối tượng này thành "đã bị phát hiện" vì thế các đối tượng đó sẽ bị bỏ qua trong các lần xem xét tiếp theo.

• Phát hiện nhân vật sau lưng bằng giác quan thứ sáu: giác quan thứ sáu cũng được mô phỏng bằng SphereC- ollider trên Khi SphereCollider va chạm với nhân vật, thì ta sẽ xét xem khoảng cách từ nhân vật đến NPC có bé hơn khoảng cách mà giác quan thứ sáu của NPC cảm nhận được không Nếu bé hơn, ta sẽ tiến hành đếm ngược một khoảng thời gian đặt trước và nếu đếm ngược về 0 thì xem như NPC cảm nhận được nhân vật đang ở sau lưng mình.

FieldOfView giúp vẽ các vùng nhìn của NPC, từ đó người chơi biết được NPC các vùng nhìn và từ đó tránh được việc bị NPC phát hiện Việc này giúp giao tiếp rõ ràng các thông tin của NPC hay game đến người chơi, loại bỏ các trường hợp người chơi bị NPC phát hiện mà không rõ lí do, gây cảm giác trò chơi không công bằng.FieldOfView vẽ các vùng nhìn bằng việc thực hiện hàng loạt các raycast từ vị trí của NPC, theo các hướng khác nhau và với độ dài bằng với viewDistance Lấy các điểm cuối của ray trong trường hợp ray không va chạm vật nào và lấy các điểm va chạm nếu ray va chạm với vật khác, từ các điểm này chúng ta có thể vẽ ra một mesh tạo bởi nhiều tam giác và tạo nên vùng nhìn của NPC Để vẽ một mesh trong Unity, chúng ta đầu tiên tạo ra một mesh rỗng, sau đó gán các đỉnh vào mảng mesh.vertices và thứ tự của các đỉnh này sao cho cứ 3 đỉnh là tạo thành một tam giác vào mảng mesh.triangles (cùng tập đỉnh nhưng thứ tự của các đỉnh này trong mesh.triangles khác nhau sẽ cho ra các mesh có hình dạng khác nhau) Mesh này sẽ được cập nhật từng khung hình do NPC có thể di chuyển.Việc vẽ vùng nhìn từ các raycast có thể được mô tả như hình dưới:

Hình 50: Chấm đen là vị trí NPC, các chấm trắng là vị trí cuối của các ray.

Chúng ta có thể thấy rằng, càng tăng số lượng ray thì càng làm cho vùng nhìn rõ ràng và chính xác hơn, nhưng lại ảnh hưởng đến hiệu suất của game Vì vậy, cần phải chọn số lượng ray thích hợp để cân bằng giữa việc vẽ vùng nhìn đẹp mắt và đảm bảo hiệu suất của game, trong game hiện tại em đã chọn thực hiện 20 raycast để vẽ (số này chúng ta có thể tùy chỉnh trong game).

Hình 51: Sự khác biệt khi thực hiện ít raycast và nhiều raycast.

Sau khi đã có được mesh chúng ta có thể thiết lập màu sắc cho mesh này bằng cách gán cho nó một material.Material trong Unity sẽ quyết định màu sắc cũng như các tính chất bên ngoài của nó (độ bóng, độ phản chiếu ánh sáng, có phát ra ánh sáng không, ) Hình dưới là kết quả có được sau khi thực hiện các bước trên.

Hình 52: Vùng nhìn gần của NPC (Zombie).

Khi có một vật chắn hoàn toàn (có chiều cao cao hơn NPC) thì vùng phía sau vật chắn này NPC sẽ không nhìn thấy và tạo ra một vùng mù Việc áp dụng phương pháp trên cũng cho ra kết quả như mong đợi đó là vùng nhìn phía sau của vật chắn sẽ không được vẽ.

Hình 53: Vùng nhìn gần khi có vật cản cao hơn tầm mắt của NPC (Zombie).

Từ những kết quả trên, bây giờ chúng ta đã có được vùng nhìn gần Tiếp theo ta cần vẽ vùng nhìn xa, so với vùng nhìn gần thì việc tạo ra một mesh cho vùng nhìn xa được cấu tạo bởi nhiều hình tam giác là rất khó khăn, vì các tam giác này không có một đỉnh chung giống như trong trường hợp của vùng nhìn gần Vì vậy, dẫn đến việc xác định thứ tự các đỉnh để tạo thành các tam giác cũng rất khó khăn Do đó, em đã quyết định vẽ mesh của vùng nhìn xa bằng những đường cong được cấu tạo bởi nhiều đoạn thẳng Các đầu mút của những đoạn thẳng này được xác định từ việc thực hiện raycast để vẽ vùng nhìn gần Việc này tương ứng với việc vẽ vùng nhìn gần nhưng ta lại loại bỏ những đường nối từ vị trí cuối của raycast đến NPC.

Hình 54: Chấm đen là NPC, các chấm trắng là các điểm có được từ việc raycast.

Trong trường hợp không có vật cản nào trong vùng nhìn của NPC, ta sẽ thu được kết quả sau:

Hình 55: Hai vùng nhìn của NPC (Zombie) khi không có vật cản.

Còn trong trường hợp có vật cản có chiều cao thấp hơn tầm mắt của NPC trong vùng nhìn, từ việc xác định các vị trí cuối của các ray mà ở đó chúng va chạm vật cản, ta biết được ranh giới của vùng nhìn xa ở sau vật cản và từ đó có thể vẽ được vùng nhìn xa Điều này tương tự với việc khi có vật cản có chiều cao cao hơn tầm mắt củaNPC, nhưng thay vì trong trường hợp này chúng ta sẽ có một vùng mù ở sau vật cản, thì ta sẽ dùng vùng mù đó vẽ thành vùng nhìn xa.

Hình 56: Các vùng nhìn của NPC (Zombie) khi có vật cản thấp hơn tầm mắt.

Mô hình nhận thức thính giác

Mô hình nhận thức thính giác được hiện thực như đã thiết kế và được gói vào thư viện Messaging Library với mục đích module hóa mô hình từ đó có thể tích hợp vào bất kỳ dự án nào Các thành phần của mô hình như sau:

Hình 57: Các thành phần của mô hình thính giác.

Như đã thiết kế, Message biểu diễn các tín hiệu âm thanh phát ra từ nguồn, ví dụ: khi nổ súng sẽ phát ra một âm thanh lớn thì khi này Message sẽ biểu diễn tiếng súng này mà cụ thể là các đặc điểm của nó (mô tả của âm thanh: tiếng nổ súng, độ lớn: 80dB, tần số: 1200Hz, ) Nhưng trong quá trình phát triển, em đã thêm vào một thuộc tính MaxTravelDistance để biểu diễn độ dài quãng đường lớn nhất mà âm thanh này có thể truyền trong không khí trước khi độ lớn của nó trở nên quá nhỏ không thể nghe được mà sự giảm độ lớn của âm thanh là do tính chất của âm thanh (luật bình phương nghịch đảo) và do môi trường như đã được mô tả rõ ở phần 5.

Hình 58: Class diagram của Message.

Hình 59: Class diagram của Broadcaster và Main Broadcaster.

Broadcaster đảm nhận vai trò truyền các Message từ các Emitter đến các Listener đã đăng ký với nó Broad- caster là một class singleton vì chỉ luôn tồn tại duy nhất một đối tượng của class này để tránh việc một Message được truyền nhiều lần tạo ra các duplicate không cần thiết Broadcaster mặc định sẽ truyền Mes- sage đến tất cả các Listener đã đăng ký với nó mà không xét bất cứ điều kiện nào Nhưng chúng ta có thể hoàn toàn định nghĩa ra các Broadcaster mới với các cách truyền Message tùy thích bằng cách kế thừa class Broadcaster và override hàm Broadcast Trong màn chơi đã phát triển, em đã định nghĩa ra MainBroadcaster, Broadcaster này trước khi truyền sẽ tiến hành tìm đường đi ngắn nhất (dùng NavMesh) từ vị trí nguồn âm đến vị trí của các Listener đã đăng ký với nó để mô phỏng đường truyền của âm thanh như đã mô tả ở phần

5 Sau đó, dùng đường đi này để xét xem để tính toán sự suy giảm độ lớn của âm thanh và cuối cùng xét xem độ lớn của âm thanh sau khi truyền đến Listener có vượt qua ngưỡng nghe của Listener hay không.

Nếu vượt qua thì sẽ tạo ra một copy của Message ban đầu và thay đổi độ lớn của nó thành độ lớn sau khi đã tính toán suy giảm để sau đó tiến hành giai đoạn dự đoán nguồn âm của các NPC là Listener Ngược lại, nếu độ lớn âm thanh không vượt qua ngưỡng nghe thì không truyền, điều này tương đương với thực tế là âm thanh (message) khi đến vị trí Listener thì độ lớn đã bị giảm đến mức không còn nghe được nên việc truyền Message đến Listener đó không có ý nghĩa Để giảm bớt số lần tìm đường đi dùng NavMesh (việc tìm đường đi ngắn nhất tốn nhiều performance) trước khi tìm đường đi, MainBroadcaster sẽ xét xem khoảng cách của nguồn phát Message với từng Listener có nằm trong phạm vi MaxTravelDistance của Message đó không Nếu Listener nào nằm ngoài phạm vi đó thì bỏ qua việc tìm đường vì khi này độ lớn của âm thanh đã giảm về một số rất bé (gần bằng 0) khi đến Listener, vì vậy việc tìm đường và truyền Message là không có ý nghĩa Trong thiết kế, MaxTravelDistance của một âm thanh có thể được tính toán bằng cách lấy độ lớn của âm thanh phát ra (được đo cách nguồn 1 mét) và dùng các công thức bên dưới để tính ra khoảng cách mà tại đó độ lớn của âm thanh bằng 0.

Trong đó,A 1 là độ lớn của âm thanh sau khi suy giảm theo khoảng cách (dB),A 0 là độ lớn của âm thanh nguồn vàD p là độ dài của đường đi ngắn nhất giữa nguồn âm và NPC tính bằng mét, còn 1 ở đây chính là 1 mét, mô hình giả định rằng độ lớn của âm thanh nguồn là độ lớn được đo cách nguồn 1 mét.

Trong đó,A2là độ lớn âm thanh còn lại sau khi suy giảm do khoảng cách và môi trường truyền (dB) đã được áp dụng.A 1 là kết quả của công thức ở trên M bằng 1 dB/km (10 −3 dB/m).D p là độ dài đường đi ngắn nhất được trả về từ NavMesh và được tính bằng mét.

Ví dụ cụ thể, âm thanh phát ra từ một cuộc đối thoại có độ lớn là 60dB (Walker, 2014) thì âm thanh này có thể truyền đến khoảng cách gần 1000 mét để độ lớn giảm về 0 Nhưng nếu lấy 1000 mét tương ứng với

1000 đơn vị độ dài trong màn chơi thì con số này rất lớn (độ dài của màn chơi chỉ xấp xỉ 100 đơn vị độ dài trong Unity) và việc xét Listener có nằm trong phạm vi MaxTravelDistance của Message là không có ý nghĩa Trong thực tế, để âm thanh có thể truyền được 1000 mét thì sẽ đòi hỏi không có vật cản hay vật chất nào hấp thụ năng lượng âm thanh trên đường truyền nhưng điều này không đúng trong màn chơi, vì trong màn chơi có rất nhiều vật chất và đối tượng như cây cối, nhà cửa, xe cộ, và chúng hoàn toàn có thể hấp thu năng lượng âm thanh nếu đặt trong trường hợp thực tế Vì vậy, em đã giải quyết vấn đề này bằng cách định nghĩa trước MaxTravelDistance của các âm thanh sao cho phù hợp với đơn vị trong màn chơi và phù hợp với nhận thức của người chơi về âm thanh đó trong thực tế, ví dụ như âm thanh của một cuộc đối thoại trong thực tế thì khoảng cách tối đa để nghe được mà người chơi thấy hợp lí là khoảng 20 mét thì MaxTravelDistance của âm thanh đó trong màn chơi là 20 đơn vị độ dài trong Unity Từ MaxTravelDistance đó chúng ta có thể dễ dàng tính ra độ lớn tại nguồn của âm thanh Các giá trị này có thể sai lệch so với thực tế nhưng điều quan trọng ở đây không phải là giá trị thực tế mà là cảm nhận của người chơi thấy nó thực tế, ví dụ cuộc đối thoại xảy ra ở vị trí (0, 0, 0) ở đầu màn chơi nhưng một Listener vẫn có thể nghe được âm thanh từ cuộc đối thoại đó ở vị trí (100, 0, 0) ở cuối màn chơi thì lúc này người chơi sẽ nhận thấy có điều không hợp lý, thay vào đó nếu Listener chỉ nằm trong phạm vi 20 đơn vị độ dài của Unity so với vị trí (0, 0, 0) mới có thể nghe được thì

Decayer (kể cả Leader Decayer) 9 Bảng 3: Bảng emitterID của các đối tượng trong màn chơi. lúc này người chơi sẽ thấy hợp lý hơn (giống với những gì mà người chơi quan sát được trong thực tế hàng ngày).

Hình 60: Class diagram của Emitter.

Emitter đảm nhận vai trò truyền các Message khi có âm thanh phát ra đến Broadcaster mà nó đã liên kết Khi khởi tạo một Emitter chúng ta có thể truyền một đối tượng của Broadcaster này vào để liên kết với nó Mỗi loại Emitter sẽ được định danh bằng một ID, ví dụ: nhân vật có ID là 1, Decayer có ID là 2, hoặc chúng ta có thể định danh từng Emitter cụ thể bằng một ID tương ứng, ví dụ: nhân vật John Cooper có ID là 1, DocMcCoy có ID là 2, Tất cả các Emitter có mặt trong màn chơi và ID được mô tả trong bảng 3.

Transcript Travel distant (đvđd) Frequency (Hz) Is noise?

Bảng 4: Mô tả Message tương ứng với các âm thanh được phát ra trong màn chơi

Khi màn chơi được khởi tạo, các (nhóm) đối tượng trên sẽ khởi tạo cho mình một Emitter và gán ID phù hợp Khi bất kỳ đối tượng nào phát ra âm thanh mà cụ thể là khi đối tượng đó ra lệnh cho component AudioSource của nó phát một audio clip bất kỳ thông qua hàm Play hoặc PlayOneShot Khi này, chúng sẽ tạo ra một Message tương ứng với âm thanh đó và ra lệnh cho Emitter truyền Message đến Broadcaster đã liên kết thông qua hàm Emit Các âm thanh có thể được phát ra trong màn chơi được mô tả bởi Message trong bảng 4 (các giá trị chỉ mang tính ước lượng):

– FOOTSTEP_WALK, FOOTSTEP_RUN, FOOTSTEP_CROUCH: là những âm thanh phát ra khi nhân vật di chuyển tương ứng với đi, chạy và đi khom Những âm thanh này có thể được phát hiện bởi các kẻ địch là các NPC và khi phát hiện âm thanh này các kẻ địch sẽ tiến hành tìm kiếm nhân vật đó.

– STEALTH_KILL_SOUND: là âm thanh phát ra khi nhân vật thực hiện kỹ năng Stealth Kill trên một kẻ thù nào đó khiến kẻ thù đó phát ra âm thanh trước khi bị tiêu diệt.

– COIN_DROP: là âm thanh phát ra từ đồng tiền của kỹ năng Throw Coin của John Cooper khi chạm đất giúp đánh lạc hướng kẻ thù.

– BAG_DROP: là âm thanh phát ra từ túi bẫy của kỹ năng Bait Bag của Doc McCoy khi chạm đất.

– KNIFE_IMPACT: là âm thanh phát ra từ con dao của kỹ năng Throw Knife của John Cooper khi va chạm với một đối tượng khác.

– POUR_ACID: là âm thanh phát ra khi Doc McCoy thực hiện tiêu hủy xác kẻ thù bằng axit.

– GUNSHOT_PISTOL: là âm thanh phát ra khi John Cooper thực hiện kỹ năng Shoot Pistol.

– GUNSHOT_SNIPER: là âm thanh phát ra khi Doc McCoy thực hiện kỹ năng Shoot Sniper Rifle.

– GUNSHOT_IMPACT: là âm thanh phát ra khi đạn (của cả Pistol và Sniper rifle) chạm với một vật nào đó.

– AMMO_BOX_OPEN: là âm thanh phát ra khi nhân vật mở thùng đạn để lấy đạn.

– RELOAD_GUN: là âm thanh phát ra khi nhân vật nạp đạn cho súng của mình.

– GENERATOR: là tiếng ồn do máy phát điện tạo ra, đóng vai trò là tiếng ồn từ môi trường.

– ZOMBIE_SCREAM: là tiếng kêu của Zombie khi phát hiện và rượt đuổi nhân vật, âm thanh này giúp thông báo cho các kẻ địch khác nhân vật đã bị phát hiện.

– DECAYER_SHOUT: là tiếng kêu của Decayer khi phát hiện ra nhân vật, giúp thông báo cho đồng bọn của mình.

Quân địch (NPC)

Các kẻ thù trong màn chơi chính là các NPC mà em sẽ áp dụng các mô hình đã thiết kế vào để giúp chúng phát hiện được các nhân vật và từ đó đưa ra được hành vi thích hợp Vì vậy, ngoài những component cơ bản thì các NPC sẽ được gắn thêm các component giúp cho việc nhận thức Như đã đề cập, trong màn chơi sẽ có 3 loại kẻ địch: zombie, Decayer và Leader Decayer Các component quan trọng của một kẻ địch bao gồm:

• NavMeshAgent: là một component có sẵn của Unity, giúp cho một đối tượng trong màn chơi có thể tìm đường và di chuyển trên NavMesh đã được xây dựng sẵn.

• Enemy: là một script mà em tạo ra nhằm quản lý việc tương tác giữa các nhân vật và kẻ thù Cụ thể là khi nhân vật chọn mục tiêu cho các kỹ năng thì script này sẽ giúp phân biệt đối tượng là kẻ địch với các đối tượng khác trong màn chơi, ví dụ: khi thực hiện kỹ năng Stealth Kill thì khi người chơi chọn đối tượng có component Enemy thì đây mới là mục tiêu phù hợp và nhân vật mới bắt đầu hành động Ngoài ra, script này còn quản lý các tác vụ khác như làm nổi bật (highlight) kẻ thù trong màn chơi (thông qua hàm ToggleOutline) để người chơi dễ dàng quan sát cũng như biết được các kẻ thù đang bị che khuất bởi các đối tượng khác trong màn chơi do góc nhìn của camera, một tác vụ khác đó là việc thay đổi kẻ thù thành xác chết khi kẻ thù đó bị tiêu diệt, ví dụ: khi một kẻ địch chết thì kẻ địch này sẽ thực hiện animation chết và từ đó thì khi nhân vật chọn mục tiêu cho kỹ năng thì kẻ địch này được nhận dạng là một xác chết thay vì là một kẻ địch còn sống (script DeadBody được kích hoạt).

Hình 64: Class diagram của Enemy.

• ListenerNPC: là script mà em tạo ra để cung cấp cho kẻ địch khả năng nghe các âm thanh cần thiết trong màn chơi Khi màn chơi khởi động, script này sẽ khởi tạo một đối tượng Listener trong mô hình thính giác và đăng ký với MainBroadcaster Sau đó, cứ mỗi 100ms (thời gian để cho Message được tích trữ trong hàng đợi) thì các Message trong hàng đợi sẽ được xử lý thông qua hàm FindGreatestIntensityMessage của Listener.Sau khi xử lý xong sẽ kiểm tra xem có tìm được Message có cường độ lớn nhất không Nếu không tức là kẻ địch không nghe thấy được âm thanh nào và sẽ không có phản ứng Nếu có tức là kẻ địch nghe thấy một âm thanh nào đó, thì sau 160ms (thời gian phản ứng trung bình của con người khi nghe âm thanh) sẽ truyền Message này sang cho component Cognitive để tiến hành dự đoán nguồn âm thanh và đưa ra hành vi thích hợp.

Hình 65: Class diagram của ListenerNPC.

• Cognition: là module cung cấp cho kẻ địch khả năng dự đoán nguồn âm thanh và đưa ra hành vi hợp lý.

Cuối chu kỳ xử lý các Message của Listener, Message có độ lớn lớn nhất sẽ được đưa vào module Cognition để tiến hành tính toán và dự đoán ra vị trí của nguồn âm thanh thông qua hàm calculateFromMessage và lưu vị trí nguồn âm đó vào biến estimatedPos Sau đó xét các đặc điểm của Message đó và đưa ra hành vi, ví dụ: nếu nhận được Message mô tả tiếng súng do nhân vật phát ra tức là GUN_SHOT_SOUND và Emitter ID là

1 thì kẻ địch này sẽ di chuyển đến vị trí đã dự đoán là estimatedPos để tìm kiếm nhân vật đã nổ súng.

Hình 66: Class diagram của Cognition.

• BehaviourTree: là một component trong package Behaviour Designer giúp cho một đối tượng hoạt động theo cây hành vi đã được thiết kế Trong màn chơi sẽ có một đối tượng BehaviourManager (cũng trong package Behaviour Designer) giúp quản lí việc thực hiện của các cây hành vi trong màn chơi Cụ thể là thông qua đối tượng đó, chúng ta có thể điều chỉnh chu kỳ cập nhật của các cây hành vi, dừng hoặc khởi động một cây hành vi bất kỳ trong màn chơi.Trong màn chơi hiện tại, em đã điều chỉnh chu kỳ cập nhật của các cây hành vi bằng với chu kỳ cập nhật của Unity (thời gian giữa hai lần gọi hàm Update) Cây hành vi ở đây đóng vai trò là bộ não của các kẻ địch giúp cho chúng có thể tự hoạt động, tự quyết định thực hiện một tác vụ nào đó Ví dụ: khi màn chơi bắt đầu, ở chu kỳ cập nhật đầu tiên của cây hành vi kiểm tra xem có thấy hay nghe được nhân vật hay không, nếu không cây hành vi sẽ thực hiện tác vụ đi tuần tra ở các vị trí đã đặt trước; ở chu kỳ cập nhật tiếp theo một nhân vật đột nhiên bắn súng tạo ra âm thanh lớn, lúc này mô hình thính giác đã giúp cho các kẻ địch nghe thấy được âm thanh đó và đã dự đoán ra nguồn âm, lúc này component Cognitive của các kẻ địch đã nhận được một Message, cây hành vi kiểm tra các điều kiện và điều kiện nghe âm thanh từ nhân vật đã thỏa mãn, lúc này cây hành vi sẽ thực hiện tác vụ di chuyển về vị trí đã dự đoán cung cấp bởi component Cognitive Như đã thiết kế, mỗi loại kẻ địch sẽ có các hành vi khác nhau, do đó dẫn đến các cây hành vi cũng khác nhau, cụ thể các cây hành vi đã được thiết kế (xem mục Kẻ thù phần 7.1.2 ) trong Behaviour Designer như sau:

– Cây hành vi của Zombie:

* Đầu tiên cần xét xem Zombie còn sống hay không (isDead), nếu không thì sẽ thực hiện hành động chết và cây hành vi sẽ ngừng chạy Nếu còn sống thì ta sẽ xét đến nhánh phải Alive để đưa ra hành động thích hợp.

* Tiếp đến cần xét xem Zombie có đang báo động không (isAlert) Nếu không thì xét tiếp các nhánh bên phải (Detect Player, Distract, Zombie Patrol), nếu có thì xét tiếp Zombie có đang thấy nhân vật không (isSeePlayer), nếu không thì zombie sẽ tiến hành đi tìm nhân vật (Search) xung quanh vị trí cuối cùng mà zombie nhìn thấy nhân vật, nếu có thì sẽ thực hiện hành động rượt đuổi nhân vật Nếu trong lúc đuổi người chơi nằm trong tầm tấn công của Zombie, lúc này Zombie sẽ thực hiện tấn công (Attack), hoặc khi không thấy nhân vật nữa, lúc này Zombie sẽ tìm kiếm nhân vật (Search) Trong lúc tấn công hoặc rượt đuổi một nhân vật, nếu có một nhân vật khác cũng lọt vào tầm nhìn hay tầm tấn công thì Zombie sẽ rượt hoặc tấn công nhân vật gần nhất với mình.

* Nếu zombie đang không alert thì sẽ xét xem người chơi có đang lọt trong tầm nhìn không Nếu không thì sẽ xét tiếp các điều kiện của các nhánh bên phải, nếu có thì Zombie sẽ chuyển sang trạng thái alert.

* Nếu Zombie không alert cũng không nhìn thấy nhân vật, thì xét xem có nghe thấy âm thanh không. Nếu không thì sẽ xét tiếp các điều kiện của nhánh bên phải, nếu có (Distract) thì sẽ tiến hành đi tới vị trí dự đoán của nguồn âm và thực hiện tìm kiếm bất kể âm thanh nghe được là âm thanh do nhân vật phát ra hay là tiếng ồn.

* Nếu toàn bộ các điều kiện trên đều không thỏa, tức là Zombie không phát hiện điều gì bất thường, Zombie sẽ tiến hành đi tuần tra (Zombie Patrol) Nếu Zombie được đặt sẵn các vị trí tuần tra thì nó sẽ đi qua lại các vị trí này, nếu không có thì Zombie sẽ đứng yên Sau khi tìm kiếm nhân vật hay nguồn âm, nếu tìm kiếm thất bại nó sẽ quay lại các vị trí đi tuần nếu có, nếu không có vị trí đi tuần thì nó sẽ giữ nguyên vị trí.

Hình 67: Cây hành vi của Zombie được thiết kế trong Behaviour Designer.

– Cây hành vi của Decayer:

* Đầu tiên cần xét xem Decayer còn sống hay không (isDie), nếu không thì sẽ thực hiện hành động chết và cây hành vi sẽ ngừng chạy Nếu còn sống thì ta sẽ xét tiếp các điều kiện khác bên nhánh phải của cây hành vi để đưa ra hành động thích hợp.

* Tiếp đến cần xét xem Decayer có đang báo động không (isAlert) Nếu không thì xét tiếp các điều kiện của nhánh bên phải, nếu có thì xét tiếp Decayer có đang thấy nhân vật không (isSeePlayer),nếu không thì Decayer sẽ tiến hành đi tìm nhân vật xung quanh vị trí cuối cùng mà hắn nhìn thấy nhân vật hoặc xung quanh vị trí của xác chết nếu có phát hiện, nếu có thì sẽ thực hiện hành động rượt đuổi nhân vật, trong lúc rượt đuổi Decayer sẽ hô to để báo động cho các đồng bọn gần đó.Decayer sẽ đuổi đến khi hoặc người chơi nằm trong tầm tấn công, lúc này Decayer sẽ thực hiện

Hình 68: Cây hành vi của Decayer được thiết kế trong Behaviour Designer. tấn công, hoặc khi không thấy nhân vật nữa, lúc này Decayer sẽ tìm kiếm nhân vật Trong lúc tấn công hoặc rượt đuổi một nhân vật, nếu có một nhân vật khác cũng lọt vào tầm nhìn hay tầm tấn công thì Decayer sẽ rượt hoặc tấn công nhân vật gần nhất với mình.

* Nếu Decayer đang không alert thì sẽ xét xem người chơi hoặc xác chết có đang lọt trong tầm nhìn không Nếu không thì sẽ xét tiếp các điều kiện của nhánh bên phải, nếu có thì Decayer sẽ chuyển sang trạng thái alert.

Một số hình ảnh trong game

Hình 71: Doc McCoy (trái) và John Cooper (phải).

Hình 73: Zombie đang đi tuần tra.

Hình 74: Vùng tầm nhìn (viewcone) của Zombie.

Hình 75: Zombie bị thu hút bởi tiếng ồn của máy phát điện.

Trong phần này, em sẽ trình bày những kết quả thu được sau khi kiểm thử các mô hình khi đã được áp dụng vào NPC trong game Dying Hope Quá trình kiểm thử sẽ được thực hiện trên NPC Decayer vì NPC này có đầy đủ các chức năng và hành vi so với các NPC khác và các Decayer này được kiểm thử trên một màn chơi đặc biệt tạo điều kiện thuận lợi hơn cho việc kiểm thử so với màn chơi đã được xây dựng trong game Vì màn chơi đặc biệt này cho phép thêm bớt các đối tượng rất dễ dàng, nhanh chóng giúp cho quá trình kiểm thử diễn ra nhanh hơn Sau đây là những testcase và kết quả thu được để biết được các mô hình có đáp ứng được những chức năng cơ bản như đã được đề ra không.

Kiểm thử mô hình thị giác

Dưới đây là những testcase được thực hiện trên mô hình thị giác và kết quả thu được:

• Nhân vật đứng trong vùng nhìn gần của NPC: NPC đã thành công phát hiện nhân vật (vùng nhìn chuyển dần sang màu vàng).

Hình 76: Nhân vật bị phát hiện khi đứng trong vùng nhìn gần của NPC.

• Nhân vật ngồi trong vùng nhìn gần của NPC: NPC đã thành công phát hiện nhân vật (vùng nhìn chuyển dần sang màu vàng) Điều này cho thấy rằng NPC vẫn phát hiện người chơi trong vùng nhìn gần dù nhân vật có đứng hay ngồi và điều này khớp với những gì mà em đã mong đợi.

Hình 77: Nhân vật bị phát hiện khi ngồi trong vùng nhìn gần của NPC.

• Nhân vật đứng trong vùng nhìn xa của NPC: NPC đã thành công phát hiện nhân vật (vùng nhìn chuyển dần sang màu vàng) Kết quả thu được như mong đợi vì vùng nhìn xa sẽ giúp phát hiện các đối tượng cao hơn tầm mắt của NPC.

Hình 78: Nhân vật bị phát hiện khi đứng trong vùng nhìn xa của NPC.

• Nhân vật ngồi trong vùng nhìn xa của NPC: NPC đã không phát hiện nhân vật Đây là kết quả mà em mong đợi, vì vùng nhìn xa sẽ không phát hiện được các đối tượng thấp hơn tầm mắt của NPC (nhân vật khi ngồi sẽ thấp hơn tầm mắt của NPC).

Hình 79: Nhân vật không bị phát hiện khi ngồi trong vùng nhìn xa của NPC.

• Nhân vật đứng sau vật cản (thùng rác) cao hơn tầm mắt của NPC: NPC đã không phát hiện nhân vật Kết quả giống như mong đợi, vì khi có vật cản cao hơn tầm mắt trong vùng nhìn sẽ tạo nên một vùng phía sau vật cản mà NPC không thể thấy được, vì vậy NPC không thể nhìn thấy nhân vật sau vật cản.

Hình 80: Nhân vật không bị phát hiện khi đứng sau vật cản (thùng rác) cao hơn tầm mắt của NPC.

• Nhân vật ngồi sau vật cản (thùng rác) cao hơn tầm mắt của NPC: NPC đã không phát hiện nhân vật Kết quả thống nhất với trường hợp ở trên: NPC không thể thấy bất kỳ đối tượng nào sau vật cản, dù nhân vật có đứng hay ngồi cũng không phát hiện được.

Hình 81: Nhân vật không bị phát hiện khi ngồi sau vật cản (thùng rác) cao hơn tầm mắt của NPC.

• Nhân vật đứng sau vật cản (rào chắn) thấp hơn tầm mắt của NPC: NPC đã thành công phát hiện nhân vật (vùng nhìn chuyển dần sang màu vàng) Mô hình đã hoạt động như mong đợi Các vật cản thấp hơn tầm mắt của NPC sẽ tạo nên một vùng nhìn có chức năng tương tự như vùng nhìn xa phía sau chúng Vì vậy, việc nhân vật đứng trong vùng nhìn này cũng tương tự như việc nhân vật đứng trong vùng nhìn xa nên đã bị NPC phát hiện.

Hình 82: Nhân vật bị phát hiện khi đứng sau vật cản (rào chắn) thấp hơn tầm mắt của NPC.

• Nhân vật ngồi sau vật cản (rào chắn) thấp hơn tầm mắt của NPC: NPC đã không phát hiện nhân vật Kết quả thu được giống như mong đợi Vì việc nhân vật ngồi trong vùng nhìn phía sau vật cản này cũng tương tự như việc nhân vật ngồi trong vùng nhìn xa nên không bị NPC phát hiện.

Hình 83: Nhân vật không bị phát hiện khi ngồi sau vật cản (rào chắn) thấp hơn tầm mắt của NPC.

Kiểm thử mô hình thính giác

Dưới đây là những testcase được thực hiện trên mô hình thính giác và kết quả thu được:

• Nhân vật bắn súng, phát ra một âm thanh lớn và có một NPC gần đó: NPC đã thành công nghe được âm thanh tiếng súng và dự đoán đúng nguồn âm (đoạn thẳng màu vàng là đường nối từ vị trí NPC đến vị trí nguồn âm mà nó dự đoán) Trong trường hợp này, âm thanh phát ra lớn và do không có vật cản trên đường truyền âm, nên NPC dự đoán nguồn âm khá chính xác.

Hình 84: Nhân vật bắn súng gần NPC.

Hình 85: NPC nghe và dự đoán khá chính xác nguồn âm của tiếng súng do nhân vật phát ra.

• Nhân vật bắn súng, cách xa NPC và có một vật cản giữa nhân vật và NPC: NPC đã thành công nghe được âm thanh tiếng súng nhưng dự đoán nguồn âm không chính xác (lệch khá xa so với vị trí thực của nguồn âm) Kết quả thu được như mong đợi của em Trong trường hợp này, âm thanh cách xa NPC do đó độ lớn âm thanh khi đến tai NPC đã bị giảm nhiều và do vật cản trên đường truyền âm càng làm tăng độ sai lệch khi dự đoán, nên NPC dự đoán nguồn âm không chính xác.

Hình 86: Nhân vật bắn súng cách xa NPC.

Hình 87: NPC nghe nhưng dự đoán không chính xác nguồn âm của tiếng súng do nhân vật phát ra.

• Nhân vật bắn súng, cách xa NPC và có một nguồn phát ra tiếng ồn (máy phát điện) ở gần NPC: NPC đã không nghe được âm thanh tiếng súng Mô hình hoạt động như mong đợi của em Trong trường hợp này, âm thanh cách xa NPC do đó độ lớn âm thanh khi đến tai NPC đã bị giảm nhiều và cộng với sự ảnh hưởng của tiếng ồn từ máy phát điện, nên NPC không nghe được tiếng súng.

Hình 88: Nhân vật bắn súng cách xa NPC có ảnh hưởng của tiếng ồn từ máy phát điện.

Hình 89: NPC không nghe được tiếng súng do nhân vật phát ra do ảnh hưởng của tiếng ồn từ máy phát điện.

• Nhân vật ném ra một đồng tiền, phát ra âm thanh để thu hút NPC (bán kính của vòng tròn màu xanh nhạt, không có hoa văn thể hiện khoảng cách tối đa mà âm thanh của đồng tiền phát ra di chuyển được trước khi độ lớn giảm về rất nhỏ NPC không thể nghe được, xấp xỉ 0):

Hình 90: Nhân vật ném đồng tiền về phía NPC.

Trường hợp 1: NPC được áp dụng AgeFilter để thể hiện sự ảnh hưởng của độ tuổi đến khả năng nghe, cụ thểNPC được gán độ tuổi là 18 (độ tuổi với khả năng nghe hoàn hảo) Ngoài ra, ảnh hưởng của độ tuổi này đã được nhân lên 5 lần để dễ nhận thấy ảnh hưởng của nó, vì thiết kế ban đầu có các hệ số ảnh hưởng khá nhỏ.Trong trường hợp này, NPC nghe được âm thanh của đồng tiền, dự đoán nguồn âm và quay mặt về phía đồng tiền.

Hình 91: NPC thành công nghe được âm thanh đồng tiền và quay mặt về phía nó.

Trường hợp 2: NPC được áp dụng AgeFilter với giá trị tuổi là 50 (chênh lệch nhiều so với trường hợp 1). Trong trường hợp này, NPC không nghe được âm thanh của đồng tiền do ảnh hưởng của độ tuổi đến khả năng nghe, giống như mong đợi của em.

Hình 92: NPC không nghe được âm thanh đồng tiền.

Kiểm thử mô hình hành vi

Dưới đây là những testcase được thực hiện trên mô hình hành vi và kết quả thu được:

• Khi NPC phát hiện nhân vật, NPC báo động với đồng bọn và rượt đuổi nhân vật.

Hình 93: NPC kêu gọi đồng bọn và rượt đuổi nhân vật.

• Khi nhân vật nằm trong tầm tấn công, NPC tấn công nhân vật bằng súng của mình.

Hình 94: NPC tấn công nhân vật bằng súng.

• Khi không thấy nhân vật nữa, NPC sẽ tiến hành tìm kiếm xung quanh vị trí cuối cùng nhìn thấy nhân vật.

Hình 95: NPC thực hiện tìm kiếm.

• Khi phát hiện xác chết, NPC sẽ di chuyển đến đó và tìm kiếm thủ phạm xung quanh đó.

Hình 96: NPC phát hiện xác chết.

Hình 97: NPC thực hiện tìm kiếm sau khi phát hiện xác chết.

• Khi phát hiện Bait Bag, NPC sẽ di chuyển đến đó và bị Bait Bag làm mù tạm thời Khi đang bị mù, NPC sẽ báo động cho đồng bọn.

Hình 98: NPC phát hiện Bait Bag.

Hình 99: NPC bị làm mù khi lại gần Bait Bag.

9 Đánh giá và hướng phát triển

Đánh giá

Mô hình tìm đường đi:do sử dụng hệ thống NavMesh được xây dựng sẵn trong Unity nên việc tìm đường đi của các NPC diễn ra rất chính xác và hiệu quả Trong lúc di chuyển, không xuất hiện tình trạng các NPC va chạm hay chắn đường đi của nhau Vì vậy, việc di chuyển của NPC trong màn chơi diễn ra rất tự nhiên và chân thật, không giống như những con robot Nhưng trong thời gian đầu, do sử dụng thư viện có sẵn nên em cũng gặp không ít khó khăn trong việc làm quen cũng như sử dụng đúng các hàm, các utility có sẵn để giúp việc tìm đường diễn ra hiệu quả và chính xác nhất Mặc dù vậy, em đã cố gắng xem các video hướng dẫn, cùng với việc lên các diễn đàn của Unity để tìm hiểu và do đó em đã khắc phục được khó khăn.

• Mô hình thị giác đã giúp cho các NPC phát hiện được nhân vật và các đối tượng khác (Bait Bag, xác chết) một cách thành công trong trường hợp không có vật che chắn và không phát hiện khi các đối tượng khi bị che chắn hoặc nằm ngoài tầm nhìn Lúc đầu, việc vẽ ra vùng tầm nhìn của các NPC có ảnh hưởng lớn đến tốc độ xử lý của game Mặc dù, mỗi vùng tầm nhìn được vẽ ra không ảnh hưởng nhiều đến tốc độ xử lý của game nhưng vì trong màn chơi có khá nhiều NPC nên việc vẽ ra vùng tầm nhìn cho tất cả NPC mang lại ảnh hưởng không nhỏ Vì vậy, sau đó em đã quyết định trong một thời điểm chỉ vẽ cho một NPC, người chơi có thể xem vùng tầm nhìn của NPC khác bằng cách nhấp chuột vào nó và vùng tầm nhìn củ NPC hiện tại sẽ không được vẽ Các vùng tầm nhìn (vùng nhìn gần, xa, bị chắn không hoàn toàn, hoàn toàn) cũng hoạt động đúng như trong thiết kế Nhưng vùng tầm nhìn bị chắn không hoàn toàn có một lỗi em đã phát hiện được trong lúc chơi thử game mà lúc thiết kế em không để ý đến lỗi này Lỗi này phát sinh do tính chất của tầm nhìn trong không gian 3D nhưng lúc thiết kế em chỉ chú ý đến tính chất 2D của vùng tầm nhìn khi vẽ chúng.

Hình 100: NPC vẫn có thể thấy người chơi ở khoảng cách xa kể cả khi người chơi ngồi sau vật cản thấp hơn tầm nhìn NPC.

Khi một NPC hướng về một vật có độ cao thấp hơn nó thì vùng tầm nhìn phía sau vật đó là vùng bị che không hoàn toàn nghĩa là nếu nhân vật ngồi ở vùng đó thì sẽ không phát hiện, còn đứng thì sẽ bị NPC phát hiện Nhưng có một điều đáng chú ý là vùng nhìn phía sau vật này không phải chỉ là vùng nhìn bị che không hoàn toàn như mô hình thị giác hiện tại vẽ được mà sẽ có một vùng nhìn không bị che như trong hình trên mô tả Có nghĩa là kể cả khi nhân vật ngồi ở phía sau vật cản đó thì nhân vật vẫn có thể bị phát hiện nếu khoảng cách giữa nhân vật và vật cản đủ lớn Trong mô hình thị giác của em thì việc phát hiện nhân vật như mô tả ở trên vẫn cho ra kết quả đúng, nhưng việc vẽ vùng tầm nhìn thì lại không đồng nhất với việc phát hiện nhân vật Tức là, kể cả khi nhân vật ngồi phía sau vật cản này thì cũng sẽ bị phát hiện nếu khoảng cách so với vật cản đủ lớn Phát hiện được lỗi này và để đảm bảo sự đồng nhất giữa việc vẽ vùng tầm nhìn và việc phát hiện nhân vật, em đã chỉnh sửa việc phát hiện sao cho nếu nhân vật ngồi sau vật cản như trên thì sẽ không bị phát hiện dù cách vật cản bao nhiêu đi chăng nữa.

• Mô hình thị giác không tự phát hiện được vật nào có chiều cao cao hơn hay thấy hơn NPC để vẽ ra các vùng tầm nhìn hợp lý mà tất cả các đối tượng trong màn chơi đã được gắn nhãn (tag, layer) thủ công bởi em, do đó tốn không ít thời gian và công sức và vẫn có sai sót.

• Giác quan thứ sáu của các NPC (trừ Zombie) đã được mô phỏng thành công Các NPC này đã phát hiện được nhân vật khi nhân vật ở phía sau và gần NPC, nếu nhân vật ở đó quá lâu Nhưng hiện tại trong game chưa có cơ chế để báo cho người chơi biết anh/cô ta sắp bị phát hiện do giác quan thứ 6 của NPC Vì vậy, có nhiều trường hợp người chơi bị phát hiện nhưng không rõ vì sao.

• Nhờ vào mô hình thính giác các NPC đã có thể nghe các âm thanh trong màn chơi và phân biệt các âm thanh này dựa vào mô tả của chúng một cách thành công giống như mong đợi của em Các tính chất vật lý của âm thanh cũng được mô phỏng thành công (sự giảm độ lớn do khoảng cách, sự lan truyền của âm thanh trong không gian) Đồng thời, việc dự đoán nguồn âm của NPC cũng cho ra các kết quả như mong đợi Ngoài ra, em cũng đã thành công trong việc mô phỏng sự ảnh hưởng của tiếng ồn cũng như độ tuổi của NPC đến việc nhận thức âm thanh của chúng.

• Mặc dù vậy, hiện tại việc mô phỏng sự lan truyền của âm thanh vẫn dựa vào mặt phẳng NavMesh 2D mà chưa xét đến các đường truyền trong không gian 3D, vì vậy nếu màn chơi có địa hình cao thấp khác nhau sẽ cho ra kết quả không như mong đợi.

• Nhờ sử dụng công cụ Behaviour Designer, em đã thiết kế thành công cây hành vi cho các NPC dựa trên các hành vi mong muốn mà em đã định nghĩa trước Các NPC cũng đưa ra các hành vi hợp lý khi có tín hiệu từ các mô hình khác (nhìn thấy nhân vật, nghe tiếng súng, ) Mặc dù trong màn chơi có nhiều NPC và mỗi NPC lại có cây hành vi cho riêng mình, nhưng ảnh hưởng của cây hành vi đến tốc độ xử lý của game không đáng kể vẫn đảm bảo không giật, lag.

• Mặc dù vậy, em vẫn tự nhận thức được mình chưa khai thác được hết những tính năng hữu ích của công cụ Behaviour Designer này để thiết kế một cây hành vi hiệu quả và gọn gàng nhất, các hành vi có sự modular nhất không phụ thuộc vào bất kỳ hành vi nào khác, dễ dàng thêm bớt khỏi cây hành vi Lí do của hạn chế này xuất phát từ việc trong lúc nghiên cứu và tìm hiểu về công cụ này, các video hướng dẫn mà em đã tham khảo thì khá là đơn giản không đưa ra được các ví dụ chuyên sâu, cùng với các tài liệu đến từ nhà phát hành cũng hạn chế.

• Nhìn chung, game Dying Hope đã áp dụng thành công các mô hình đã thiết kế vào gameplay của mình, đúng theo những gì em đã mong đợi Chạy được 30 khung hình trên giây (fps) đối với một pc có chip Intel(R) Core(TM) i7-7500U, CPU @ 2.70GHz 2.90 GHz, RAM 8GB, chạy trên hệ điều hành Windows 10 64-bit. Đến thời điểm viết đánh giá này thì các lỗi (bug) trong game mà em phát hiện được qua nhiều lần chơi thử đã được sửa chữa Mặc dù vậy, vẫn không tránh khỏi việc còn tiềm tàng những lỗi khác mà em chưa phát hiện được Vì bản chất của game là một complex system, có rất nhiều sự tương tác của các thành phần cùng một lúc nên việc tìm ẩn lỗi là không thể tránh khỏi.

• Một điểm hạn chế là game này vẫn chưa được chạy thử trên nhiều máy có độ phân giải màn hình, cũng như cấu hình máy khác nhau nên chưa biết được hiệu suất của game sẽ thay đổi như thế nào trên mỗi dòng máy.

Hướng phát triển

Từ các đánh giá trên, em có để xuất hướng phát triển cho các mô hình cũng như game Dying Hope như sau:

• Ở giai đoạn cuối của luận văn, em đã có tìm hiểu và phát hiện hãng game Mimimi đã sử dụng một phương pháp độc đáo để cung cấp khả năng nhìn và vẽ các vùng tầm nhìn cho các NPC mà họ đã ứng dụng vào game của mình bằng cách sử dụng "shadow mapping" Họ sử dụng một camera gắn ở vị trí đầu của NPC và từ đó sinh ra một depth texture và dùng dựa vào các thông tin có được từ depth texture này để tô màu cho các vùng tâm nhìn của NPC (vùng nhìn gần, xa, vùng bị che khuất, ) Và đó là tất cả những gì họ đã mô tả Nếu sử dụng cách này người thiết kế không cần phải gắn nhãn cho các đối tượng một cách thủ công nữa và khắc phục được hạn chế đã đề cập trong phần đánh giá, đặc biệt hơn là cách này hoạt động kể cả khi địa hình của màn chơi có nhiều chỗ cao thấp khác nhau Do hạn chế về kiến thức, thời gian cũng như hạn chế về công cụ (bản Unity Pro do các công ty game thường sử dụng cho phép họ có nhiều tính năng và access được những utility sâu bên trong của Unity Engine) nên em đã quyết định không thay đổi cách hiện thực mô hình thị giác của mình Nhưng nhìn chung đây là một hướng phát triển rất có tiềm năng cho mô hình thị giác.

• Về mô hình thính giác, em sẽ tiếp tục nghiên cứu và tìm cách mô phỏng sự lan truyền của âm thanh trong không gian 3D chứ không đơn giản là 2D như hiện tại một cách hiệu quả, ít ảnh hưởng đến hiệu suất của game.

• Về cây hành vi, em sẽ tiếp tục tìm hiểu, học tập và xem các ứng dụng của công cụ Behaviour Designer trong các game trên thị trường để lấy đó làm ví dụ để có thể nâng cao hiệu suất của cây, cũng như khai thác triệt để các tiện ích mà công cụ đem lại để thiết kế ra các cây hành vi một cách hiệu quả nhất (optimal).

• Và cuối cùng, nếu đã thành công thực hiện các hướng phát triển trên, thì em có thể thiết kế thêm nhiều màn chơi có địa hình cao thấp khác nhau cũng như các nhân vật mới để có thể kiểm chứng tính hiệu quả của các mô hình mới so với các mô hình cũ.

[1] Bevilacqua, F (2013).Finite-State Machines: Theory and Implementation Truy cập từ: https://gamedevelopment.tutsplus.com/tutorials/finite-state-machines-theory-and- implementation gamedev-11867, lần truy cập cuối: 7/12/2020.

[2] Bonagiri, S (2018).Paper Review: Reciprocal Velocity Obstacles for Real-Time Multi-Agent Navigation.

Truy cập từ:https://medium.com/@suraj2596/paper-review-reciprocal-velocity-obstacles- for-real-time-multi-agent-navigation-aaf6adbedefd, lần truy cập cuối: 23/12/2020.

[3] Buttice, C (2019),Finite State Machine: How It Has Affected Your Gaming For Over 40 Years.Truy cập từ:https://www.techopedia.com/finite-state-machine-how-it-has-affected-your-gaming- for-over-40-years/2/33996, lần truy cập cuối: 14/12/2020.

[4] Chaudhari, K (2018).AI for Unity game developers: How to emulate real-world senses in your NPC agent behavior Truy cập từ: https://hub.packtpub.com/ai-unity-game-developers-emulate-real-world-senses/, lần truy cập cuối: 3/12/2020.

[5] Cowan, B (2020).A Graph-Based Real-Time Spatial Sound Framework(Doctoral thesis, Ontario Tech University)

[6] Davis, R J., & Stephens, S D G (1974) The effect of intensity on the localization of different acoustical stimuli in the vertical plane.Journal of Sound and Vibration, 35(2), trang 223-229.

[7] Doelle, L L (1972).Environmental acoustics McGraw-Hill.

[8] Estrada, M (2014).Finite State Machine vs Behaviour Tree, A True Story Truy cập từ: https://coffeebraingames.wordpress.com/2014/02/23/finite-state-machine-vs- behaviour-tree-a-true-story/, lần truy cập cuối: 8/12/2020.

[9] Fmod (2019).Audio API Documentation Truy cập từ:https://www.fmod.com/resources/ documentationapi?version=1.10&page=content/generated/overview/3dsound.html, lần truy cập cuối: 13/12/2020.

[10] gamedev, (2018).Navigation Meshes and Pathfinding Truy cập từ: https://www.gamedev.net/tutorials/programming/artificial-intelligence/navigation- meshes-and-pathfinding-r4880/, lần truy cập cuối: 20/7/2021.

[11] gamepressure, (n.d).Controls in Desperados 3 Truy cập từ: https://guides.gamepressure.com/desperados-iii/guide.asp?IDS338, lần truy cập cuối: 20/12/2020.

[12] Garner, T & Jordanous, A (2016),Emergence perception and video games that listen: Applying sonic virtuality for creative and intelligent virtual agent behaviours Trong workshop "Computational Creativity and Games" lần thứ 2, 27 tháng 6 năm 2016, Paris, Pháp

[13] Giguere, C., Abel, S.M (1993) Sound localization: effects of reverberation time, speaker array, stimulus frequency, and stimulus rise/decay.Journal of the Acoustical Society of America, 94 (2) , trang 769-776.

[14] Grimshaw, M & Garner, T (2015),Sonic virtuality: Sound as emergent perception Oxford University Press

[15] Guay, J F (2012) Real-time sound propagation in video games.Game Developers Conference(GDC), GDC Vault trang 5-9.

[16] Khatib, Y., (2014).Examining the Essential Building Blocks of Stealth Play Truy cập từ: https://www.gamasutra.com/blogs/YoussefKhatib/20140619/218797/Examining_the_

Essential_Building_Blocks_of_Stealth_Play.php, lần truy cập cuối: 24/12/2020.

[17] MacPherson, E A., & Middlebrooks, J C (2000) Localization of brief sounds: effects of level and background noise.The Journal of the Acoustical Society of America, 108(4), trang 1834-1849.

[18] Makous, J C., & Middlebrooks, J C (1990) Two-dimensional sound localization by human listeners.The Journal of the Acoustical Society of America, 87(5), trang 2188-2200.

[19] McIntosh, T., 2014.The Last of Us: Human Enemy AI Truy cập từ: https://www.gdcvault.com/play/1020338/The-Last-of-Us-Human, lần truy cập cuối: 24/12/2020.

[20] McIntosh, T., 2015 Human Enemy AI in The Last of Us.Game AI Pro 2: Collected Wisdom of Game AI Professionals Natick: A K Peters/CRC Press, trang 419-429.

[21] Middlebrooks, J C., & Green, D M (1991) Sound localization by human listeners.Annual review of psychology, 42(1), trang 135-159.

[22] Millington, I & Funge, J (2016).Artificial intelligence for games CRC Press.

[23] Mount, D & Eastman, R (2018).Motion Planning: Basic Concepts Truy cập từ: https://www.cs.umd.edu/class/spring2018/cmsc425/Lects/lect16-motion-basics.pdf, lần truy cập cuối: 20/12/2020.

[24] Opsive, (n.d).Behavior Designer Truy cập từ: https://opsive.com/support/documentation/behavior-designer/overview/, lần truy cập cuối: 20/12/2020.

[25] Parfit, D (2005).Interactive Sound, Environment, and Music Design for a 3D Immersive Video Game

(Doctoral dissertation, New York University).

[26] Plack, C J (2018).The Sense of Hearing (3rd edition), Routledge, London, UK.

[27] Pinterest (n.d).Diffraction of a sound wave Truy cập từ: https://www.pinterest.co.uk/pin/412642384579278979/, lần truy cập cuối: 23/12/2020.

[28] Rabin, S & Delp, M., (2008) Designing a Realistic and Unified Agent-Sensing Model.Game Programming Gems 7 Clifton Park: Delmar, trang 217-228.

[29] Rayleigh, L (1907) On our perception of sound direction.The London, Edinburgh, and Dublin

Philosophical Magazine and Journal of Science), 13(74), trang 214-232.

[30] Savioja, L., & Svensson, U P (2015) Overview of geometrical room acoustic modeling techniques.The

Journal of the Acoustical Society of America, 138(2), trang 708-730

[31] Simpson, C (2014).Behavior trees for AI: How they work.Truy cập từ:https://www.gamasutra.com/ blogs/ChrisSimpson/20140717/221339/Behavio_trees_for_AI_How_they_work.php, lần truy cập cuối: 14/12/2020.

[32] Sutton, G J & Robinson, D W (1979) Age effect in hearing - a comparative analysis of published threshold data.Audiology, 18, trang 320-334.

[33] Thomas, K (2017),Implementing Artificial Intelligence Perception and Decisions in a Stealth Game Truy xuất từ:http://www.kyle-thomas.com/files/Dissertation.pdf, lần truy cập cuối 15/12/2020.

Ngày đăng: 31/07/2024, 10:17

TÀI LIỆU CÙNG NGƯỜI DÙNG

  • Đang cập nhật ...

TÀI LIỆU LIÊN QUAN

w