// Fill out your copyright notice in the Description page of Project Settings. #include "PlayerCharacter.h" #include "EnhancedInputSubsystems.h" #include "EnhancedInputComponent.h" #include "DrawDebugHelpers.h" #include "InputAction.h" #include "Components/CapsuleComponent.h" // Sets default values APlayerCharacter::APlayerCharacter() { // Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; CameraComponent = CreateDefaultSubobject(TEXT("FirstPersonCamera")); CameraComponent->SetupAttachment(GetCapsuleComponent()); CameraComponent->SetRelativeLocation(FVector(-10.f, 0.f, 80.f)); // Position the camera CameraComponent->bUsePawnControlRotation = true; GetCapsuleComponent()->InitCapsuleSize(40.0f, 90.0f); USkeletalMeshComponent* MeshComp = GetMesh(); check(MeshComp); MeshComp->SetRelativeRotation(FRotator(0.0f, -90.0f, 0.0f)); // Rotate mesh to be X forward since it is exported as Y forward. MeshComp->SetRelativeLocation(FVector(0.0f, 0.0f, -90.0f)); MeshComp->SetupAttachment(GetCapsuleComponent()); MeshComp->SetCollisionProfileName(TEXT("Mesh")); MeshComp->bCastDynamicShadow = false; MeshComp->CastShadow = false; BaseEyeHeight = 80.0f; CrouchedEyeHeight = 50.0f; } // Called when the game starts or when spawned void APlayerCharacter::BeginPlay() { Super::BeginPlay(); } // Called every frame void APlayerCharacter::Tick(float DeltaTime) { Super::Tick(DeltaTime); TObjectPtr world = GetWorld(); if (world != nullptr) { FHitResult HitResult; const FVector Start = GetActorLocation(); const FVector End = GetActorForwardVector() * 100 + Start; const FCollisionObjectQueryParams QueryParams(FCollisionObjectQueryParams::AllStaticObjects); DrawDebugLine(world, Start, End, FColor::Green, false, 1, 0, 1); world->LineTraceSingleByObjectType(HitResult, Start, End, QueryParams); if (HitResult.bBlockingHit) { if (GEngine != nullptr) { GEngine->AddOnScreenDebugMessage( -1, 1.f, FColor::Red, FString::Printf(TEXT("You are hitting: %s"), *HitResult.GetActor()->GetName() )); } } } } #pragma region Inputs // Called to bind functionality to input void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) { Super::SetupPlayerInputComponent(PlayerInputComponent); // Get the player controller APlayerController* PC = Cast(GetController()); // Get the local player subsystem UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem(PC->GetLocalPlayer()); // Clear out existing mapping, and add our mapping Subsystem->ClearAllMappings(); Subsystem->AddMappingContext(InputMapping, 0); // Get the EnhancedInputComponent UEnhancedInputComponent* PEI = Cast(PlayerInputComponent); // Bind the actions PEI->BindAction(IA_Move, ETriggerEvent::Triggered, this, &APlayerCharacter::Move); PEI->BindAction(IA_Look, ETriggerEvent::Triggered, this, &APlayerCharacter::Look); PEI->BindAction(IA_Jump, ETriggerEvent::Triggered, this, &APlayerCharacter::ActivateJump); } void APlayerCharacter::Move(const FInputActionValue& Value) { if (Controller != nullptr) { const FVector2D MoveValue = Value.Get(); const FRotator MovementRotation(0, Controller->GetControlRotation().Yaw, 0); // Forward/Backward direction if (MoveValue.Y != 0.f) { // Get forward vector const FVector Direction = MovementRotation.RotateVector(FVector::ForwardVector); AddMovementInput(Direction, MoveValue.Y); } // Right/Left direction if (MoveValue.X != 0.f) { // Get right vector const FVector Direction = MovementRotation.RotateVector(FVector::RightVector); AddMovementInput(Direction, MoveValue.X); } } } void APlayerCharacter::Look(const FInputActionValue& Value) { if (Controller != nullptr) { const FVector2D LookValue = Value.Get(); if (LookValue.X != 0.f) { AddControllerYawInput(LookValue.X); } if (LookValue.Y != 0.f) { AddControllerPitchInput(LookValue.Y); } } } void APlayerCharacter::ActivateJump(const FInputActionValue& Value) { if (Controller != nullptr) { const bool JumpValue = Value.Get(); if (JumpValue) { Jump(); } else { StopJumping(); } } } #pragma endregion