专栏名称: 游戏开发技术教程
网易十年码农,教程、内推、解惑。游戏开发技术、技巧、教程和资源下载,答疑解惑,内推面试。Unity3D、UnrealEngine(UE4、UE5)引擎,C#、C++等语法,图形渲染、物理动画、原理机制、源码剖析等及面试笔试题、职业规划。
目录
相关文章推荐
微观三农  ·  2025年大豆提单产科学施肥指导意见 ·  昨天  
微观三农  ·  微评丨化被动为主动,积极应对“倒春寒” ·  2 天前  
微观三农  ·  2025年春季小麦提单产科学施肥指导意见 ·  3 天前  
51好读  ›  专栏  ›  游戏开发技术教程

虚幻4渲染编程(工具篇)【第八卷:Asset creation】

游戏开发技术教程  · 公众号  ·  · 2024-05-14 19:29

主要观点总结

本文主要介绍了在虚幻引擎中创建资源的方法,包括创建工具创建资源、初始化资源、管理资源等需求。文章详细描述了创建不同类型资源(如Mesh Asset、Material Instance Asset、Texture等)的过程,并提供了相应的代码示例。此外,文章还概述了如何通过AssetTools提供的AssetFactory来创建资源。

关键观点总结

关键观点1: 虚幻引擎中的资源创建流程

文章介绍了在虚幻引擎中创建资源的固定格式,包括创建Package、创建对应的UObject、填充数据、通知资源浏览器等步骤。

关键观点2: 创建Mesh Asset的过程

文章提供了创建Mesh Asset的详细步骤和代码示例,包括创建Package、创建Object、初始化资源等。

关键观点3: 创建Material Instance Asset和Texture的过程

文章介绍了创建Material Instance Asset和Texture的方法,包括使用AssetTools提供的AssetFactory来创建资源的过程。

关键观点4: 编辑器时间内创建数据的方法

文章给出了在编辑器时间内创建数据(如Texture)的示例代码,并解释了如何填充Source数据。


正文

MY BLOG DIRECTORY:


INTRODUCTION:

有时候我们需要写工具创建资源,初始化资源,管理资源等需求,比如合并DC的时候需要重新创建贴图,管理材质的时候需要创建并指认材质球,设置材质球等。

在一切开始之前需要清楚虚幻的资源结构以及合编辑器的关系。首先虚幻中有大量的类型,UMaterial,MaterialInstance,Texture,StaticMesh等等,这些资源从外部导入到引擎的时候做了一次数据抽取,如贴图资源模型资源等。这些数据被放在了一个UObject里,然后这个UObject放在一个Package里。

拿贴图的数据导入为例,如下图所示。

引擎会抽取数据然后创建对应的UTexture。使用创建的UTexture填充其Source。所以Unreal的资源创建有一个固定格式

(1)New一个Package

(2)New一个对应的UObject,在此时指认Package合UObject

(3)向这个UObject里填充数据

(4)MarkDirty,通知资源浏览器这里创建了一个新资源,然后保存。


MAIN CONTENT:

(1)Create Mesh Asset with c++

先来一段简单的

按下按钮后创建一个新的模型资源,代码如下:

  1. FString CreatedMeshName = TEXT("TestMesh");

  2. FString AssetPath = AssetDatas[0].PackagePath.ToString() + TEXT("/Content");

  3. UPackage* NewMeshPack = CreatePackage(nullptr, *AssetPath);

  4. UStaticMesh* NewStaticMesh = NewObject<UStaticMesh>(NewMeshPack, FName(*CreatedMeshName), RF_Public | RF_Standalone);

  5. FAssetRegistryModule ::AssetCreated(NewStaticMesh);

  6. NewMeshPack->MarkPackageDirty();

过程也是非常简单的,首先先创建一个Package,然后New一个mesh,在NewObject方法中就会把这个新创建的UObject和Package指认,然后通知ContentBrower我们创建了这个新资源,请求它加载即可。

这里创建的是一个空的MeshAsset,如果想要给MeshAsset里加模型的顶点信息等,可以通过设置NewStaticMesh->SourceModels来给MeshAsset增加资源信息。

然后是我写的:

【1】创建Package

