【UE4】 第08講 實現全方位的行走
阿新 • • 發佈:2018-11-12
(版權宣告,禁止轉載)
行走控制元件的渲染實現之後,下一步為其新增Pressed事件響應,具體可以參考UButton裡的實現
Pressed的時候,將WalkWidget的方位資訊傳遞給CharacterPanda
實現功能的過程發現,UE4的藍圖系統還是非常靈活高效的,非常推薦深入學習UE4 (^_^)
為自定義的UWalkWidget新增OnPressed事件
分兩部分
UWalkWidget類中
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnWalkWidgetPressedEvent); class MOBAHERO_API UWalkWidget : public UWidget { public: /** Called when the button is pressed */ UPROPERTY(BlueprintAssignable, Category = "WalkWidget|Event") FOnWalkWidgetPressedEvent OnPressed; protected: void SlateHandlePressed(); }; TSharedRef<SWidget> UWalkWidget::RebuildWidget() { MyWalkWidget = SNew(SWalkWidget) .OnPressed(BIND_UOBJECT_DELEGATE(FSimpleDelegate, SlateHandlePressed)); return MyWalkWidget.ToSharedRef(); } void UWalkWidget::SlateHandlePressed() { OnPressed.Broadcast(); }
SWalkWidget類中
需要在OnTouchStarted裡呼叫Press,才能通過藍圖進行事件的控制
class MOBAHERO_API SWalkWidget : public SLeafWidget { public: SLATE_BEGIN_ARGS(SWalkWidget) {} /** Called when the button is pressed */ SLATE_EVENT(FSimpleDelegate, OnPressed) SLATE_END_ARGS() void Construct(const FArguments& InArgs); virtual FReply OnTouchStarted(const FGeometry& MyGeometry, const FPointerEvent& Event) override; private: bool bPressed; /** Press the widget */ virtual void Press(); /** The delegate to execute when the button is pressed */ FSimpleDelegate OnPressed; }; void SWalkWidget::Construct(const FArguments& InArgs) { // bPressed = false; OnPressed = InArgs._OnPressed; } FReply SWalkWidget::OnTouchStarted(const FGeometry& MyGeometry, const FPointerEvent& Event) { FVector2D LocalCoord = MyGeometry.AbsoluteToLocal(Event.GetScreenSpacePosition()); Control.ThumbPosition = LocalCoord - Control.VisualCenter; Press(); return FReply::Handled(); } void SWalkWidget::Press() { if (!bPressed) { bPressed = true; //PlayPressedSound(); OnPressed.ExecuteIfBound(); } }
Slate藍圖 成功時右側會在【事件】下面顯示OnPressed
編輯事件,並傳遞資訊給CharacterPanda
在Level藍圖設定Player Controller的Owner,然後傳遞給Slate藍圖
最後在CharacterPanda裡只需SetDirection即可進行方向控制
void ACharacterPanda::SetDirection(const FVector2D& Dir)
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, FString::Printf(TEXT("當前方向 X:%.3f,Y:%.3f"), Dir.X, Dir.Y));
//
VelocityDirection = FVector(-Dir.Y,Dir.X,0.f);
FQuat Rot;
Rot = FQuat::FindBetweenVectors(FVector(0.f,1.f,0.f), VelocityDirection);
this->SetActorRotation(Rot);
CurrentState = CharacterState::Walk;
}