#pragma once #include "CoreMinimal.h" #include "GameFramework/PlayerController.h" #include "MotionCaptureInterface.h" #include "PlanetPlayerController.generated.h" class AInteractiveObjectBase; class UGlobeInteractionComponent; DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnObjectSelected, AInteractiveObjectBase*, Object); DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnObjectDeselected); /** * APlanetPlayerController * * 统一处理两路输入: * 1. 鼠标/键盘(始终可用,调试和演示备用) * 2. 动捕手势(TODO: 供应商协议确认后接入) * * 鼠标操作: * 左键拖拽 → 旋转地球 * 滚轮 → 缩放 * 悬停 → 高亮物件 * 左键单击 → 选中物件 / 取消选中 * ESC → 取消选中 */ UCLASS(BlueprintType, Blueprintable) class PLANETCLIENT_API APlanetPlayerController : public APlayerController { GENERATED_BODY() public: APlanetPlayerController(); // ----------------------------------------------------------------------- // 组件 // ----------------------------------------------------------------------- UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Planet|Components") UGlobeInteractionComponent* GlobeInteraction; // ----------------------------------------------------------------------- // 动捕配置(TODO: 供应商回复后配置) // ----------------------------------------------------------------------- UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Planet|MotionCapture") FMotionActionMapping MotionActionMapping; // 动捕接收器实例(TODO: 确认协议后指向具体子类实例) UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Planet|MotionCapture") UMotionCaptureReceiver* MotionCaptureReceiver = nullptr; // ----------------------------------------------------------------------- // 鼠标灵敏度 // ----------------------------------------------------------------------- UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Planet|Input") float MouseDragSensitivity = 0.3f; // 判定为"拖拽"而非"点击"的最小移动距离(像素) UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Planet|Input") float DragThresholdPixels = 5.f; // ----------------------------------------------------------------------- // 事件 // ----------------------------------------------------------------------- UPROPERTY(BlueprintAssignable, Category="Planet|Events") FOnObjectSelected OnObjectSelected; UPROPERTY(BlueprintAssignable, Category="Planet|Events") FOnObjectDeselected OnObjectDeselected; // ----------------------------------------------------------------------- // 公开 API // ----------------------------------------------------------------------- UFUNCTION(BlueprintCallable, Category="Planet") void DeselectCurrent(); UFUNCTION(BlueprintPure, Category="Planet") AInteractiveObjectBase* GetSelectedObject() const { return SelectedObject; } protected: virtual void BeginPlay() override; virtual void Tick(float DeltaTime) override; virtual void SetupInputComponent() override; private: // 鼠标拖拽状态 bool bLeftMouseDown = false; bool bIsDragging = false; FVector2D MouseDownPosition = FVector2D::ZeroVector; // 交互状态 AInteractiveObjectBase* SelectedObject = nullptr; AInteractiveObjectBase* HoveredObject = nullptr; // 输入回调 void OnLeftMouseDown(); void OnLeftMouseUp(); void OnMouseX(float Value); void OnMouseY(float Value); void OnZoom(float Value); void OnEscape(); // 悬停检测 void UpdateHover(); // 射线检测 AInteractiveObjectBase* GetObjectUnderCursor() const; // 动捕事件绑定(TODO: 供应商回复后在 BeginPlay 里绑定接收器) UFUNCTION() void OnMotionGesture(EMotionGesture Gesture); UFUNCTION() void OnMotionRotate(float DeltaYaw, float DeltaPitch); UFUNCTION() void OnMotionZoom(float DeltaScale); void BindMotionCaptureEvents(); };