UE5 SetActorLocation背后发生了什么

一、接口在游戏线程被调用时:

cpp 复制代码
AActor::SetActorLocation
  -> RootComponent->MoveComponent
  -> InternalSetWorldLocationAndRotation
      -> 计算 RelativeLocation / RelativeRotation
      -> UpdateComponentToWorldWithParent
          -> CalcNewComponentToWorld
          -> ComponentToWorld = NewTransform
          -> PropagateTransformUpdate
              -> UpdateBounds
              -> OnUpdateTransform
              -> TransformUpdated.Broadcast
                 // 标记这个组件为Dirty
              -> MarkRenderTransformDirty
                  -> MarkForNeededEndOfFrameUpdate                   
                         //将这个组件加入到一个数组中,在帧末时 来调用
                      -> MarkActorComponentForNeededEndOfFrameUpdate
                         
              -> UpdateChildTransforms

二、在帧末时:

cpp 复制代码
UWorld::SendAllEndOfFrameUpdates
  -> DoDeferredRenderUpdates_Concurrent
      -> SendRenderTransform_Concurrent
          -> FSceneInterface::UpdatePrimitiveTransform
              -> FScene::UpdatePrimitiveTransform
                     //创建了一个RenderCommand添加到渲染线程执行
                  -> ENQUEUE_RENDER_COMMAND( UpdateTransformCommand )   

最终会更新渲染线程侧的 Primitive Proxy 状态

Tip: ENQUEUE_RENDER_COMMAND( UpdateTransformCommand ) 这个宏传入的是值类型的数据,并且在Render Thread 会把这些值类型赋值给Primitive Proxy。然后在RenderThread中,Primitive Proxy提供渲染数据,从而避免GameThread 和RenderThread 的数据读写冲突

附加一个具体的代码

cpp 复制代码
ENQUEUE_RENDER_COMMAND(UpdateTransformCommand)(
						[UpdateParams](FRHICommandListBase&)
						{
							FScopeCycleCounter Context(UpdateParams.PrimitiveSceneProxy->GetStatId());
							UpdateParams.Scene->UpdatePrimitiveTransform_RenderThread(
								UpdateParams.PrimitiveSceneProxy,
								UpdateParams.WorldBounds,
								UpdateParams.LocalBounds,
								UpdateParams.LocalToWorld,
								UpdateParams.AttachmentRootPosition,
								UpdateParams.PreviousTransform
							);
							if (FSimpleStreamableAssetManager::IsEnabled())
							{
								const FPrimitiveSceneProxy* SceneProxy = UpdateParams.PrimitiveSceneProxy;
								FSimpleStreamableAssetManager::Update(
									FSimpleStreamableAssetManager::FUpdate
									{
										SceneProxy,
										SceneProxy->SimpleStreamableAssetManagerIndex,
										UpdateParams.WorldBounds,
										SceneProxy->GetMinDrawDistance(),
										SceneProxy->GetMaxDrawDistance(),
										SceneProxy->PrimitiveSceneInfo->LastRenderTime,
										SceneProxy->IsForceMipStreaming()
									}
								);
							}
						}
					);
相关推荐
努力学习的小廉2 天前
UE5 入门系列(三):核心框架类全解析
ue5
平行云3 天前
建筑BIM/3D可视化轻量级实时评审与分享方案
unity·ue5·3dsmax·实时云渲染·云桌面·云游戏·建筑bim
BugPhysician8 天前
影之刃零首发UE崩溃排查:着色器缓存、虚拟内存与驱动版本
ue5·影之刃零·影之刃零报错·影之刃零进不去·ue崩溃·ue引擎崩溃·ue5引擎崩溃
电子云与长程纠缠9 天前
UE5魂系游戏开发教程05
开发语言·学习·游戏·ui·ue5
fanfan_hongyun9 天前
UE5.1 蓝图调用C++方法
ue5
易知微EasyV数据可视化9 天前
UE5 中接入 GDAL:从vcpkg编译到插件打包
ue5
努力学习的小廉9 天前
UE5入门系列(一):环境搭建.md
ue5
fanfan_hongyun10 天前
【UE5.1 创建C++文件】
c++·ue5
努力学习的小廉10 天前
UE5 入门系列(二):编辑器基础操作速通
ue5·编辑器
Дерек的学习记录11 天前
Unreal Engine 5:开关门实现和流程控制
开发语言·学习·ue5