Tìm hiểu về Steering Behaviors (Phần 3) - Path Follow, Wander
White

Kaopiz Software Co., Ltd. viết ngày 30/11/2018

Recap

Sau một thời gian đi nhặt bớt dây điện ra khỏi đầu do sự cố ở phần 2. Lần này rút kinh nghiệm để không bị AI gây ảnh hưởng nữa, tại phần này em sẽ viết về 2 steering behaviors khá là đơn giản là Path Follow (Đi theo lối định sẵn) và Wander (Lang thang). Do 2 hành vi này khá là đơn giản nên chắc là sẽ không bị nhiễm như lần trước nữa

Path Follow

Path Follow là hành vi mà gần như AI nào trong những game hành động giải đố như Hitman, MGS,... đều sử dụng. Hành vi này tạo cho những nhân vật AI đi theo một con đường được đưa ra sẵn. Và chúng chỉ đi theo con đường đó.
Thực chất Path Follow là hành vi mà ta sẽ khiến AI sử dụng hành vi Seek đi tới một chuỗi các điểm đã được định sẵn.
Đầu tiên chúng ta cần định nghĩa cho AI một con đường mà ta muốn chúng đi theo. Để làm điều này có khá là nhiều cách, ở đây sử dụng một mảng GameObject để dễ dàng thiết lập trên Editor của Unity. Bên cạnh đó cũng cần thêm index của điểm mà AI cần đi tới và một tham số nhỏ cho việc đến gần điểm cần tới bao nhiêu thì đổi điểm. Tóm lại ta cần:
int targetIndex;
public GameObject[] pathPoint;
public float changeDirectionRadius;

Như này cũng đã đủ rồi. Việc tiếp theo tạo một hàm followPath với giá trị trả ra là một vector. tương tự như ở các hành vi trước vector này chính là hướng di chuyển mà AI cần đi tới.
Vector2 followPath(GameObject[] path)
{
Vector3 target = Vector3.zero;
if (path != null)
{
target = path[targetIndex].transform.position;
if ((transform.position - target).magnitude < changeDirectionRadius)
{
targetIndex++;
if (targetIndex >= path.Length)
{
targetIndex = path.Length - 1;
}
}
}
return target != Vector3.zero ? seek(target) : new Vector2();
}

Giải thích: Tại hàm này ta truyền tham số là một mảng các game object, và việc của hàm này là tính toán để đưa ra game object mà AI cần hướng tới. Tức là khi mà khoảng cách giữa AI và đích tới nhỏ hơn khoảng cách đổi điểm đã được định sẵn thì chỉ mục hiện tại được tăng thêm 1 tức là sẽ sang điểm tiếp theo. Khi đã có điểm rồi thì đơn giảm là đi Seek hoặc Arrival tới điểm đó thôi (Nếu như sử dụng Arrival thì có lẽ tham số changeDirectionRadius sẽ không cần sử dụng đến nữa :9).

