依赖注入
依赖注入的概念为,不让一个对象自己创建或自己寻找它依赖的东西,而是让外部直接告诉它。
依赖注入这个名字听着很高级,但是我们在平时写代码时肯定都用过。比如形式为 SetXXX 的函数就是最常见的依赖注入方式,它通过 Set 函数设置依赖。另一种常见的方式是在构造函数这个阶段传递依赖项。
在本篇文章中,我们需要 Box 组件(Trigger)和移动组件(Mover)进行“交互”:Box 组件检测到重叠之后,通过移动组件移动对象。
触发对象移动的功能已经实现,有些久远,可以看 《实现移动组件功能》 回顾。
在移动组件中,我们通过设置 ShouldMove 变量来触发所在的 Actor 移动。原来的 ShouldMove 是在编辑器里勾选设置的,现在如代码清单 1 所示,我们去掉 UPROPERTY 宏,并通过添加 SetShouldMove() 接口来设置。
- UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
- class CRYPTRAIDER_API UMover : public UActorComponent
- {
- GENERATED_BODY()
- public:
- void SetShouldMove(bool NewShouldMove);
- private:
- // Checkbox to toggle movement
- bool ShouldMove = false;
- };
接着我们来到 Box 组件的代码所在。如代码清单 2 所示,我们添加 SetMover() 函数设置移动组件,并保存在 Mover 变量中。这就是文章开头所说的依赖注入。
注意此处的 UFUNCTION() 宏。SetMover 需要在蓝图里调用,因为移动组件是在编辑器里添加创建的。
- UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
- class CRYPTRAIDER_API UTriggerComponent : public UBoxComponent
- {
- GENERATED_BODY()
- public:
- UFUNCTION(BlueprintCallable)
- void SetMover(UMover* NewMover);
- private:
- UMover* Mover = NULL;
- };
如代码清单 3 所示,我们在 Box 组件的检测逻辑之后继续完善功能。当检测到有对象重叠时,我们就调用移动组件的函数,让其触发移动。
- // Called every frame
- void UTriggerComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
- {
- Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
- AActor* Actor = GetAcceptableActor();
- if (Actor != NULL)
- {
- UE_LOG(LogTemp, Display, TEXT("Unlocking"));
- if (Mover != NULL)
- Mover->SetShouldMove(true);
- }
- else
- {
- if (Mover != NULL)
- Mover->SetShouldMove(false);
- }
- }
最后我们来到门资产的对应蓝图里。如图 1 所示,我们在 BeginPlay 时调用 Box 组件的 SetMover 接口。传递的移动组件就是当下资产下附加的名为 Mover 的移动组件对象。

运行的效果如下方视频所示。可以看到存在一点小问题,Box 组件没有覆盖门内部上面的拱形,所以重叠事件到上方就停止了,导致门没有继续下降。