vault backup: 2025-07-14 15:06:59

This commit is contained in:
BlueRose 2025-07-14 15:06:59 +08:00
parent 884ee372ed
commit 6d9b688f0f

View File

@ -1069,3 +1069,101 @@ OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEZ"), 1);
# 植被生成逻辑
Tick() => TerrainAndSpawnablesManagement() => UpdateSpawnables() => UpdateSpawnable()
# 碰撞Python逻辑
```python
def TickCheckWorldReady(self, dt: float) -> bool:
is_shader_world_ready = self.ShaderWorldActor.WorldAndCollisionGeneratedReady()
if not is_shader_world_ready:
return True
is_ready = self.ShaderWorldActor.CheckCollisionGeneratedReady(self.AvatarBornPosition)
print("LBK -------- TickCheckWorldReady", self.FailedCheckCnt, is_ready)
if is_ready:
self.OnWorldMeshReady()
ue.RemoveTicker(self.worldTickHander)
# 等待地形物理加载完毕
if self.OtherLoadFinshed:
GlobalData.TimerSystem.AddTimer(1, self.ReallyStartDriving)
else:
self.OtherLoadFinshed = True
print('LBK -------------- DrivingModeSystem: TickCheckWorldReady', GlobalData.p.pos, self.AvatarBornPosition)
return False
self.FailedCheckCnt += 1
if self.FailedCheckCnt > self.FailedAttemptCnt: #self.FailedAttemptCnt为40
self.ShaderWorldActor.RebuildWorld()
self.FailedCheckCnt = 0
return True
# 通过LineTraceSingleForObjects检测碰撞高度是否超过5来判断碰撞是否生成。
def CheckCollisionGeneratedReady(self, checkPosition: ue.Vector) -> bool:
HitStartLocation = checkPosition + ue.Vector(0, 0, 50000.0)
HitEndLocation = checkPosition + ue.Vector(0, 0, -50000.0)
hitState, hitResult = ue.KismetSystemLibrary.LineTraceSingleForObjects(
self.GetWorld(),
HitStartLocation,
HitEndLocation,
[ue.EObjectTypeQuery.ObjectTypeQuery1, ue.EObjectTypeQuery.ObjectTypeQuery13], # Ground
False, # 是否追踪复杂碰撞
[],
ue.EDrawDebugTrace.ForDuration if GlobalData.IsDebugMode else ue.EDrawDebugTrace.NONE, # 调试可视化
True, # 忽略自身
ue.LinearColor(1.0, 0.0, 0.0, 1.0), # 红色
ue.LinearColor(0.0, 1.0, 0.0, 1.0), # 绿色
20.0 # 调试线条持续时间
)
if not hitState:
return False
# TODO LBK 这个射线检测的方式不太准确,那个物理生成,会从平面开始
return hitResult.Location.Z > 5.0
```
```c++
bool AShaderWorldActor::WorldAndCollisionGeneratedReady()
{
if (!WorldGeneratedAndReady())
return false;
if (!CollisionShareable.IsValid())
return false;
FScopeLock CollisionMeshArrayAccess(CollisionMeshAccessLock.Get());
// 1. 必须有碰撞布局
if (CollisionShareable->GroundCollisionLayout.Num() == 0)
return false;
// 2. 检查所有Patch都ready
for (const auto& Pair : CollisionShareable->GroundCollisionLayout)
{
const FIntVector& Loc = Pair.Key;
const FName& CollisionName = Pair.Value;
// Patch必须存在
if (!CollisionMesh.Contains(CollisionName))
return false;
// Patch必须在已用集合
if (!CollisionShareable->UsedCollisionMesh.Contains(CollisionName))
return false;
// Patch必须ReadBack完成
const FCollisionMeshElement& CollisionElement = *CollisionMesh.Find(CollisionName);
if (!CollisionElement.ReadBackCompletion.IsValid() || !(*CollisionElement.ReadBackCompletion.Get()))
return false;
// Patch不能在待处理队列
if (CollisionReadToProcess.Contains(CollisionName))
return false;
if (!UsedCollisionMesh.Contains(CollisionName))
return false;
// Patch不能在工作队列
for (const auto& WQ : CollisionWorkQueue)
if (WQ.MeshID == CollisionName)
return false;
}
return true;
}
```