Trong RecastNavulation, làm cách nào tôi có thể làm cho một tác nhân nhàn rỗi sau khi đến đích?


8

Câu hỏi này đặc biệt về việc xử lý thư viện Recast Navigation.

Tôi đã thêm một đại lý với addAgentvà đặt mục tiêu của nó với requestMoveTarget. Khi tác nhân đến đích, nó dừng lại, nhưng khi bị đẩy ra khỏi đường (bởi một tác nhân khác), nó sẽ cố gắng quay trở lại mục tiêu. Thay vào đó, muốn nó dừng lại và trở nên nhàn rỗi, để khi các tác nhân khác đi bằng cách đẩy nó sang một bên và nó sẽ không quay trở lại.

Tôi đã cố gắng kêu gọi resetMoveTargettrên agent.nposlà gần agent.targetPos(như nếu đại lý đã đạt được đích của nó), nhưng điều đó dường như phá vỡ logic bên trong của mô phỏng đám đông - đại lý sẽ chỉ tiếp tục đi theo hướng cũ, không bao giờ dừng lại.

Làm thế nào để tôi nói đúng một tác nhân dừng lại và trở nên nhàn rỗi (chưa thể đẩy được) trong RecastNavulation?

Câu trả lời:


2

Một sửa chữa đã được thực hiện ngược dòng liên quan đến giải pháp của bạn đặt lại vận tốc mong muốn trong resetMoveTarget.

bool dtCrowd::resetMoveTarget(const int idx)
 {
    if (idx < 0 || idx >= m_maxAgents)
        return false;

    dtCrowdAgent* ag = &m_agents[idx];

    // Initialize request.
    ag->targetRef = 0;
    dtVset(ag->targetPos, 0,0,0);
    dtVset(ag->dvel, 0,0,0); // <<-- This line added
    ag->targetPathqRef = DT_PATHQ_INVALID;
    ag->targetReplan = false;
    ag->targetState = DT_CROWDAGENT_TARGET_NONE;

    return true;
 }

Theo như tôi có thể nhớ đây là câu trả lời không đầy đủ. Tôi bối rối. Đây là một câu trả lời hoặc một nhận xét cho câu trả lời của tôi dưới đây? Bởi vì bạn cũng cần thiết lập lại hành lang đại lý, để các tác nhân trở nên thực sự nhàn rỗi (có thể đẩy được).
Kromster

OK tôi đã quên vấn đề của bạn với đại lý trở nên không thể tin được. Tôi sẽ cố gắng tái sản xuất.
Leif Gruenwoldt

@KromStern Hmm Tôi gặp khó khăn khi sao chép này. Nếu không có cooridor, các tác nhân của tôi có thể bị đẩy bởi các tác nhân khác. Có cần thiết không?
Leif Gruenwoldt

Tôi đã thử thêm nó vào resetMoveTargetđịa phương nhưng tôi không quan sát thấy sự khác biệt. ag->corridor.reset(ag->corridor.getFirstPoly(), agent->npos);
Leif Gruenwoldt

1
Vì một số lý do kỳ lạ, tôi cũng không thể tái tạo nó. Có vẻ như một cái gì đó đã thay đổi kể từ đó. Dù sao, cảm ơn sự tham gia của bạn! :)
Kromster

0

Tôi không chắc nhưng dự đoán của tôi sẽ gọi "requestMoveVelocity" với vectơ không cũng trên tác nhân đó. Hãy thử một lần.


0

Lưu ý: Giải pháp này có vẻ không cần thiết, nhưng tôi sẽ để nó trong trường hợp vấn đề xuất hiện lại.

Sau rất nhiều lần giải mã, dùng thử và lỗi, tôi đã lấy dtCrowd.resetMoveTargetlàm cơ sở và tìm ra cách sửa đổi nó:

procedure TKMTerrainNavigation.AgentTargetClear(aIdx: Integer);
var
  ag: PdtCrowdAgent;
begin
  ag := fRecastCrowd.getAgent(aIdx);

  ag.targetRef := 0;
  dtVset(@ag.targetPos[0], 0, 0, 0);
  ag.targetPathqRef := DT_PATHQ_INVALID;
  ag.targetReplan := False;
  ag.targetState := DT_CROWDAGENT_TARGET_NONE;

  // Reset desired velocity
  dtVset(@ag.dvel[0], 0, 0, 0); 

  // Reset agents corridor so that agent won't try to walk back to his last corner
  ag.ncorners := 0;
end;

Mã PS ở trên là Delphi, nhưng nó cũng hoạt động tốt như trong C ++.

Recast Navigation tác giả nhận xét:

Thay vì đặt lại các góc, bạn nên đặt lại hành lang về vị trí hiện tại và đa giác đầu tiên.

Đặt vị trí mục tiêu cho vị trí hiện tại của đại lý thường được ưu tiên hơn là đặt nó thành 0,0,0. Nhưng bạn cũng đang thiết lập lại mọi thứ khác, tôi nghĩ nó vẫn ổn.

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.