Hi, Im getting stuck on official tutorial Adding FP camera Adding a First-Person Camera, Mesh, and Animation | Unreal Engine 5.6 Documentation | Epic Developer Community
At the end I have a strange result:
- My camera look in wrong direction by 90 degrees in yaw, changing rotation and position via C++ or editor has no effect, and i cant understand why. Seems like its simply ignored, but FOV works great. I can change the mesh rotation to the camera, but i think its a dirty fix
- Character have animation, but shadow of the character is static, I fixed it by setting animation to the original mesh. But i dont know is it good workaround
I’ll be glad if you help me figure it out, sorry for my English
StudyCharacter.h
#pragma once
#include "CoreMinimal.h"
#include "EnhancedInputComponent.h"
#include "Camera/CameraComponent.h"
#include "InputActionValue.h"
#include "EnhancedInputSubsystems.h"
#include "GameFramework/Character.h"
#include "StudyCharacter.generated.h"
class UInputMappingContext;
class UInputAction;
class UInputComponent;
class UAnimBlueprint;
class UInputMappingContext;
class UInputAction;
class UInputComponent;
UCLASS()
class STUDYGAME_API AStudyCharacter : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AStudyCharacter();
// First Person animations
UPROPERTY(EditAnywhere, Category = Animation)
UAnimBlueprint* FirstPersonDefaultAnim;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input)
TObjectPtr<UInputMappingContext> FirstPersonContext;
// Move Input Actions
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input)
TObjectPtr<UInputAction> MoveAction;
// Jump Input Actions
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input)
TObjectPtr<UInputAction> JumpAction;
// Look Input Actions
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input)
UInputAction* LookAction;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
UFUNCTION()
void Move(const FInputActionValue& Value);
// Handles Look Input
UFUNCTION()
void Look(const FInputActionValue& Value);
// First Person camera
UPROPERTY(VisibleAnywhere, Category = Camera)
UCameraComponent* FirstPersonCameraComponent;
// Offset for the first-person camera
UPROPERTY(EditAnywhere, Category = Camera)
FVector FirstPersonCameraOffset = FVector(2.8f, 5.9f, 0.0f);
// First-person primitives field of view
UPROPERTY(EditAnywhere, Category = Camera)
float FirstPersonFieldOfView = 70.0f;
// First-person primitives view scale
UPROPERTY(EditAnywhere, Category = Camera)
float FirstPersonScale = 0.6f;
// First-person mesh, visible only to the owning player
UPROPERTY(VisibleAnywhere, Category = Mesh)
USkeletalMeshComponent* FirstPersonMeshComponent;
};
StudyCharacter.cpp
#include "StudyCharacter.h"
// Sets default values
AStudyCharacter::AStudyCharacter()
{
// 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;
// Create a first person camera component
FirstPersonCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera"));
check(FirstPersonCameraComponent != nullptr);
// Create a first person mesh component for the owning player
FirstPersonMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("FirstPersonMesh"));
check(FirstPersonMeshComponent != nullptr);
// Attach the first person mesh to the skeletal mesh
FirstPersonMeshComponent->SetupAttachment(GetMesh());
// The first-person mesh is included in First Person rendering (use FirstPersonFieldofView and FirstPersonScale on this mesh)
FirstPersonMeshComponent->FirstPersonPrimitiveType = EFirstPersonPrimitiveType::FirstPerson;
// Only the owning player sees the first-person mesh
FirstPersonMeshComponent->SetOnlyOwnerSee(true);
// The owning player doesn't see the regular (third-person) body mesh, but it casts a shadow
GetMesh()->FirstPersonPrimitiveType = EFirstPersonPrimitiveType::WorldSpaceRepresentation;
// Set the first person mesh to not collide with other objects
FirstPersonMeshComponent->SetCollisionProfileName(FName("NoCollision"));
FirstPersonCameraComponent->SetupAttachment(FirstPersonMeshComponent, FName("head"));
// Position the camera slightly above the eyes and rotate it to behind the player's head
FirstPersonCameraComponent->SetRelativeLocationAndRotation(FirstPersonCameraOffset, FRotator(0.0f, 90.0f, -90.0f));
FirstPersonCameraComponent->bUsePawnControlRotation = true;
// Enable first-person rendering on the camera and set default FOV and scale values
FirstPersonCameraComponent->bEnableFirstPersonFieldOfView = true;
FirstPersonCameraComponent->bEnableFirstPersonScale = true;
FirstPersonCameraComponent->FirstPersonFieldOfView = FirstPersonFieldOfView;
FirstPersonCameraComponent->FirstPersonScale = FirstPersonScale;
}
// Called when the game starts or when spawned
void AStudyCharacter::BeginPlay()
{
Super::BeginPlay();
check(GEngine != nullptr);
// Get the player controller for this character
if (APlayerController* PlayerController = Cast<APlayerController>(Controller))
{
// Get the enhanced input local player subsystem and add a new input mapping context to it
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
{
Subsystem->AddMappingContext(FirstPersonContext, 0);
}
}
// Only the owning player sees the first person mesh.
FirstPersonMeshComponent->SetOnlyOwnerSee(true);
// The owning player doesn't see the regular (third-person) body mesh
GetMesh()->SetOwnerNoSee(true);
// Position the camera slightly above the eyes.
FirstPersonCameraComponent->SetRelativeLocation(FVector(2.8f, 5.9f, 0.0f));
// Set the animations on the first person mesh.
FirstPersonMeshComponent->SetAnimInstanceClass(FirstPersonDefaultAnim->GeneratedClass);
// FIX STATIC SHADOW BUG?
GetMesh()->SetAnimInstanceClass(FirstPersonDefaultAnim->GeneratedClass);
// Doesnt work
// FirstPersonCameraComponent->SetRelativeLocationAndRotation(FirstPersonCameraOffset, FRotator(0.0f, 180.0f, -90.0f));
// Display a debug message for five seconds.
// The -1 "Key" value argument prevents the message from being updated or refreshed.
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("We are using AStudyCharacter."));
}
// Called every frame
void AStudyCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void AStudyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent))
{
// Bind Look Actions
EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &AStudyCharacter::Look);
// Bind Movement Actions
EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AStudyCharacter::Move);
// Bind Jump Actions
EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Started, this, &ACharacter::Jump);
EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping);
}
}
void AStudyCharacter::Move(const FInputActionValue& Value)
{
// 2D Vector of movement values returned from the input action
const FVector2D MovementValue = Value.Get<FVector2D>();
// Check if the controller posessing this Actor is valid
if (Controller)
{
// Add left and right movement
const FVector Right = GetActorRightVector();
AddMovementInput(Right, MovementValue.X);
// Add forward and back movement
const FVector Forward = GetActorForwardVector();
AddMovementInput(Forward, MovementValue.Y);
}
}
void AStudyCharacter::Look(const FInputActionValue& Value)
{
const FVector2D LookAxisValue = Value.Get<FVector2D>();
if (Controller)
{
AddControllerYawInput(LookAxisValue.X);
AddControllerPitchInput(LookAxisValue.Y);
}
}