确定A *探路者中无法通过的磁贴

时间:2018-02-17 20:27:56

标签: c# unity3d

我正在尝试在Tilemap的2D场景中实现A *寻路算法。为了做到这一点,我需要计算网格中的哪些图块是可以通过的。我的TilemapCollider2D上的图层上附有TilemapTilemap,但是我很难将碰撞器边界与每个节点的边界(没有双关语)对齐。

我的TilemapCollider2D.OverlapPoint()中的每个图块被细分为A *算法的4个节点,以便提供更精细的移动粒度。我需要能够获取每个路径查找器节点的边界并确定它是否包含碰撞区域。我的第一个想法是使用Rect来检查每个节点的左上角,右上角,左下角和右下角,以查看这些点中是否有任何点与对撞机重叠,但后来我意识到问题是如果对手位于节点中间而没有重叠角落,那就不会起作用。

我的下一个想法是从每个节点的边界创建一个Sprite.GetPhysicsShape(),然后从每个对手的点(从int xMin = tilemap.cellBounds.x; int xMax = xMin + tilemap.size.x - 1; int yMin = tilemap.cellBounds.y; int yMax = yMin + tilemap.size.y - 1; for (int x = xMin; x <= xMax; x++) { for (int y = yMin; y <= yMax; y++) { // Create four A* nodes for this tile Rect node1 = new Rect(x, y, 0.5f, 0.5f); Rect node2 = new Rect(x + 0.5f, y, 0.5f, 0.5f); Rect node3 = new Rect(x, y + 0.5f, 0.5f, 0.5f); Rect node4 = new Rect(x + 0.5f, y + 0.5f, 0.5f, 0.5f); var sprite = tilemap.GetSprite(new Vector3Int(x, y, 0)); if (sprite != null) { // Get the points that define this sprite's collider shape List<Vector2> points = new List<Vector2>(); sprite.GetPhysicsShape(0, points); // This is where I would like to create a polygon from the // collider's points and see if that polygon overlaps any // of my four A* nodes, but I don't know how to do that } } } 获得)创建一个多边形,然后看看是否矩形和多边形重叠,但我不确定如何创建这样的多边形并测试Unity中的重叠。

这是我尝试做的基本概要:

class ThreadManager{
public:
    std::vector<std::thread> threads;
    std::vector<bool> threadCompletes;

    std::mutex sendMtx, recvMtx, boolLock;
    std::condition_variable sendCv;

    static std::string printBool(std::vector<bool>& bools){
        std::string xx;
        for(int i=0; i<bools.size(); i++){
            if(bools[i]) xx += "1"; else xx+="0";
        }
        return xx;
    }

    static void thread_worker(int id, ThreadManager* manager){

        while(1){
            std::unique_lock<std::mutex> lck(manager->sendMtx);
            //cout << "Thread Wait: " << id << endl;
            manager->sendCv.wait(lck);
            lck.unlock();
            // DO WORK
            //std::this_thread::sleep_for(std::chrono::milliseconds(10));
            manager->boolLock.lock();
            cout << "Start ParOp..: " << id << endl;
            manager->boolLock.unlock();

            std::this_thread::sleep_for(std::chrono::milliseconds(10));

            manager->boolLock.lock();
            manager->threadCompletes[id] = true;
            bool done = (std::find(std::begin(manager->threadCompletes), std::end(manager->threadCompletes), false) == std::end(manager->threadCompletes));
            cout << "Job Complete: " << id << " " << printBool(manager->threadCompletes) << endl;
            manager->boolLock.unlock();
            if(done){
                cout << "All Done" << endl;
                manager->recvMtx.unlock();
            }
        }
    }

    ThreadManager(){

    }

    void addThread(){
        threadCompletes.push_back(false);
        threads.push_back(std::thread(ThreadManager::thread_worker, threads.size(), this));
    }

    void signal(){
        boolLock.lock();
        for(auto i : threadCompletes) i = 0;
        boolLock.unlock();
        recvMtx.lock();
        std::unique_lock<std::mutex> sendLck(sendMtx);
        sendCv.notify_all();
        sendLck.unlock();
    }

    void wait(){
        recvMtx.lock();
        recvMtx.unlock();
    }

    void join(){
        for (int i = 0; i < threads.size(); ++i) {
            threads[i].join();
        }
    }
};


void test2(){

    ThreadManager manager;
    for(int i=0; i<8; i++){
        manager.addThread();
    }

    std::this_thread::sleep_for(std::chrono::milliseconds(1000));

    for(int i=0; i<500; i++){
        manager.signal();
        manager.wait();
        cout << "\nComplete: " << i << endl;
    }

    cout << "ALL DONE" << endl;

    manager.join();

}

我如何实施此解决方案,还是有比我正在做的更好的方式?

1 个答案:

答案 0 :(得分:0)

  

我正在尝试使用Tilemap在2D场景中实现A *寻路算法。为了做到这一点,我需要计算网格中的哪些图块是可以通过的。我有一个TilemapCollider2D附加到我的Tilemap上有墙的图层,但我正在努力将对撞机边界与每个节点的边界网格化(没有双关语意)。

您可以使用tile脚本中的布尔值将自己的tile标记为无法通过。然后在碰撞时抓取该脚本(使用GetComponent())并检查它是否可以通过。

如果它不能与TilemapCollider2D一起使用,它将适用于BoxCollider2D。