开篇

其实UE4中有很多Commandlet这些Commandlet 为我们提供了不同的功能有自动导入资源的ImportAssetsCommandlet;烘焙的CookCommandlet等等。了解和熟悉这些Commandlet可以帮助我们实现自动化或者半自动化流程。

今天我们就来讲讲ImportAssetsCommandlet 这个Commandlet 可以实现静默的资源导入。想具体了解这个命令都干了些什么事情就需要去到引擎源代码中的Editor\UnrealEd\Private\Commandlets\ImportAssetsCommandlet.cpp 看源码了。 在这里我教大家如何使用或者是如何配置一个自动化导入资源的命令以及简单的剖析这个命令的源码 ,看看里面都做了些什么。

正文

如何使用
使用这个命令的方式很简单打开cmd命令行找到 引擎的Binaries\Win64文件夹 下有一个叫UE4Ediotr-cmd.exe 的可执行文件 将这个exe 拖进cmd窗口 然后 按照下面的格式输入命令:

 项目的.uproject  -run=ImportAssets -importSettings="导入设置的json文件路径"

完整示例:

D:\SoftWare\UE_4.25\Engine\Binaries\Win64\UE4Editor-Cmd.exe "D:\WorkSpace\Unreal Project\ACT\ACT.uproject" -run=ImportAssets -importSettings="D:/Export/Importsetting.json"

首先我们来讲下 第一个是引擎编辑器的cmd 第二个参数是你要导入的项目 第三个是需要导入的资源的json 文件

下面我们来看看这个导入设置的json 文件

{"ImportGroups": [{"FileNames": [ "C:/Users/VR/Desktop/Export/43291A04.fbx" ],"bReplaceExisting": "true","DestinationPath": "/Game/mesh/UserModel/638281/43291A04/","FactoryName": "FbxFactory","ImportSettings": {}},{"FileNames": [ "C:/Users/VR/Desktop/Temp/43291A04/3d66Mat-855555-maps-1_diffuse.jpg", "C:/Users/VR/Desktop/Temp/43291A04/3d66Mat-855555-maps-1_normal.jpg", "C:/Users/VR/Desktop/Temp/43291A04/43291A04_001_AO.png", "C:/Users/VR/Desktop/Temp/43291A04/43291A04_002_AO.png", "C:/Users/VR/Desktop/Temp/43291A04/43291A04_003_AO.png", "C:/Users/VR/Desktop/Temp/43291A04/43291A04_006_AO.png"],"bReplaceExisting": "true","DestinationPath": "/Game/mesh/UserModel/638281/43291A04/Texture/","bSkipReadOnly": "true","ImportSettings": {}}]
}

我们来解析一下 ImportGroups 里面是 代表的是每组导入的资源 可以分组导入
例如我第一组到的可能是fbx文件 然后指定使用fbx的工厂类去处理这批资源自动导入 其中还有
bReplaceExisting 参数指定是否替换现有资源;
FileNames 组里面都是些需要导入的资源的路径 ;
DestinationPath 需要将这组资源导入到什么位置
bSkipReadOnly 是否跳过自读的文件 ;
ImportSettings 里面没放参数 但是可以通过json去指定一些导入的设置 下面放一组fbx 的可指定参数参照; ------当然除了这种Json的方式指定导入时的设置我们还可以打开我们的项目将我们需要导入的资源不同类型的先导入一遍然后按照自己的设置去导入 然后会发现我们的项目save\Config\Windows\EditorPerProjectUserSettings.ini下的配置文件会帮我们记录这份导入设置 看下图

"ImportSettings": {"AnimSequenceImportData":{},"SkeletalMeshImportData":{},"TextureImportData":{},"StaticMeshImportData":{}"bCombineMeshes":0,"bAutoGenerateCollision":1,"bRemoveDegenerates":1
}


上图中都是记录的一些导入设置 ImportAssets 命令执行时如果发现 ImportSettings 里面是空的就会去读项目的设置

