伺服器使用recast navigation

來源:互聯網
上載者:User

標籤:

  在3D MMO或者其他類型的遊戲中,通常需要進行尋路處理,地圖針對尋路有多種方案,比如劃分格子,凸多邊形等,本篇介紹一種比較常用的navigation mesh的方式來進行尋路。不過整套navmesh的演算法比較複雜,沒有深入的研究寫不出來,我們使用網上開源的解決方案,google的recast方案。我們使用的開發環境是win7 + vs2013.

  一、伺服器端recast的安裝和使用

  1、先從github上面下載recast的原始碼

  2. 原始碼下載下來之後,需要我們自己進行編譯,recast使用先行編譯工具premake,需要premake.lua。先下載lua,然後單獨下載premake5,否則premake5.lua不能使用。將下載好的premake.exe放到和premake5.lua的同一目錄下,然後在控制台運行premake.exe vs2013(根據自己的IDE版本號碼),就會產生vs2013的解決方案sln檔案。

  2. recast的測試程式中,用到了SDL的相關庫,這個比較簡單,下載一個SDL-devel的庫就可以了,然後看下RecastDemo裡面的配置目錄,copy進去就可以編譯通過了。中間編譯的時候,可能由於vs2013版本,會提示min,max這些函數沒有定義,只要#include對應的STL庫標頭檔<algorithm>就可以了

  3. 成功編譯了recast相關的庫,Detour,Recast等,我們一開始對於如何使用recast可能一點概念都沒有,不過recast已經考慮到了這一點,工程中有一個RecastDemo程式,是用來樣本如何使用recast的。

  4. 使用recastDemo,我們可以根據情境的.obj檔案,來產生navmesh,和匯入我們自己產生的navmesh,不過這都是我們通過recast開源工具產生的。實際的遊戲中,我們需要的是從用戶端產生的navmesh,然後匯入到伺服器中進行解析。

 

  二、Unity3D用戶端的navmesh產生

  unity3D是內建navmesh agent的,可以自己產生navmesh,並且匯出navmesh,不過它的匯出navmesh,我查下來是需要自己寫代碼的,而且navmesh agent是修改過匯出navmesh檔案格式的,也就是說我們recast C++代碼是不能直接使用的。後來我又搜尋了一下recast for Unity這個外掛程式,這個外掛程式是有原始碼的,不過如果正常購買需要$50。

  對於這個外掛程式當時研究了比較長的時間,一開始匯出了一下它的navmesh格式,然後用C++recast匯入試了一下,發現格式肯定是不一樣的了。然後就仔細研究了一下兩邊產生navmesh時的格式差異,針對TileMesh儲存的時候,兩邊是不一致的,本來想直接修改C#代碼來達到兩邊一致,不過由於對C#的序列化不夠熟悉,就放棄了。不過應該可以直接改成一致,這個後面有時間可以再深入研究一下。

  後來使用了KBEngine修改過的CritterAI,它匯出來的navmesh檔案,在KBEngine中是能直接使用的。然後把我們伺服器中解析navmesh的格式,改成和KBEngine一致就可以了。代碼還是非常簡單的,代碼如下:

    bool NavMeshLoader::load_cai(const char* path) {        FILE* fp = fopen(path, "rb");        if (!fp) return false;        // Read header.        NavMeshSetHeader_CAI header;        size_t readLen = fread(&header, sizeof(NavMeshSetHeader_CAI), 1, fp);        if (readLen != 1)        {            fclose(fp);            return false;        }        if (header.version != NAVMESHSET_VERSION)        {            fclose(fp);            return false;        }        dtNavMesh* mesh = dtAllocNavMesh();        if (!mesh)        {            fclose(fp);            return false;        }        dtStatus status = mesh->init(&header.params);        if (dtStatusFailed(status))        {            fclose(fp);            return false;        }        // Read tiles.        for (int i = 0; i < header.tileCount; ++i)        {            NavMeshTileHeader tileHeader;            readLen = fread(&tileHeader, sizeof(tileHeader), 1, fp);            if (readLen != 1)            {                fclose(fp);                return false;            }            if (!tileHeader.tileRef || !tileHeader.dataSize)                break;            unsigned char* data = (unsigned char*)dtAlloc(tileHeader.dataSize, DT_ALLOC_PERM);            if (!data) break;            memset(data, 0, tileHeader.dataSize);            readLen = fread(data, tileHeader.dataSize, 1, fp);            if (readLen != 1)            {                fclose(fp);                return false;            }            mesh->addTile(data, tileHeader.dataSize, DT_TILE_FREE_DATA, tileHeader.tileRef, 0);        }        fclose(fp);        m_navMesh = mesh;        m_navQuery = dtAllocNavMeshQuery();        status = m_navQuery->init(m_navMesh, 2048);        if (dtStatusFailed(status))        {            return false;        }        return true;    }

  KBEngine中和RecastDemo中解析navmesh主要就是NavMeshSetHeader頭結構不一致,其他的都一樣,所以還是比較簡單的。

  能正常解析navmesh檔案之後,就是對地圖進行尋路了,在這裡主要使用了RecastDemo中尋路的代碼,進行了本地化的修改。

  

  三、 使用recast navigation遇到的問題

  1、其中有段時間,我對於用戶端產生的navmesh,和伺服器產生的navmesh在座標繫上不一致,感覺很困惑,甚至想要不要自己用3DMax之類的工具重新匯入地圖模型,然後修改座標系,這現在看來很可笑,主要還是對於navmesh的產生原理不是很懂。其實用戶端產生的navmesh是帶有自身座標系和相對座標的。之前之所以有那種困惑,是因為伺服器用的是recastDemo中產生的navmesh,用戶端產生了自己的,根本就是兩種世界,兩種座標,當然不一致了!!

  2、其實CritterAI的底層是C++寫的dll,通過unity匯入進工程,然後產生navmesh的,只要符合unity使用dll的規則,我們其實也可以使用recast的源碼,然後改成unity能夠使用的dll來匯出navmesh。這個後面可以試試

伺服器使用recast navigation

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.