Good day everyone,
Here’s the problem. I wanted to make a basic movement system where, the player by default can look around and the character moves relative to the direction of the camera/controller. So the character can run facing toward the camera by pressing S(backward) key. Close examples that come to mind are Metal Gear Solid V: Phantom Pain, Tomb Raider… etc. So what I did was to set the Mesh’s “bAbsoluteRotation” to true, so that it doesn’t rotate with the Camera. But I want it to rotate with the camera while aiming, thus I set it to false, in the event of a right click press, and then set it to true again on release, however it seemed that on release it snaps back to a default (0.0f,0.0f,0.0f) rotation. But when I took a closer look I saw that on release it actually stays on that rotation until a little bump to the mouse or until a W/A/S/D input when it snaps to said rotation. I don’t understand why it works this way, since the mouse input function should do nothing to the mesh’s rotation. But here are the code snips:
BaseCharacter.h
UCLASS()
class PROJECT_ATLAS_API ABaseCharacter : public ACharacter
{
GENERATED_BODY()
public:
ABaseCharacter();
UPROPERTY(EditDefaultsOnly, Category = Controller)
class APlayerController* CharacterController;
UPROPERTY(EditDefaultsOnly, Category = Camera)
class USpringArmComponent* CharacterSpringArm;
UPROPERTY(EditDefaultsOnly, Category = Camera)
class UCameraComponent* CharacterCamera;
//FUNCTIONS
void MoveForward(float argValue); //W__S (1.0__-1.0)
void MoveRight(float argValue); //D__A (1.0 __ -1.0)
void Turn(float argValue); //Mouse X (1.0)
void LookUp(float argValue); //Mouse Y (-1.0)
void Aim(); //RMB press
void ReleaseAim(); //RMB release
protected:
virtual void BeginPlay() override;
};
BaseCharacter.cpp
#include "Public/BaseCharacter.h"
#include "GameFramework/SpringArmComponent.h"
#include "GameFramework/PlayerController.h"
#include "Components/SkeletalMeshComponent.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
ABaseCharacter::ABaseCharacter()
{
PrimaryActorTick.bCanEverTick = true;
CharacterSpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("CharacterSpringArmText"));
CharacterSpringArm->SetupAttachment(RootComponent);
CharacterSpringArm->TargetArmLength = 150.0f;
CharacterSpringArm->bUsePawnControlRotation = true;
CharacterCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("CharacterCameraText"));
CharacterCamera->SetupAttachment(CharacterSpringArm, USpringArmComponent::SocketName);
}
// Called when the game starts or when spawned
void ABaseCharacter::BeginPlay()
{
Super::BeginPlay();
if (GetController())
{
CharacterController = dynamic_cast<APlayerController*>(GetController());
}
GetMesh()->bAbsoluteRotation = true;
}
// Called every frame
void ABaseCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void ABaseCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent->BindAxis("MoveForward", this, &ABaseCharacter::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &ABaseCharacter::MoveRight);
PlayerInputComponent->BindAxis("Turn", this, &ABaseCharacter::Turn);
PlayerInputComponent->BindAxis("LookUp", this, &ABaseCharacter::LookUp);
PlayerInputComponent->BindAction("Aim", IE_Pressed, this, &ABaseCharacter::Aim);
PlayerInputComponent->BindAction("Aim", IE_Released, this, &ABaseCharacter::ReleaseAim);
}
void ABaseCharacter::MoveForward(float argValue)
{
AddMovementInput(GetActorForwardVector()*argValue);
}
void ABaseCharacter::MoveRight(float argValue)
{
AddMovementInput(CharacterCamera->GetRightVector()*argValue);
}
void ABaseCharacter::Turn(float argValue)
{
if (CharacterController)
{
CharacterController->AddYawInput(argValue);
}
}
void ABaseCharacter::LookUp(float argValue)
{
if (CharacterController)
{
CharacterController->AddPitchInput(argValue);
}
}
void ABaseCharacter::Aim()
{
GetMesh()->bAbsoluteRotation = false;
bIsAiming = true;
}
void ABaseCharacter::ReleaseAim()
{
GetMesh()->bAbsoluteRotation = true;
bIsAiming = false;
}
Why does it snap back? How would I get it to stay? If there’s a better way I’d appreciate it.
Thanks for your time and have a good one.