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