diff --git a/BladeSmith.sln.DotSettings.user b/BladeSmith.sln.DotSettings.user deleted file mode 100644 index 4b21207..0000000 --- a/BladeSmith.sln.DotSettings.user +++ /dev/null @@ -1,13 +0,0 @@ - - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded - ForceIncluded \ No newline at end of file diff --git a/Content/BP/BP_DynamicIron.uasset b/Content/BP/BP_DynamicIron.uasset index 9b20bf5..a0c29b7 100644 Binary files a/Content/BP/BP_DynamicIron.uasset and b/Content/BP/BP_DynamicIron.uasset differ diff --git a/Content/Maps/Demo.umap b/Content/Maps/Demo.umap index 8087d84..dc6348d 100644 Binary files a/Content/Maps/Demo.umap and b/Content/Maps/Demo.umap differ diff --git a/Source/BladeSmith/BladeSmith.Build.cs b/Source/BladeSmith/BladeSmith.Build.cs index 057f8d9..59e84f4 100644 --- a/Source/BladeSmith/BladeSmith.Build.cs +++ b/Source/BladeSmith/BladeSmith.Build.cs @@ -6,6 +6,7 @@ public class BladeSmith : ModuleRules { public BladeSmith(ReadOnlyTargetRules Target) : base(Target) { + PrivateDependencyModuleNames.AddRange(new string[] { "GeometryScriptingCore" }); PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; // 如果你的模块类型是 Runtime 或 Gameplay 相关的,则添加这行: diff --git a/Source/BladeSmith/DeformAsyncTask.cpp b/Source/BladeSmith/DeformAsyncTask.cpp new file mode 100644 index 0000000..e69de29 diff --git a/Source/BladeSmith/DeformAsyncTask.h b/Source/BladeSmith/DeformAsyncTask.h new file mode 100644 index 0000000..7535230 --- /dev/null +++ b/Source/BladeSmith/DeformAsyncTask.h @@ -0,0 +1,98 @@ +#pragma once +#include "CoreMinimal.h" +#include "GeometryScript/GeometryScriptSelectionTypes.h" +#include "GeometryScript/MeshDeformFunctions.h" +#include "GeometryScript/MeshSpatialFunctions.h" +#include "GeometryScript/MeshTransformFunctions.h" +#include "Kismet/BlueprintAsyncActionBase.h" +#include "DeformAsyncTask.generated.h" + + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnDeformFinished, bool, ResultValue); +// .h 文件 +UCLASS() +class UDeformAsyncTask : public UBlueprintAsyncActionBase +{ + GENERATED_BODY() + +public: + // 暴露给蓝图的静态工厂方法 + UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true", Category = "AsyncTask", WorldContext = "WorldContextObject")) + static UDeformAsyncTask* StartCalculation(UObject* WorldContextObject,FGeometryScriptMeshSelection& InSelection,FVector& InLocalHitLocation,FVector& InLocaHitNormal); + + // 成功回调引脚 (在游戏线程触发) + UPROPERTY(BlueprintAssignable) + FOnDeformFinished OnDeformFinish; + + virtual void Activate() override; + +private: + FGeometryScriptMeshSelection Selection; + FVector LocalHitLocation; + FVector LocaHitNormal; + // 核心计算逻辑,在工作线程中执行 + void PerformBackgroundCalculation(); +}; + +inline UDeformAsyncTask* UDeformAsyncTask::StartCalculation(UObject* WorldContextObject, + FGeometryScriptMeshSelection& InSelection, FVector& InLocalHitLocation, FVector& InLocaHitNormal) +{ + // 1. 检查 WorldContextObject 是否有效,这是异步操作节点的标准做法 + if (!WorldContextObject || !WorldContextObject->GetWorld()) + { + return nullptr; + } + + // 2. 创建 UCalculateAsyncTask 的实例 + // 使用 NewObject 而非 new,以确保对象被 UE 的内存管理系统(GC)追踪 + UDeformAsyncTask* Task = NewObject(); + + // 3. 存储输入参数 + Task->Selection = InSelection; + Task->LocalHitLocation = InLocalHitLocation; + Task->LocaHitNormal = InLocaHitNormal; + + // 4. 将实例的生命周期与 WorldContextObject 绑定,确保在关卡卸载时它能被回收 + Task->RegisterWithGameInstance(WorldContextObject); + + // 5. 调用 Activate() 启动实际的后台逻辑 + // Activate() 才是真正执行后台任务的地方 + Task->Activate(); + + // 6. 返回实例,在蓝图节点上显示回调引脚 + return Task; +} + +// .cpp 文件(在 Activate 中启动后台任务) +inline void UDeformAsyncTask::Activate() +{ + // 启动一个后台任务,使用 UE 的 Task Graph + // 这里的 lambda 函数会在工作线程上运行 + (new FAutoDeleteAsyncTask>( + [this]() + { + PerformBackgroundCalculation(); // 耗时的计算在这里执行 + + // 切换回游戏线程执行回调 + FFunctionGraphTask::CreateAndDispatchWhenReady( + [this]() + { + if (IsValid(this)) + { + // 确保在游戏线程上触发蓝图回调 + OnDeformFinish.Broadcast(true); + SetReadyToDestroy(); + } + }, + TStatId(), + nullptr, + ENamedThreads::GameThread // 确保在游戏线程回调 + ); + } + ))->StartBackgroundTask(); +} + +inline void UDeformAsyncTask::PerformBackgroundCalculation() +{ + UGeometryScriptLibrary_MeshTransformFunctions::TranslateMeshSelection() +}