Bạn có chắc chắn muốn xóa bài viết này không ?
Bạn có chắc chắn muốn xóa bình luận này không ?
Sau một tháng ngồi quan sát những bài viết đã có ở trên Kipalog. Em quyết định viết một bài nhỏ chia sẻ về một trong những kỹ thuật xây dựng hành vi cho AI mà em sử dụng khá nhiều. Kỹ thuật này rất đơn giản những kết quả nó đem lại là vô cùng ảo diệu. Đó là kỹ thuật Steering Behaviors kỹ thuật giúp cho những con AI biết tổ lái.
Steering Behaviors được tạo ra để giúp những con AI có hành vi di chuyển giống với thực tế bằng cách sử dụng cách tính toán lực Vector đơn giản. Kỹ thuật này không sử dụng những tính toán phức tạp với các tính toán bằng các biến Global mà làm việc dựa trên Local Information như là vị trí hay vận tốc hiện tại. Điều này khiến Steering Behaviors rất đơn giản để cài đặt nhưng vẫn đem lại sự ảo ma cho những con AI.
Thường thi Steering Behaviors được áp dụng trong việc xây dựng Heat Seeking Missle hay là những con Zombie mà không cần phải cài đặt Path Finding cồng kềnh.
Có thể kết hợp Path Finding với Steering Behavior để tạo ra một thứ còn hơn cả ảo diệu - Unity Navmesh Agent
Em không có giỏi vật lý lắm nên mong là những lời giải thích sau sẽ đem lại cái gì đó chắc thế
Như đã trình bày Steering Behaviors là tính toán dựa trên Vector-Base.
Từng con AI sẽ có cái gọi là vị trí hiện tại và vector vận tốc. Vector vận tốc sẽ bao gồm hướng và con AI sẽ di chuyển và độ nhanh chậm của chúng
Để tiến hành cài đặt cần có những quy tắc sau:
Để đảm bảo không được vượt quá các Parameter tối đa ta sẽ sử dụng hàm ClampMagnitude(value , max_value);
Về cơ bản một con AI được cài đặt Steering Behaviors sẽ gồm:
steeringForce = Vector2.zero;
steeringForce = steeringForce + TheForce
steeringForce = Vector2.ClampMagnitude(steeringForce, max_force);
steeringForce = steeringForce / mass;
velocity = Vector2.ClampMagnitude(velocity + steeringForce, max_speed);
transform.Translate(velocity * Time.deltaTime);
Trong đoạn code trên TheForce là lực được cộng thêm vào với steeringForce. steeringForce ở mỗi lần Update sẽ độ lớn và hướng tác động của lực tác động lên Object để di chuỷen chúng.
TheForce có các loại sau
Seek là hành vi một Object sẽ luôn theo đuổi một Target của nó. Ở trong Unity đã có sẵn một hàm MoveToward, tuy nhiên hàm này khiến cho con AI luôn luôn đuổi theo mục tiêu của nó. Điều này sẽ khiến cho người chơi phải liên tục di chuyển.
Còn Seek? Xem gif sau sẽ rõ :insert dejavu meme:
Nhìn khác bọt hẳn luông. Seek sẽ giúp người chơi có khoảng thời gian nghỉ giữa những lần input di chuyển qua đó có những khoảng nhỏ thời gian cho các công việc phán đoán khác.
Vậy bắt đầu tiến hành cài đặt thôi!
Để xây dựng được hàm Seek()
ta sẽ cần một Vector chỉ hướng giữa mục tiêu và bản thân của Seeker - AI biết Seek ?? :D ??. Để có được đơn giản ta sẽ tìm khoảng cách tương đối giữa mục tiêu và Object bằng cách lấy hiệu toạ độ của chúng.
Như vậy hàm Seek()
sẽ như sau:
Seek(target)
{
Vector2 desired_velocity = (target - transform.position).normalized *Seek_Coffiency;
Vector2 seek = desired_velocity - velocity;
return seek;
}
desired_velocity chính là vận tốc mà chúng ta muốn đưa vào Object, vận tốc này sẽ bao gồm hướng và độ lớn cần thiết để thêm vào.
Seek_Coffiency chính là hệ số của Seek.
Sau đó tính toán vận tốc cần có và trừ đi vận tốc hiện tại để có thể đưa ra đúng lực mà ta cần. Sau khi trả ra được lực cần thiết ta thêm lực này vào trong steeringForce tại Update()
:
steeringForce = steeringForce + Seek(Target)
Vào lúc này con AI đã biết tăng tốc, đánh võng, úp vỉa các kiểu để có thể tìm đến mục tiêu của chúng rồi.
Flee là một hành vi là con AI sẽ chạy trốn khỏi Target nào đó, thường thì khi tích hợp hành vi này sẽ bao gồm cả phạm vi phát hiện nguy hiểm (Danger Zone) nhưng để đơn giản trước tiên hãy xây dựng hàm Flee(target)
đã.
Về cơ bản Flee cũng sử dụng khoảng cách tương đối giữa Object và target để đưa ra được lực tác động phù hợp. Nói thì có vể hoa mỹ những thật ra Flee = Seek * -1. Hàm Flee(target)
được xây dựng như sau:
Flee(target)
{
Vector2 desired_velocity = (target - transform.position).normalized *Flee_Coffiency;
Vector2 flee = -desired_velocity - velocity;
return flee;
}
Chú ý vào flee = -desired_velocity - velocity, chắc tại đâu không cần giải thích thêm đâu ha :D.
Tương tự như Seek ta sẽ thêm kết quả vào steeringForce để tạo ra 1 con AI chỉ biết chạy (-_-!).
Một con AI chỉ biết đuổi hay chỉ biết chạy sẽ là một con AI khá là ngu. Tuy nhiên vì kỹ thuật này sử dụng toán Vector là chính nên việc cộng các Vector này để đưa ra một lực tổng hợp rất là dễ. Đơn giản ta sẽ thêm vào steeringForce cả 2 lực:
steeringForce = steeringForce + seek(target) + Flee(target)
.
Object sử dụng cái này sẽ có thể vừa đuổi theo vừa chạy trốn, khá tuyệt phải không? Và chính các hệ số như Seek_Coffiency hay Flee_Coffiency quyết định xem Object sẽ ưu tiên cái gì? Được ăn hay bị ăn?
Tính chất này cũng sẽ được áp dụng cho các loại Steering Behaviors khác sau này. Và tính chất này cũng là tính chất giúp cho AI có được những hành vi di chuyển phức tạp khi được cài đặt những hành vi phù hợp
Ở bài viết sau sẽ là nội dung của Arrival - Khi Seek chưa hay cho lắm. Và Evade - Tránh né đẹp trai :D
https://gamedevelopment.tutsplus.com/series/understanding-steering-behaviors--gamedev-12732