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()
+}