【2】创建Object

【3】初始化资源

  1. /************************************************************************/

  2. /* Init Static Mesh */

  3. /************************************************************************/

  4. StaticMesh->InitResources();

  5. StaticMesh->LightingGuid = FGuid::NewGuid();

  6. // Determine which texture coordinate map should be used for storing/generating the lightmap UVs

  7. const uint32 LightMapIndex = FMath::Min(MaxInUseTextureCoordinate + 1, (uint32)MAX_MESH_TEXTURE_COORDS - 1);

  8. // Add source to new StaticMesh

  9. for (FRawMesh& RawMesh : RawMeshes)

  10. {

  11. if (RawMesh.IsValidOrFixable())

  12. {

  13. FStaticMeshSourceModel& SrcModel = StaticMesh->AddSourceModel();

  14. SrcModel.BuildSettings.bRecomputeNormals = false;

  15. SrcModel.BuildSettings.bRecomputeTangents = false;

  16. SrcModel.BuildSettings.bRemoveDegenerates = true;

  17. SrcModel.BuildSettings.bUseHighPrecisionTangentBasis = false;

  18. SrcModel.BuildSettings.bUseFullPrecisionUVs = false;

  19. SrcModel. BuildSettings.bGenerateLightmapUVs = true;

  20. SrcModel.BuildSettings.SrcLightmapIndex = 0;

  21. SrcModel.BuildSettings.DstLightmapIndex = LightMapIndex;

  22. SrcModel.SaveRawMesh(RawMesh);

  23. }

  24. }

  25. // Copy materials to new mesh

  26. //for (UMaterialInterface* Material : Materials)

  27. //{

  28. // StaticMesh->StaticMaterials.Add(FStaticMaterial(Material));

  29. //}

  30. //Force to use one material to render this mesh, reducing draw call on ceil phong platform

  31. StaticMesh->StaticMaterials.SetNum(1);

  32. StaticMesh->StaticMaterials[0] = FStaticMaterial(MergeOneMaterial);

  33. //Set the Imported version before calling the build

  34. StaticMesh->ImportVersion = EImportStaticMeshVersion::LastVersion;

  35. // Set light map coordinate index to match DstLightmapIndex

  36. StaticMesh->LightMapCoordinateIndex = LightMapIndex;

  37. // setup section info map

  38. for (int32 RawMeshLODIndex = 0; RawMeshLODIndex < RawMeshes.Num(); RawMeshLODIndex++)

  39. {

  40. const FRawMesh& RawMesh = RawMeshes[RawMeshLODIndex];

  41. TArray UniqueMaterialIndices;

  42. for (int32 MaterialIndex : RawMesh.FaceMaterialIndices)

  43. {

  44. UniqueMaterialIndices.AddUnique(MaterialIndex);

  45. }

  46. int32 SectionIndex = 0;

  47. for (int32 UniqueMaterialIndex : UniqueMaterialIndices)

  48. {

  49. StaticMesh->SectionInfoMap.Set(RawMeshLODIndex, SectionIndex, FMeshSectionInfo(UniqueMaterialIndex));

  50. SectionIndex++;

  51. }

  52. }

  53. StaticMesh->OriginalSectionInfoMap.CopyFrom( StaticMesh->SectionInfoMap);

  54. // Build mesh from source

  55. StaticMesh->Build(false);

  56. StaticMesh->PostEditChange();

【4】MarkDirty然后通知资源浏览器

  1. StaticMesh->MarkPackageDirty();

告知资源浏览器

  1. FAssetRegistryModule::AssetCreated(StaticMesh);

(2)Create Material Instance Asset with c++

  1. FString MaterialInsBaseName = "MI_";

  2. MaterialInsBaseName += AssetDatas[i].AssetName.ToString();

  3. FString AssetPath = AssetDatas[i].PackagePath.ToString() + TEXT("/Content");

  4. UPackage* NewMatInsPack = CreatePackage(nullptr, *AssetPath);

  5. UMaterialInstanceConstantFactoryNew* Factory = NewObject<UMaterialInstanceConstantFactoryNew>();

  6. FAssetToolsModule& AssetToolsModule = FModuleManager







请到「今天看啥」查看全文