Khi ta đưa công Vector Wander và trong steeringForce hiện tại thì ta sẽ có hành vi như sau:alt text
Hành vi này sử dụng seek với changeDirectionRadius là 0.3. Như ta có thể thấy khi AI đến điểm cuối cùng thì nó cứ chỉ quanh quẩn và vẫy đuôi ở đó do đã hết mục đích rồi :(. Khá là đáng buồn cho chú AI bé nhỏ này phải không. Thay vì chỉ quanh quẩn ở đấy sao không làm hành vi này nó toẹt vời hơn bằng cách cho AI đi lại con đường đã. Giống như hành vi Patrol trong đế chế :D.
Ta thêm một tham số public bool là isPatroller để có thể toggle điều này ở trên Editor cùng với thêm vào một tham số int là dir ( tượng chưng cho direction của AI: 1 là đi tới, -1 và hướng về).
hàm pathFollow sẽ nhìn như sau:
Vector2 followPath(GameObject[] path)
{
Vector3 target = Vector3.zero;
if (path != null)
{
target = path[targetIndex].transform.position;
if ((transform.position - target).magnitude < changeDirectionRadius)
{
targetIndex += dir;
if (!isPatroller) {
if (targetIndex >= path.Length)
{
targetIndex = path.Length - 1;
}
}
else {
if (targetIndex >= path.Length || targetIndex < 0)
{
dir *= -1;
targetIndex += dir;
}
}
}
}
return target != Vector3.zero ? seek(target) : new Vector2();
}

Nếu như AI là một Patroller thì khi đi tới cuối hoặc đầu con đường tham số dir sẽ đổi dấu và AI sẽ đi tới lui như là đi tuần vậy:alt text
Và như vậy ta có một tuần tra viên \ :v /

Wander

Từ trước tới giờ mỗi một hành vi ta đều truyền vào tham số là đích đến của AI. Vậy thì giả dụ như AI không còn mục tiêu nữa thì sao? Nếu như nó lạc và một thế giới khác so với thế giới có đích tới của nó thì sao? Một đứa trẻ lạc sẽ làm gì nếu như không có người lớn? Phần lớn là ngồi im một chỗ(Quanh quẩn tại một điểm) hoặc tìm tới chỗ người lớn(Tự tìm một mục tiêu khác) nhưng mà em không thích như thế, khi mà rời xa bàn tay người lớn tức là bắt đầu một cuộc phượt không đích đến nho nhỏ của trẻ còn và cái này gọi là "Lang thang".
Để thiết lập hành vi này có rất là nhiều cách ví dụ chuyển đổi hướng đi sau một khoảng thời gian ngẫu nhiên, đặt đích đến một cách ngẫu nhiên trên bản đồ sau một khoảng thời gian,... Có khá là nhiều, tuy nhiên sẽ có những cách khiến cho AI quay đầu 180 độ và điều này nhìn không tự nhiên gì cả. Nó giống như kiểu "S*#t, quên mịa điện thoại ở nhà rồi" nhưng mà AI cần có hành vi là "Welp, đi hướng này thử xem".
Với lý do như vậy em đã tìm ra một phương pháp như sau:alt text
Nhìn dễ hiểu phải không? Vì em không biết phải giái thích cái này như nào :(
Về cơ bản tạo ra một vòng tròn (2D) hoặc hình cầu (3D) nằm ở ngay trước mặt AI. Và tâm của vòng tròn chính là độ lớn của Vector vận tốc hiện tại. Sau đó tìm ra displacement Vector nằm ở trong vòng tròn đó và thêm nó vào Vector vận tốc hiện tại. Bằng cách này gần như AI sẽ luôn đi tới như không thể quay đầu 180 độ nữa.
alt text
Wander force chính là Vector vận tốc mới mà AI sẽ sử dụng để di chuyển.
xây dựng hàm Wander như sau:

private Vector2 wander()
{
Vector2 circleCenter = velocity.normalized;
Vector2 randomPoint = Random.insideUnitCircle *.5f;
Vector2 displacement = new Vector2(randomPoint.x, randomPoint.y) * CircleRadius;
displacement = Quaternion.LookRotation(velocity) * displacement;
Vector2 wanderForce = circleCenter + displacement;
return wanderForce;
}

Đầu tiên là tìm circleCenter bằng với độ lớn của vector vận tốc hiện tại. Sau đó tìm một điểm nằm ngẫu nhiên xung quanh AI (randomPoint) hàm Random.insideUnitCircle sẽ thực hiện điều này với bán kính là 0.5 xung quanh AI. Sau đó đối chiếu điểm đó so với bán kính của vòng tròn trước mặt (Circle Radius). cuối cùng cộng với vector circleCenter để có được vector lang thang mong muốn.
Thêm Vector này vào trong steeringForce ta sẽ có như sau:alt text
Gif hơi lag do có hơi nhiều AI trong đó. Dù sao thì nhìn cá bơi thì phải nhiều chứ nhìn 1 2 con thì chán lắm

Kết luận

Và như vậy ta đã có thêm 2 hành vi mới. Các hành vi này sẽ rất là tuyệt với khi kết hợp với những thuật toán khác. Đặc là khi kết hợp Path Follow với cả giải thuật Path Finding. Ở phần sau sẽ là những hành vi khác, là hành vi gì hồi sau sẽ rõ :9.

Nguồn

Tương tự phần 1, 2.


Bài viết này được trích dẫn từ blog nội bộ công ty KAOPIZ - カオピーズ
Bài gốc: http://kipalog.kaopiz.com/posts/jQ8GpkFLkespWmoWMb2Eaw

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Kaopiz Software Co., Ltd.

27 bài viết.
23 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
50 2
Bài viết này được trích dẫn từ blog nội bộ công ty (Link) (Link) Bài gốc: https://kipalog.kaopiz.com/posts/RegexHocroimanhuchuahoc (Ảnh) 1. Tự...
Kaopiz Software Co., Ltd. viết 8 tháng trước
50 2
White
5 0
Mở Đầu Chắc hẳn là dev ai cũng từng nghe qua về Docker và Virtual Machine (VBox hoặc Vmware). Docker giúp cho việc xây dựng và triển khai một môi ...
Kaopiz Software Co., Ltd. viết 8 tháng trước
5 0
White
5 0
Introduction Elasticsearch là một công cụ tìm kiếm dựa trên nền tảng Apache Lucene. Nó cung cấp một bộ máy tìm kiếm dạng phân tán, có đầy đủ công ...
Kaopiz Software Co., Ltd. viết 8 tháng trước
5 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
27 bài viết.
23 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!