From 79ad1e2c249e64cf0218fadbe3cfd68677985cba Mon Sep 17 00:00:00 2001 From: BlueRose <378100977@qq.com> Date: Thu, 12 Sep 2024 16:09:05 +0800 Subject: [PATCH] vault backup: 2024-09-12 16:09:05 --- 03-UnrealEngine/Gameplay/Mass/Mass扩展笔记.md | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 03-UnrealEngine/Gameplay/Mass/Mass扩展笔记.md diff --git a/03-UnrealEngine/Gameplay/Mass/Mass扩展笔记.md b/03-UnrealEngine/Gameplay/Mass/Mass扩展笔记.md new file mode 100644 index 0000000..0fd6f6d --- /dev/null +++ b/03-UnrealEngine/Gameplay/Mass/Mass扩展笔记.md @@ -0,0 +1,136 @@ +--- +title: Mass扩展笔记 +date: 2024-09-12 15:32:15 +excerpt: +tags: +rating: ⭐ +--- +# +1. 创建 UMassEntityTraitBase (UMassVisualizationTrait) +2. 相关的渲染设置逻辑位于UMassVisualizationComponent。 + + + +# UMassVisualizationComponent +```c++ + +void UMassVisualizationComponent::ConstructStaticMeshComponents() +{ + AActor* ActorOwner = GetOwner(); + check(ActorOwner); + + UE_MT_SCOPED_WRITE_ACCESS(InstancedStaticMeshInfosDetector); + for (FMassInstancedStaticMeshInfo& Info : InstancedStaticMeshInfos) + { + // Check if it is already created + if (!Info.InstancedStaticMeshComponents.IsEmpty()) + { + continue; + } + + // Check if there are any specified meshes for this visual type + if(Info.Desc.Meshes.Num() == 0) + { + UE_LOG(LogMassRepresentation, Error, TEXT("No associated meshes for this intanced static mesh type")); + continue; + } + for (const FStaticMeshInstanceVisualizationMeshDesc& MeshDesc : Info.Desc.Meshes) + { + FISMCSharedData* SharedData = ISMCSharedData.Find(MeshDesc); + UInstancedStaticMeshComponent* ISMC = SharedData ? SharedData->ISMC : nullptr; + if (SharedData) + { + SharedData->RefCount += 1; + } + else + { + ISMC = NewObject(ActorOwner); + ISMC->SetStaticMesh(MeshDesc.Mesh); + for (int32 ElementIndex = 0; ElementIndex < MeshDesc.MaterialOverrides.Num(); ++ElementIndex) + { + if (UMaterialInterface* MaterialOverride = MeshDesc.MaterialOverrides[ElementIndex]) + { + ISMC->SetMaterial(ElementIndex, MaterialOverride); + } + } + ISMC->SetCullDistances(0, 1000000); // @todo: Need to figure out what to do here, either LOD or cull distances. + ISMC->SetupAttachment(ActorOwner->GetRootComponent()); + ISMC->SetCanEverAffectNavigation(false); + ISMC->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName); + ISMC->SetCastShadow(MeshDesc.bCastShadows); + ISMC->Mobility = MeshDesc.Mobility; + ISMC->SetReceivesDecals(false); + ISMC->RegisterComponent(); + + ISMCSharedData.Emplace(MeshDesc, FISMCSharedData(ISMC)); + } + + Info.InstancedStaticMeshComponents.Add(ISMC); + } + + // Build the LOD significance ranges + TArray AllLODSignificances; + auto UniqueInsertOrdered = [&AllLODSignificances](const float Significance) + { + int i = 0; + for (; i < AllLODSignificances.Num(); ++i) + { + // I did not use epsilon check here on purpose, because it will make it hard later meshes inside. + if (Significance == AllLODSignificances[i]) + { + return; + } + if (AllLODSignificances[i] > Significance) + { + break; + } + } + AllLODSignificances.Insert(Significance, i); + }; + for (const FStaticMeshInstanceVisualizationMeshDesc& MeshDesc : Info.Desc.Meshes) + { + UniqueInsertOrdered(MeshDesc.MinLODSignificance); + UniqueInsertOrdered(MeshDesc.MaxLODSignificance); + } + Info.LODSignificanceRanges.SetNum(AllLODSignificances.Num() - 1); + for (int i = 0; i < Info.LODSignificanceRanges.Num(); ++i) + { + FMassLODSignificanceRange& Range = Info.LODSignificanceRanges[i]; + Range.MinSignificance = AllLODSignificances[i]; + Range.MaxSignificance = AllLODSignificances[i+1]; + Range.ISMCSharedDataPtr = &ISMCSharedData; + + for (int j = 0; j < Info.Desc.Meshes.Num(); ++j) + { + const FStaticMeshInstanceVisualizationMeshDesc& MeshDesc = Info.Desc.Meshes[j]; + const bool bAddMeshInRange = (Range.MinSignificance >= MeshDesc.MinLODSignificance && Range.MinSignificance < MeshDesc.MaxLODSignificance); + if (bAddMeshInRange) + { + Range.StaticMeshRefs.Add(MeshDesc); + } + } + } + + } +} +``` + +设置灯光通道: +```c++ +void UPrimitiveComponent::SetLightingChannels(bool bChannel0, bool bChannel1, bool bChannel2) +{ + if (bChannel0 != LightingChannels.bChannel0 || + bChannel1 != LightingChannels.bChannel1 || + bChannel2 != LightingChannels.bChannel2) + { + LightingChannels.bChannel0 = bChannel0; + LightingChannels.bChannel1 = bChannel1; + LightingChannels.bChannel2 = bChannel2; + if (SceneProxy) + { + SceneProxy->SetLightingChannels_GameThread(LightingChannels); + } + MarkRenderStateDirty(); + } +} +``` \ No newline at end of file