UE4 實時讀取模型數據插件
在Runtime模式下讀取模型數據,以前做家裝時候有出現過這種需求,看現在一些論壇上就是放個視頻給很多人眼饞一下,本身傳承知識的習慣,
在Runtime模式下讀取模型數據,以前做家裝時候有出現過這種需求,看現在一些論壇上就是放個視頻給很多人眼饞一下,本身傳承知識的習慣,博主最近抽空做了個可以實時讀取,也可以點擊讀取的插件,同樣的先說下原理和實現,最后放上插件源碼。
這個插件照樣是使用UE4.19,好了廢話不說了。
插件的實現主要有2個函數,如下所示:
UFUNCTION(BlueprintCallable,Category="MeshLoader")ntstatic FReturnedData LoadMesh(FString filepath,EPathType type= EPathType:: Absolute);nntUFUNCTION(BlueprintCallable, Category = "MeshLoader")ntstatic TArray<FString> GetAllFilesInDirectory(const FString directory, const bool fullPath, const bool withoutExtention, const FString onlyFilesStartingWith, const FString onlyFilesWithExtension);
這兩個一個用來讀取當前模型頂點,一個用來獲取某各路徑下的所有文件。
讀取模型數據,插件使用了assimpSDK,assimp是一個加載模型數據的庫,可以提取模型的定點數據、法線、紋理坐標,assimp的數據會存為一個包,這個包的數據擁有一個比較復雜的數據結構,像Mesh的結構會儲存Vertices、Normals、TextureCoords、Faces等。
存儲的這些數據,都是以數組方式存在,那么問題來了,怎么去還原這個數據,之前我們的另一個插件Metaballs是用ProceduralMesh實現,那么這里同樣是使用ProceduralMesh+CreateMeshSection去還原通過assimp存儲的模型數據。

FindMeshInfo函數,是通過assimp創建的結構數據,assimp存儲會以結構方式進行,最上面是scene,然后就像腦圖一樣,有Mesh,有Material等等。所以這里的mesh、mi是將模型數據,存入vertex、mTransformation、uv,可以看到全都是將對應的aiMesh *mesh中去提取Vector、Normal、UV、Tangent等等數據,這些數據都保存在meshInfo里,也就是FMeshInfo &mi = result.meshInfo[meshidx];中的mi,meshInfo其實是個結構體,他里面包含的數據,就是通過assimp獲取的模型數據。
然后再來說LoadMesh,LoadMesh里其實沒有太多東西,因為數據結構是在FindMeshInfo里已經完成的,所以LoadMesh里一個是查找路徑,一個是將meshInfo添加到當前函數,路徑的話其實UE4有自己的API,叫FPaths,里面有各種Dir,你可以弄成自己想要的Dir,可以是引擎的Engine目錄,也可以是項目的Content目錄,或者工程目錄,具體可以看FPaths里面的方法,FPaths::ProjectContentDir()很好理解就是項目的Content目錄,mScenePtr是用來讀取當前的模型文件,然后FindMesh再去根據上面圖中的索引路徑去查詢每個節點數據。
如果是自定義路徑,可以使用GetBaseFilename方法。
剩下一個函數GetAllFilesInDirectory就是用來獲取目錄下所有文件了,這里文件不限制后綴格式,所以使用這個節點可以獲取任何類型的對象,圖片,xml,反正就是各種數據,你可以自己寫個解析xml的配合這個節點來用,也可以寫個解析XXX的配合GetAllFilesInDirectory來用。
那么這個節點很好理解,首先獲取一個路徑,然后遍歷路徑下的文件,IPlatformFile是UE自帶的API,可以用來對文件對象進行操作,方法包含了文件I/O,讀取當前平臺路徑,獲取當前文件名字,獲取當前文件,獲取當前磁盤上一個文件名字,反正具體去看IPlatformFile這個類好了,這里使用了一個GetExtension用來取指定后綴的文件,屬于FPaths中的方法,具體可以定義到GetExtension索引,剩下的其實就沒有什么了,最后IF里套了一個三元運算符來看GetExtension下的withoutExtention布爾變量是否是自定義路徑還是返回一個文件名。
然后來看UE里的實現,首先是生成Mesh,既然是ProceduralMesh,所以需要一個ProceduralMesh組件,然后LoadMesh的邏輯主要是這樣的,靠的是LoadMesh節點:

這里用的函數,我的思路是這樣的,首先UMG里面用按鈕點一下,通過GetAllFilesInDirectory獲取路徑和文件,然后將路徑文件傳入這個LoadMeshF函數里,點擊函數如下圖所示:

上述方法就是通過GetAllFilesInDirectory函數獲取路徑,這是個String數組,然后遍歷一下獲取所有該路徑下的文件,只查找后綴為FBX的,然后這里有個跨UMG傳輸數據,我以前講的一個文章里有這種實現,ScrollBox是一個下拉滾動條,如下圖所示:

這個就是UI了,方框里的數據,是通過CreateWidget去Add到這個容器里的,創建的另一個UMG是個button,如下圖所示:

這個button的邏輯如下圖所示:

調用LoadMeshF那個Actor藍圖里面的函數,FilePath是在主UMG中,傳入的FilePath路徑,如下圖所示:

然后GetAllFilesInDirectory的path變量填寫你的電腦絕對路徑,最后運行游戲就是如下圖所示:
https://www.zhihu.com/video/1134593970997932032上面視頻是實時讀取,你可以在主UMG中,斷開Tick,把下面的OnClick連接上:

好了,最后附上整個工程,注意了默認運行是沒有FBX的,你需要在UMG函數里這個節點,添加你自己的路徑,比如C:/test,然后再這個文件夾下放幾個FBX或者OBJ文件:

還有一個問題,材質的賦予,到FBX那個Actor藍圖里,的LoadMeshF函數,我目前就只給了所有ProceduralMesh一樣的材質,你可以根據路徑文件的Index,分別給予不同的材質。
最后附上工程,工程里面的Plugins是插件,帶插件源碼,請使用UE4.19打開:
鏈接:https://pan.baidu.com/s/1kXQcJErCw-_6MKqM0AqctA 密碼:aiab
上一篇:044第二次作業
下一篇:4米2冷藏車廠家供應價格








