diff --git a/Source/ChildHood/ChildHoodCharacter.cpp b/Source/ChildHood/ChildHoodCharacter.cpp index 60e34b8..f3a1383 100644 --- a/Source/ChildHood/ChildHoodCharacter.cpp +++ b/Source/ChildHood/ChildHoodCharacter.cpp @@ -16,55 +16,72 @@ AChildHoodCharacter::AChildHoodCharacter() { // Set size for collision capsule GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f); - + // Don't rotate when the controller rotates. Let that just affect the camera. bUseControllerRotationPitch = false; bUseControllerRotationYaw = false; bUseControllerRotationRoll = false; - // Configure character movement - GetCharacterMovement()->bOrientRotationToMovement = true; - GetCharacterMovement()->RotationRate = FRotator(0.0f, 500.0f, 0.0f); - - // Note: For faster iteration times these variables, and many more, can be tweaked in the Character Blueprint - // instead of recompiling to adjust them - GetCharacterMovement()->JumpZVelocity = 500.f; - GetCharacterMovement()->AirControl = 0.35f; - GetCharacterMovement()->MaxWalkSpeed = 500.f; - GetCharacterMovement()->MinAnalogWalkSpeed = 20.f; - GetCharacterMovement()->BrakingDecelerationWalking = 2000.f; - GetCharacterMovement()->BrakingDecelerationFalling = 1500.0f; + // Configure character movement — v0.1 player controller tech design parameters + auto* CMC = GetCharacterMovement(); + CMC->bOrientRotationToMovement = true; // 角色朝移动方向旋转 + CMC->RotationRate = FRotator(0.0f, 720.0f, 0.0f); // 转向速度 720°/s(远快于鼠标 150°/s) + CMC->MaxWalkSpeed = 450.0f; // 跑步速度 4.5 m/s + CMC->MaxAcceleration = 2250.0f; // 起步加速 0.2s (450/0.2) + CMC->BrakingDecelerationWalking = 1500.0f; // 停止减速 0.3s (450/0.3) + CMC->BrakingDecelerationFalling = 1500.0f; + CMC->MinAnalogWalkSpeed = 20.f; + // WalkableFloorAngle 默认 45°,无需修改 + // v0.1 不跳跃,不设置 JumpZVelocity / AirControl // Create a camera boom (pulls in towards the player if there is a collision) CameraBoom = CreateDefaultSubobject(TEXT("CameraBoom")); CameraBoom->SetupAttachment(RootComponent); - CameraBoom->TargetArmLength = 400.0f; + CameraBoom->TargetArmLength = 350.0f; // 摄像机距离 3.5m + CameraBoom->SocketOffset = FVector(0.f, 0.f, 80.f); // 摄像机高度 0.8m(头部上方) CameraBoom->bUsePawnControlRotation = true; + // 摄像机软跟随 + CameraBoom->bEnableCameraLag = true; // 启用位置延迟跟随 + CameraBoom->CameraLagSpeed = 6.0f; // 跟随速度(可调 2-8) + CameraBoom->bEnableCameraRotationLag = false; // v0.1 不启用旋转延迟 + + // 摄像机碰撞处理 + CameraBoom->bDoCollisionTest = true; // 启用碰撞检测 + CameraBoom->ProbeSize = 12.0f; // 碰撞探针半径 + CameraBoom->ProbeChannel = ECC_Camera; // 使用 Camera 碰撞通道 + // Create a follow camera FollowCamera = CreateDefaultSubobject(TEXT("FollowCamera")); FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); FollowCamera->bUsePawnControlRotation = false; - - // Note: The skeletal mesh and anim blueprint references on the Mesh component (inherited from Character) - // are set in the derived blueprint asset named ThirdPersonCharacter (to avoid direct content references in C++) } void AChildHoodCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) { // Set up action bindings if (UEnhancedInputComponent* EnhancedInputComponent = Cast(PlayerInputComponent)) { - - // Jumping - EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Started, this, &ACharacter::Jump); - EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping); // Moving EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AChildHoodCharacter::Move); + + // Looking (gamepad + mouse) + EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &AChildHoodCharacter::Look); EnhancedInputComponent->BindAction(MouseLookAction, ETriggerEvent::Triggered, this, &AChildHoodCharacter::Look); - // Looking - EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &AChildHoodCharacter::Look); + // Interaction IAs — bind to placeholder callbacks; interaction system will hook into these + if (InteractAction) + { + EnhancedInputComponent->BindAction(InteractAction, ETriggerEvent::Started, this, &AChildHoodCharacter::OnInteract); + } + if (CancelAction) + { + EnhancedInputComponent->BindAction(CancelAction, ETriggerEvent::Started, this, &AChildHoodCharacter::OnCancel); + } + if (SwitchInteractAction) + { + EnhancedInputComponent->BindAction(SwitchInteractAction, ETriggerEvent::Started, this, &AChildHoodCharacter::OnSwitchInteract); + } } else { @@ -90,8 +107,30 @@ void AChildHoodCharacter::Look(const FInputActionValue& Value) DoLook(LookAxisVector.X, LookAxisVector.Y); } +void AChildHoodCharacter::OnInteract(const FInputActionValue& Value) +{ + // v0.1 placeholder — interaction system will provide implementation + // Interaction system hooks in via blueprint or future C++ delegate +} + +void AChildHoodCharacter::OnCancel(const FInputActionValue& Value) +{ + // v0.1 placeholder — interaction system will provide implementation +} + +void AChildHoodCharacter::OnSwitchInteract(const FInputActionValue& Value) +{ + // v0.1 placeholder — interaction system will provide implementation +} + void AChildHoodCharacter::DoMove(float Right, float Forward) { + // P1: 交互中忽略移动输入 + if (bIsInteracting) + { + return; + } + if (GetController() != nullptr) { // find out which way is forward @@ -101,10 +140,10 @@ void AChildHoodCharacter::DoMove(float Right, float Forward) // get forward vector const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X); - // get right vector + // get right vector const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y); - // add movement + // add movement AddMovementInput(ForwardDirection, Forward); AddMovementInput(RightDirection, Right); } @@ -120,14 +159,18 @@ void AChildHoodCharacter::DoLook(float Yaw, float Pitch) } } -void AChildHoodCharacter::DoJumpStart() +void AChildHoodCharacter::SetInteracting(bool bValue) { - // signal the character to jump - Jump(); + bIsInteracting = bValue; } -void AChildHoodCharacter::DoJumpEnd() +bool AChildHoodCharacter::IsInteracting() const { - // signal the character to stop jumping - StopJumping(); + return bIsInteracting; +} + +bool AChildHoodCharacter::IsRunning() const +{ + return GetVelocity().SizeSquared() > 100.f // 速度 > 10 cm/s 阈值 + && GetCharacterMovement()->IsMovingOnGround(); } diff --git a/Source/ChildHood/ChildHoodCharacter.h b/Source/ChildHood/ChildHoodCharacter.h index 33f7414..59f53e2 100644 --- a/Source/ChildHood/ChildHoodCharacter.h +++ b/Source/ChildHood/ChildHoodCharacter.h @@ -30,12 +30,8 @@ class AChildHoodCharacter : public ACharacter /** Follow camera */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Components", meta = (AllowPrivateAccess = "true")) UCameraComponent* FollowCamera; - -protected: - /** Jump Input Action */ - UPROPERTY(EditAnywhere, Category="Input") - UInputAction* JumpAction; +protected: /** Move Input Action */ UPROPERTY(EditAnywhere, Category="Input") @@ -49,10 +45,25 @@ protected: UPROPERTY(EditAnywhere, Category="Input") UInputAction* MouseLookAction; + /** Interact Input Action (E key) — delegates to interaction system */ + UPROPERTY(EditAnywhere, Category="Input") + UInputAction* InteractAction; + + /** Cancel Input Action (ESC key) — delegates to interaction system */ + UPROPERTY(EditAnywhere, Category="Input") + UInputAction* CancelAction; + + /** Switch Interact Target Input Action (Tab / Mouse Wheel) — delegates to interaction system */ + UPROPERTY(EditAnywhere, Category="Input") + UInputAction* SwitchInteractAction; + + /** Whether the character is currently in an interaction */ + bool bIsInteracting = false; + public: /** Constructor */ - AChildHoodCharacter(); + AChildHoodCharacter(); protected: @@ -67,6 +78,15 @@ protected: /** Called for looking input */ void Look(const FInputActionValue& Value); + /** Called for interact input (E) — placeholder, delegates to interaction system */ + void OnInteract(const FInputActionValue& Value); + + /** Called for cancel input (ESC) — placeholder, delegates to interaction system */ + void OnCancel(const FInputActionValue& Value); + + /** Called for switch interact target input (Tab/Wheel) — placeholder, delegates to interaction system */ + void OnSwitchInteract(const FInputActionValue& Value); + public: /** Handles move inputs from either controls or UI interfaces */ @@ -77,13 +97,17 @@ public: UFUNCTION(BlueprintCallable, Category="Input") virtual void DoLook(float Yaw, float Pitch); - /** Handles jump pressed inputs from either controls or UI interfaces */ - UFUNCTION(BlueprintCallable, Category="Input") - virtual void DoJumpStart(); + /** Set interaction state — called by interaction system */ + UFUNCTION(BlueprintCallable, Category="Interaction") + void SetInteracting(bool bValue); - /** Handles jump pressed inputs from either controls or UI interfaces */ - UFUNCTION(BlueprintCallable, Category="Input") - virtual void DoJumpEnd(); + /** Query: is the character currently interacting? */ + UFUNCTION(BlueprintCallable, BlueprintPure, Category="Interaction") + bool IsInteracting() const; + + /** Query: is the character currently running (moving on ground)? */ + UFUNCTION(BlueprintCallable, BlueprintPure, Category="Interaction") + bool IsRunning() const; public: @@ -93,4 +117,3 @@ public: /** Returns FollowCamera subobject **/ FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; } }; - diff --git a/Source/ChildHood/ChildHoodPlayerController.cpp b/Source/ChildHood/ChildHoodPlayerController.cpp index cadaba8..83d008d 100644 --- a/Source/ChildHood/ChildHoodPlayerController.cpp +++ b/Source/ChildHood/ChildHoodPlayerController.cpp @@ -13,6 +13,19 @@ void AChildHoodPlayerController::BeginPlay() { Super::BeginPlay(); + // C3: 设置摄像机俯仰角限制(垂直旋转 +45°/-30°) + if (PlayerCameraManager) + { + PlayerCameraManager->ViewPitchMin = -30.0f; // 向下看最多 30° + PlayerCameraManager->ViewPitchMax = 45.0f; // 向上看最多 45° + } + + // C1: 初始俯角 -15°(摄像机默认略向下看向角色) + if (GetControlRotation().Pitch == 0.f) + { + SetControlRotation(FRotator(-15.0f, GetControlRotation().Yaw, GetControlRotation().Roll)); + } + // only spawn touch controls on local player controllers if (ShouldUseTouchControls() && IsLocalPlayerController()) {