I created a project with Third Person template. I want to have reference to skeletal mesh in character class so I created new character. My problem is I have 2 Skeletal mesh in viewport when create child class of c++ class
AMyRPG_TutorialCharacter.h:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Components/TimelineComponent.h"
#include "GameFramework/Character.h"
#include "InputActionValue.h"
#include "Components/SkeletalMeshComponent.h"
#include "MotionWarpingComponent.h"
#include "Animation/AnimMontage.h"
#include "MyRPG_TutorialCharacter.generated.h"
class UTimelineComponent;
typedef void(*FunctionPointer)();
UCLASS()
class RPG_TUTORIAL_API AMyRPG_TutorialCharacter : public ACharacter
{
GENERATED_BODY()
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class USpringArmComponent* CameraBoom;
/** Follow camera */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class UCameraComponent* FollowCamera;
/** MappingContext */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
class UInputMappingContext* DefaultMappingContext;
/** Jump Input Action */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
class UInputAction* JumpAction;
/** Move Input Action */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
class UInputAction* MoveAction;
/** Look Input Action */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
class UInputAction* LookAction;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
class UInputAction* CrouchedAction;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
class UInputAction* AssasinAction;
public:
// Sets default values for this character's properties
AMyRPG_TutorialCharacter();
UFUNCTION()
void Crouch_JumpWrapper();
UPROPERTY(EditAnywhere, BlueprintReadOnly)
bool Crouched;
UPROPERTY(EditAnywhere, Category = "Timeline Cam Curve")
UCurveFloat* CrouchedCamCurve;
UFUNCTION(BlueprintCallable)
void Vault_C();
UFUNCTION(BlueprintCallable)
void VaultMotionWarp();
UPROPERTY(EditAnywhere, BlueprintReadWrite)
bool CanWrap;
UPROPERTY(EditDefaultsOnly)
USkeletalMeshComponent* CharacterMesh;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
UMotionWarpingComponent* MotionWarping;
UPROPERTY(EditAnywhere)
UAnimMontage* MontageToPlay;
protected:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FVector VaultStartPos;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FVector VaultMiddlePos;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FVector VaultLandPos;
/** Called for movement input */
void Move(const FInputActionValue& Value);
/** Called for looking input */
void Look(const FInputActionValue& Value);
void Crouch(const FInputActionValue& Value);
void Assasin(const FInputActionValue& Value);
UTimelineComponent* MainTimeline;
UFUNCTION()
void TimelineProgress(float Value);
protected:
// APawn interface
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// To add mapping context
virtual void BeginPlay();
public:
FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; }
};
AMyRPG_TutorialCharacter.cpp:
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyRPG_TutorialCharacter.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/InputComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "GameFramework/Controller.h"
#include "GameFramework/SpringArmComponent.h"
#include "EnhancedInputComponent.h"
#include "Components/TimelineComponent.h"
#include "EnhancedInputSubsystems.h"
#include "Kismet/KismetSystemLibrary.h"
#include "Components/SkeletalMeshComponent.h"
#include "MotionWarpingComponent.h"
#include "RootMotionModifier.h"
#include "Kismet/KismetMathLibrary.h"
// Sets default values
AMyRPG_TutorialCharacter::AMyRPG_TutorialCharacter()
{
// 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;
GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);
bUseControllerRotationPitch = false;
bUseControllerRotationYaw = false;
bUseControllerRotationRoll = false;
// Configure character movement
GetCharacterMovement()->bOrientRotationToMovement = true; // Character moves in the direction of input...
GetCharacterMovement()->RotationRate = FRotator(0.0f, 500.0f, 0.0f); // ...at this rotation rate
GetCharacterMovement()->JumpZVelocity = 700.f;
GetCharacterMovement()->AirControl = 0.35f;
GetCharacterMovement()->MaxWalkSpeed = 500.f;
GetCharacterMovement()->MinAnalogWalkSpeed = 20.f;
GetCharacterMovement()->BrakingDecelerationWalking = 2000.f;
CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
CameraBoom->SetupAttachment(RootComponent);
CameraBoom->TargetArmLength = 400.0f;
CameraBoom->bUsePawnControlRotation = true;
// Create a follow camera
FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName);
FollowCamera->bUsePawnControlRotation = false;
CharacterMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("CharacterMesh"));
CharacterMesh->SetupAttachment(GetCapsuleComponent(), CapsuleComponentName);
MainTimeline = CreateDefaultSubobject<UTimelineComponent>(TEXT("CamTimeline"));
}
// Called when the game starts or when spawned
void AMyRPG_TutorialCharacter::BeginPlay()
{
Super::BeginPlay();
if (APlayerController* PlayerController = Cast<APlayerController>(Controller))
{
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
{
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
}
}
// Called to bind functionality to input
void AMyRPG_TutorialCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent)) {
//Jumping
EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Started, this, &AMyRPG_TutorialCharacter::Crouch_JumpWrapper);
EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping);
//Moving
EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMyRPG_TutorialCharacter::Move);
//Looking
EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &AMyRPG_TutorialCharacter::Look);
EnhancedInputComponent->BindAction(CrouchedAction, ETriggerEvent::Started, this, &AMyRPG_TutorialCharacter::Crouch);
EnhancedInputComponent->BindAction(AssasinAction, ETriggerEvent::Started, this, &AMyRPG_TutorialCharacter::Assasin);
}
}
void AMyRPG_TutorialCharacter::Crouch_JumpWrapper()
{
if (Crouched) {
Crouch(1);
}
ACharacter::Jump();
}
void AMyRPG_TutorialCharacter::Move(const FInputActionValue& Value)
{
// input is a Vector2D
FVector2D MovementVector = Value.Get<FVector2D>();
if (Controller != nullptr)
{
// find out which way is forward
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
// get forward vector
const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
// get right vector
const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
// add movement
AddMovementInput(ForwardDirection, MovementVector.Y);
AddMovementInput(RightDirection, MovementVector.X);
}
}
void AMyRPG_TutorialCharacter::Look(const FInputActionValue& Value)
{
// input is a Vector2D
FVector2D LookAxisVector = Value.Get<FVector2D>();
if (Controller != nullptr)
{
// add yaw and pitch input to controller
AddControllerYawInput(LookAxisVector.X);
AddControllerPitchInput(LookAxisVector.Y);
}
}
void AMyRPG_TutorialCharacter::Crouch(const FInputActionValue& Value)
{
if (!Crouched) Crouched = true;
else Crouched = false;
FOnTimelineFloat CamMovementValue;
CamMovementValue.BindUFunction(this, FName("TimelineProgress"));
if (CrouchedCamCurve) {
MainTimeline->AddInterpFloat(CrouchedCamCurve, CamMovementValue);
}
if (Crouched) {
GetCharacterMovement()->MaxWalkSpeed = 350.0;
MainTimeline->PlayFromStart();
}
else {
GetCharacterMovement()->MaxWalkSpeed = 500.0;
MainTimeline->ReverseFromEnd();
}
}
void AMyRPG_TutorialCharacter::TimelineProgress(float Value)
{
CameraBoom->TargetArmLength = FMath::Lerp(400.0, 500.0, Value);
}
void AMyRPG_TutorialCharacter::Assasin(const FInputActionValue& Value)
{
}
void AMyRPG_TutorialCharacter::Vault_C()
{
FHitResult TraceResults;
TArray<AActor*, FDefaultAllocator> IgnoredActors;
for (int i = 0; i <= 2; i++) {
FVector TraceStart = GetActorLocation();
TraceStart.Z += i * 30;
FVector TraceEnd = GetActorForwardVector();
TraceEnd *= 180.0;
if (UKismetSystemLibrary::SphereTraceSingle(this, TraceStart, TraceEnd + TraceStart, 5.0, ETraceTypeQuery::TraceTypeQuery1, false, IgnoredActors, EDrawDebugTrace::ForDuration, TraceResults, true)) {
break;
}
}
FHitResult SubTraceResults, SubTraceResultsLand;
for (int j = 0; j <= 5; j++) {
FVector SubTraceStart = TraceResults.Location + FVector(0.0, 0.0, 100.0);
//GEngine->AddOnScreenDebugMessage(-1, 15.0, FColor::Black, FString::Printf(TEXT("X = %d"), TraceResults.Location.X));
//GEngine->AddOnScreenDebugMessage(-1, 15.0, FColor::Black, FString::Printf(TEXT("Y = %d"), TraceResults.Location.Y));
//GEngine->AddOnScreenDebugMessage(-1, 15.0, FColor::Black, FString::Printf(TEXT("Z = %d"), TraceResults.Location.Z));
FVector SubTraceEnd = GetActorForwardVector();
SubTraceEnd *= (j * 50);
if (UKismetSystemLibrary::SphereTraceSingle(this, SubTraceStart + SubTraceEnd, SubTraceStart + SubTraceEnd - FVector(0.0, 0.0, 100.0), 10.0, ETraceTypeQuery::TraceTypeQuery1, false, IgnoredActors, EDrawDebugTrace::ForDuration, SubTraceResults, true)) {
if (j == 0) {
VaultStartPos = SubTraceResults.Location;
DrawDebugSphere(GetWorld(), VaultStartPos, 10.0, 12, FColor::Purple, false, 10.0, 2.0);
}
VaultMiddlePos = SubTraceResults.Location;
DrawDebugSphere(GetWorld(), VaultMiddlePos, 10.0, 12, FColor::Yellow, false, 10.0, 2.0);
CanWrap = true;
}
else {
if (UKismetSystemLibrary::SphereTraceSingle(this,
SubTraceResults.TraceStart + (GetActorForwardVector() * 80.0),
(SubTraceResults.TraceStart + (GetActorForwardVector() * 80.0)) - FVector(0.0, 0.0, 1000.0),
10.0,
ETraceTypeQuery::TraceTypeQuery1,
false,
IgnoredActors,
EDrawDebugTrace::ForDuration,
SubTraceResultsLand,
true, FColor::Purple)) {
VaultLandPos = SubTraceResultsLand.Location;
break;
}
}
}
VaultMotionWarp();
}
void AMyRPG_TutorialCharacter::VaultMotionWarp()
{
if (CanWrap && VaultLandPos.Z >= CharacterMesh->K2_GetComponentLocation().Z - 50.0 && VaultLandPos.Z <= CharacterMesh->K2_GetComponentLocation().Z + 50.0) {
GetCharacterMovement()->SetMovementMode(EMovementMode::MOVE_Flying, 0);
SetActorEnableCollision(false);
MotionWarping->AddOrUpdateWarpTargetFromLocationAndRotation("VaultStart", VaultStartPos, GetActorRotation());
MotionWarping->AddOrUpdateWarpTargetFromLocationAndRotation("VaultMiddle", VaultMiddlePos, GetActorRotation());
MotionWarping->AddOrUpdateWarpTargetFromLocationAndRotation("VaultLand", VaultLandPos, GetActorRotation());
PlayAnimMontage(MontageToPlay, 1.0, NAME_None);
GetCharacterMovement()->SetMovementMode(EMovementMode::MOVE_Walking, 0);
SetActorEnableCollision(true);
CanWrap = false;
VaultLandPos = FVector(0.0, 0.0, 20000.0);
GEngine->AddOnScreenDebugMessage(-1, 15.0, FColor::Black, TEXT("Montage Played"));
}
}
As you can see I just copied code from default character because I thought that skeletal mesh is created in blueprint in default class but default skeletal mesh not disappeared