Làm thế nào để làm cho nhân vật của tôi trở nên mượt mà khi đi trên một con đường (danh sách tọa độ)?


15

Tôi có một danh sách với tọa độ - đầu ra từ thuật toán A * - và tôi muốn làm cho các nhân vật của mình thuận lợi đi theo con đường này bằng các phép quay.

Vì vậy, tôi có một cái gì đó như A và tôi muốn có được C

nhập mô tả hình ảnh ở đây

Tôi có thể làm cái này như thế nào ?

BIÊN TẬP

Để làm cho bản thân rõ ràng hơn một chút:

Tôi quan tâm nhiều hơn đến việc chuyển trơn tru vì tôi đã biết cách đi từ nút này sang nút khác.

BIÊN TẬP

Vì nhiều người thấy điều này hữu ích (tôi cũng vậy) Tôi đang đăng liên kết tới "Bản chất của mã" của Daniel Shiffman, nơi anh ấy thảo luận về rất nhiều vấn đề về AI (và vật lý) trong trò chơi, ví dụ như hành vi lái http://natureofcode.com/book/ch CHƯƠNG- 6-đại lý tự trị / # chương06_section8


Không phải là tìm đường tích hợp trong Unity sao?
joltmode

@Tom Vâng, nhưng tôi đã thực hiện phiên bản của mình. Điểm của câu hỏi này là để có được những bước ngoặt (quay) mượt mà trong khi đi trên con đường.
Patryk

3
Một thuật ngữ hay cho Google về vấn đề này là 'Hành vi chỉ đạo' :)
Roy T.

3
@RoyT. Tất nhiên ! Tôi đã đọc điều này vài tuần trước và đã quên: / Đây là một bài viết tuyệt vời về con đường tiếp theo với toán học tuyệt vời + giải thích vật lý Natureofcode.com
Patryk

1
Tôi chỉ muốn cảm ơn @Patryk vì liên kết - có vẻ rất nhiều thông tin và tôi đã tìm kiếm một nguồn tài nguyên tốt về hành vi lái.
Christian

Câu trả lời:


7

Nếu bạn muốn các đường dẫn trơn tru trong môi trường dựa trên ô xếp, không có cách nào để áp dụng một số làm mịn đường dẫn trên các điểm tham chiếu A * của bạn. Trong cuốn sách về trò chơi lập trình AI của mình, Matt Buckland đã mô tả một thuật toán đơn giản và nhanh chóng để làm phẳng một đường dẫn (về cơ bản loại bỏ tất cả các cạnh có thể được loại bỏ mà không gây ra giao cắt với chướng ngại vật của bạn).

Khi bạn đã loại bỏ các cạnh không cần thiết như thế này, trường hợp đầu tiên của bạn ( A -> B ) sẽ được giải quyết. Làm mịn các cạnh trong biểu đồ của bạn có thể được thực hiện theo nhiều cách. Nhiều khả năng, các spline Hermite sẽ hoạt động (phụ thuộc một chút vào mật độ chướng ngại vật và kích thước gạch của bạn). Một lựa chọn khác có thể là các hành vi lái, trong đó bạn bắt đầu lái về điểm tiếp theo, ngay khi bạn cách nửa mục tiêu so với mục tiêu hiện tại (điều này thực sự phụ thuộc vào tốc độ di chuyển / quay của "tác nhân" của bạn).


9

Như những người khác đã đề cập, trong trường hợp thứ hai, bạn sẽ cần phải thực hiện một số loại spline hoặc (thực sự phù hợp hơn với ví dụ của bạn) cung cấp cho đơn vị một số loại hành vi lái.

Tuy nhiên, đối với trường hợp đầu tiên, có một giải pháp vừa đơn giản hơn vừa cho kết quả tốt hơn so với làm mịn đường dẫn. Nó được gọi là Theta * , và là một phần mở rộng đơn giản (và tương đối mới) của A * trên các lưới cho phép các đơn vị di chuyển theo bất kỳ hướng nào giữa các điểm lưới.

Theta * so với làm mịn đường dẫn

Có một bài viết rất hay giải thích về Theta * (từ đó tôi đã đánh cắp hình ảnh trên) ở đây


2

Để một phong trào thực tế hơn của con người, hãy thử tích hợp với Hành vi chỉ đạo. (Phiên bản C # của OpenSteer cổ điển http://sharpsteer.codeplex.com/ ) Bạn nhận được đầu ra của AStar và để hành vi lái quan tâm đến chuyển động (Một trong các mẫu hiển thị chính xác cách thực hiện việc này, điều hướng theo một đường dẫn)


1

Trong trường hợp điều hướng từ điểm này sang điểm khác, tôi đã sử dụng sự khác biệt về góc (hướng người chơi hiện tại so với hướng từ điểm hiện tại sang điểm tiếp theo) và sau đó dần dần thay đổi góc tới góc cuối cùng khi chuyển động xảy ra. Kiểm tra trò chơi này ở đây nơi máy bay di chuyển từ 1 điểm này sang điểm khác nhưng lần lượt không đột ngột nhưng khi quan sát cẩn thận người ta có thể xác định các điểm của đường dẫn. (trò chơi chỉ hoạt động trên thiết bị di động mặc dù tốt nhất là iPhone / iPad).


Đây chính xác là những gì tôi đã làm.
Patryk

1

Tôi đã có may mắn với splines Catmull-Rom (một loại spline hình khối như được đề xuất bởi @bummzack). Điểm hay của những điều đó là spline sẽ luôn đi qua các điểm kiểm soát, nhiều điểm khác thì không. Thực hiện một cái gì đó như thế này:

t    = <time*>
t12  = t + 1.0
t23  = t
t34  = t - 1.0
t123 = (t + 1.0) / 2.0
t234 = t / 2

c1 = controlpoint[0];
c2 = controlpoint[1];
c3 = controlpoint[2];
c4 = controlpoint[3];

l12 = lerp(c1, c2, t12);
l23 = lerp(c2, c3, t23);
l34 = lerp(c3, c4, t34);
position = lerp(lerp(l12, l23, t123), lerp(l23, l34, t234), t);

* thời gian là một giá trị [0,1] giữa các điểm kiểm soát 1 và 2.


0

A-> B có thể được giải quyết bằng cách sử dụng các lưới điều hướng thay vì lưới. Điều này ngụ ý một sự thay đổi lớn trong việc tạo dữ liệu tìm đường.

Các trường hợp như C và D chỉ là cắt góc: nếu nhân vật đang di chuyển trong một đường dẫn và bên trong một "góc" (ô trong đó các ô trước, hiện tại, tiếp theo không nằm trên một đường thẳng), hãy đẩy nó theo hướng của cả ô trước và ô tiếp theo . Vấn đề duy nhất là xác định khoảng cách từ vị trí thực (khoảng cách đẩy). Điều đó có thể sẽ yêu cầu khoảng cách từ ô hiện tại làm đầu vào. Một cái gì đó như thế này:

push_dir = average( prevcell.pos, nextcell.pos ) - curcell.pos;
push_dist = cell_half_width - distance( char.pos, curcell.pos );
char.pos += push_dir * push_dist;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.