代码的简单分析
由于代码过多这里没有办法对所有代码进行注解,只能对部分我认为比较重要的代码进行注解

bool UImportAssetsCommandlet::ImportAndSave(const TArray<UAutomatedAssetImportData*>& AssetImportList)
{bool bImportAndSaveSucceeded = true; //初始化自动导入和自动保存FAssetToolsModule& AssetToolsModule = FModuleManager::Get().LoadModuleChecked<FAssetToolsModule>("AssetTools"); //加载AssetTools模块 这个模块内包含了很多对资源进行操作的功能 具体可以看看AssetTools模块的源代码 ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider();for(const UAutomatedAssetImportData* ImportData : AssetImportList) //枚举每组导入资源{UE_LOG(LogAutomatedImport, Log, TEXT("Importing group %s"), *ImportData->GetDisplayName() );UFactory* Factory = ImportData->Factory; //从这组导入资源中获取指定的工厂类 我们上面示例Json中导入 FBX就有指定const TSharedPtr<FJsonObject>* ImportSettingsJsonObject = nullptr;if(ImportData->ImportGroupJsonData.IsValid()) //判断这组导入资源的Json是否有效{ImportData->ImportGroupJsonData->TryGetObjectField(TEXT("ImportSettings"), ImportSettingsJsonObject); //尝试获取导入设置Json}if(Factory != nullptr && ImportSettingsJsonObject) //如果拿到了有效的Json 并且知道了改用什么工厂类去处理{IImportSettingsParser* ImportSettings = Factory->GetImportSettingsParser(); //拿到这个工程类对导入设置的解析器 因为每种资源的导入都有专门的工厂类去处理if(ImportSettings){ImportSettings->ParseFromJson(ImportSettingsJsonObject->ToSharedRef()); //解析导入设置}}else if(Factory == nullptr && ImportSettingsJsonObject){UE_LOG(LogAutomatedImport, Warning, TEXT("A vaild factory name must be specfied in order to specify settings"));}// Load a level if specifiedbImportAndSaveSucceeded = LoadLevel(ImportData->LevelToLoad); //尝试去加载指定的关卡 无指定则 会自动忽略 具体可以看里面的代码实现// Clear dirty packages that were created as a result of loading the level.  We do not want to save theseClearDirtyPackages(); //资源操作 ---- 清理所有资源身上的需要保存的标记TArray<UObject*> ImportedAssets = AssetToolsModule.Get().ImportAssetsAutomated(ImportData); //根据解析好的数据以及设置自动进行资源呢导入 返回一组以及导入的资源if(ImportedAssets.Num() > 0 && bImportAndSaveSucceeded){TArray<UPackage*> DirtyPackages; //创建包TArray<FSourceControlStateRef> PackageStates;FEditorFileUtils::GetDirtyContentPackages(DirtyPackages); //将内容浏览器中刚刚自动导入的资源并标记为需要保存的添加到这个包的数组内FEditorFileUtils::GetDirtyWorldPackages(DirtyPackages);//这个则是世界中的 同上bool bUseSourceControl = bHasSourceControl && SourceControlProvider.IsAvailable(); //这个是版本管理的 git 或者 svn 等if(bUseSourceControl){SourceControlProvider.GetState(DirtyPackages, PackageStates, EStateCacheUsage::ForceUpdate);}for(int32 PackageIndex = 0; PackageIndex < DirtyPackages.Num(); ++PackageIndex){UPackage* PackageToSave = DirtyPackages[PackageIndex];FString PackageFilename = SourceControlHelpers::PackageFilename(PackageToSave);bool bShouldAttemptToSave = false;bool bShouldAttemptToAdd = false;if(bUseSourceControl) //下面都是版本管理的内容{FSourceControlStateRef PackageSCState = PackageStates[PackageIndex];bool bPackageCanBeCheckedOut = false;if(PackageSCState->IsCheckedOutOther()){// Cannot checkout, file is already checked outUE_LOG(LogAutomatedImport, Error, TEXT("%s is already checked out by someone else, can not submit!"), *PackageFilename);bImportAndSaveSucceeded = false;}else if(!PackageSCState->IsCurrent()){// Cannot checkout, file is not at head revisionUE_LOG(LogAutomatedImport, Error, TEXT("%s is not at the head revision and cannot be checked out"), *PackageFilename);bImportAndSaveSucceeded = false;}else if(PackageSCState->CanCheckout()){const bool bWasCheckedOut = SourceControlHelpers::CheckOutOrAddFile(PackageFilename);bShouldAttemptToSave = bWasCheckedOut;if(!bWasCheckedOut){UE_LOG(LogAutomatedImport, Error, TEXT("%s could not be checked out"), *PackageFilename);bImportAndSaveSucceeded = false;}}else{// package was not checked out by another user and is at the current head revision and could not be checked out// this means it should be added after save because it doesn't existbShouldAttemptToSave = true;bShouldAttemptToAdd = true;}}else{bool bIsReadOnly = IFileManager::Get().IsReadOnly(*PackageFilename); //判断是否只读if(bIsReadOnly && ImportData->bSkipReadOnly) //判断是否跳过只读{bShouldAttemptToSave = false;if(bIsReadOnly){UE_LOG(LogAutomatedImport, Error, TEXT("%s is read only and -skipreadonly was specified.  Will not save"), *PackageFilename);bImportAndSaveSucceeded = false;}}else if(bIsReadOnly){bShouldAttemptToSave = FPlatformFileManager::Get().GetPlatformFile().SetReadOnly(*PackageFilename, false); //设置为不是只读if(!bShouldAttemptToSave){UE_LOG(LogAutomatedImport, Error, TEXT("%s is read only and could not be made writable.  Will not save"), *PackageFilename);bImportAndSaveSucceeded = false;}}else{bShouldAttemptToSave = true;}}if(bShouldAttemptToSave){SavePackage(PackageToSave, PackageFilename); //将包保存下来if(bShouldAttemptToAdd){const bool bWasAdded = SourceControlHelpers::MarkFileForAdd(PackageFilename);if(!bWasAdded){UE_LOG(LogAutomatedImport, Error, TEXT("%s could not be added to source control"), *PackageFilename);bImportAndSaveSucceeded = false;}}}}}else{bImportAndSaveSucceeded = false;UE_LOG(LogAutomatedImport, Error, TEXT("Failed to import all assets in group %s"), *ImportData->GetDisplayName());}}return bImportAndSaveSucceeded;
}

