vault backup: 2024-09-12 16:09:05
This commit is contained in:
parent
aacb0f78cc
commit
79ad1e2c24
136
03-UnrealEngine/Gameplay/Mass/Mass扩展笔记.md
Normal file
136
03-UnrealEngine/Gameplay/Mass/Mass扩展笔记.md
Normal file
@ -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<UInstancedStaticMeshComponent>(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<float> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
Loading…
x
Reference in New Issue
Block a user