上面这部分是资源的的保存了,资源的导入过程中还做了很多事情。不过那都是在一个个工厂类中的事情了,还有前期的Commandlet是如何在为指定工厂类的情况下 知道改用那种工厂类去解析的 。 具体这些代码都可以翻看UE4的源码找到答案

最后
还是那句话如果文章中有一些错误内容请帮我指出,我会十分感谢!!!

文章虽然写的不是很好,但希望转载时注明出处。

UE4引擎之Commandlet命令相关推荐

  1. UE4游戏开发基础命令

    在个人的Unrealengine账户中关联自己的GitHub账户成功之后,就可以访问UE4引擎的源码了. git clone -b release https://github.com/EpicGam ...

  2. 游戏安全UE4引擎之天堂W跳线程,HOOK明文收包发包并分析加密解密,实现send发包

    开始我们的UE4的跳线程之旅 简单了解游戏数据 拿到一个游戏,想去分析,在什么都不了解的情况下,我们只能先盲目的找2个简单的数据熟悉一下,之后再根据需求系统的分析,这是必然的一个顺序. 那么,先来找下 ...

  3. 开源工具 | 手游自动化框架GAutomator,新增iOS系统和UE4引擎支

    WeTest 导读 GAutomator是腾讯WeTest推出的手游自动化测试框架,已用于腾讯多个手游项目组的自动化测试. 1.GAutomator诞生背后 研究过手游自动化测试的同学都知道,虽然市场 ...

  4. 视频教程-FPS游戏逆向与安全+UE4引擎基础详解-其他

    FPS游戏逆向与安全+UE4引擎基础详解 想把自己的知识传播出去,让更多人学习到 苏瑞兵 ¥188.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 APP订阅课程,领取 ...

  5. 认识Panda3D引擎bam相关命令

    看一下Panda自带命令,其中有bam相关的,来了解一下: 输入一个命令看一下,提示需要输入一个bam文件名: 查一下,查到一个介绍一种bam文件的资料如下, SAM (Sequence Alignm ...

  6. 【UE4 C++】如何关联GitHub 下载UE4引擎源代码

    注册一个Epic games的账户和GITHUB的账户,此步骤省略. 绑定Github账号右上角账号名称下拉菜单点个人进入设置界面,如下图 左侧Tab栏选择连接的账户,找到Github点击连接. 绑定 ...

  7. UE4引擎AR开发插件Unreal4AR的获取方法

    <学习笔记记录> 新人接触UE4,在此发帖主要用于记录学习内容,同时希望可以帮助其他朋友 在网上看到很多AR的视频,感觉很有意思,就研究了一下,感觉UE4好像不能直接进行AR的开发.通过查 ...

  8. UE4引擎源码学习笔记(一):源码整体文件结构

    首先根据目录文件夹整体看一下结构,版本4.2 Binaries 里面是一些配置文件和第三方的配置文件,全部是xml,从这可以看到虚幻4都用了什么第三方工具,有各个平台的图形库,还有声音库,物理库(Ph ...

  9. 虚幻引擎的控制台命令(长期更新)

    小标题前如果标注具体虚幻的版本号,则仅在特定版本中有效 若没标注,则代表全版本通用 局内 [UE5]世界分区(World Partition) 显示世界分区加载网格 2D&3D wp.Runt ...

最新文章

  1. 画正圆角矩形 - HTML5 Canvas 作图
  2. 数据结构之查找二叉树
  3. 小白入门深度学习 | 第三篇:30分钟入门深度学习 - TensorFlow版
  4. 电脑维修的十大原则,你都认同吗?
  5. XSLT2.0---多文件输出
  6. 查询引擎: SQL反解析(json2sql)(附源码)
  7. poj 3258 River Hopscotch 二分
  8. linux中ssh登录Permanently added (RSA) to the list of known hosts问题解决
  9. Java集合不能存放基本数据类型,只存放对象的引用
  10. 全国750所高校(50所985/211)501个专业的毕业生在同一家公司搞事情
  11. 物流车笔记——编码器原理
  12. 微信QQ在线客服基本功能介绍
  13. ArcGIS制图学习(1)
  14. 帆软数据决策系统漏洞_帆软报表漏洞总结
  15. 虞美人盛开的山坡片尾曲_さよならの夏_离别的夏天_歌词_带假名及翻译
  16. P1772 [ZJOI2006]物流运输(线性dp+最短路径)
  17. JAVA图形面积与周长(抽象类)
  18. 达人评测 i3 12100和i5 12400选哪个
  19. 批量分析中通快运单号物流,并查看是否签收
  20. sublime 4 设置文件编码 GBK

热门文章

  1. MXC抹茶与Simplex合作,支持VISA、万事达卡直接买币
  2. 华为荣耀MagicBook笔记本 键盘灯怎么设置为常亮?
  3. Android APK安装失败错误代码含义
  4. 微信扫码授权登录手游的原理和问题(你使用的浏览器暂不支持微信登录)
  5. 杰信物流项目总结(八)
  6. java异或-实现字符串找不同
  7. 测试常用的理论知识总结
  8. 树莓派已经通过网络连接通过串口通信在串口调试小助手打印与操作
  9. 程序员常用Mac软件整理
  10. 解决WPS字体缺失问题的四种方法