Equipping weapon/Inventory troubles based on shooter game

Hi guys I need some help to understand what’s wrong with this.

I used the shooter game as exemple to create my own character and create inventory.
This is a character for a multiplayer fps, so both first and third person view.

When my character equip a weapon, this is only working in first view, but not in third. The weapon seems to be not attached.

Also it seems the weapon are only added in inventory.
What do you think I am missing guys ?
Thanx for your help

Here is my source code:




// Fill out your copyright notice in the Description page of Project Settings.

#include "TOUnderFire.h"
#include "TOCharacter.h"
#include "UnrealNetwork.h"
#include "Player/BasePlayerState.h"

// Sets default values
ATOCharacter::ATOCharacter(const FObjectInitializer & ObjectInitializer)
{
	// Set size for collision capsule
	GetCapsuleComponent()->InitCapsuleSize(55.f, 96.0f);

	// set our turn rates for input
	BaseTurnRate = 45.f;
	BaseLookUpRate = 45.f;
	
	// Create a CameraComponent	
	FirstPersonCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera"));
	FirstPersonCameraComponent->SetupAttachment(GetCapsuleComponent());
	//FirstPersonCameraComponent->RelativeLocation = FVector(-39.56f, 1.75f, 64.f); // Position the camera
	FirstPersonCameraComponent->bUsePawnControlRotation = true;
	
	// Create a mesh component that will be used when being viewed from a '1st person' view (when controlling this pawn)
	Mesh1P = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("CharacterMesh1P"));
	Mesh1P->SetOnlyOwnerSee(true);
	Mesh1P->SetupAttachment(GetCapsuleComponent());
	Mesh1P->bCastDynamicShadow = false;
	Mesh1P->CastShadow = false;

	//Mesh1P->RelativeRotation = FRotator(1.9f, -19.19f, -160.f);
	//Mesh1P->RelativeLocation = FVector(-0.5f, -4.4f, -155.7f);

	/*// Create a gun mesh component
	FP_Gun = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("FP_Gun"));
	FP_Gun->SetOnlyOwnerSee(true);			// only the owning player will see this mesh
	FP_Gun->bCastDynamicShadow = false;
	FP_Gun->CastShadow = false;
	// FP_Gun->SetupAttachment(Mesh1P, TEXT("GripPoint"));
	FP_Gun->SetupAttachment(RootComponent);


	// Create a gun mesh component for 3rdPersonn
	TP_Gun = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("TP_Gun"));
	TP_Gun-> SetOnlyOwnerSee(false);// only the others player will see this mesh
	TP_Gun->bCastDynamicShadow = true;
	TP_Gun->CastShadow = true;
	// FP_Gun->SetupAttachment(Mesh1P, TEXT("GripPoint"));
	TP_Gun->SetupAttachment(GetMesh());
	*/
	FP_MuzzleLocation = CreateDefaultSubobject<USceneComponent>(TEXT("MuzzleLocation"));
	//FP_MuzzleLocation->SetupAttachment(FP_Gun);
	FP_MuzzleLocation->SetRelativeLocation(FVector(0.2f, 48.4f, -10.6f));

	
	
	HealthMax = 100;

	
}

void ATOCharacter::PostInitializeComponents()
{
	Super::PostInitializeComponents();

	if (Role == ROLE_Authority)
	{
		Health = HealthMax;
		SpawnDefaultInventory();
	}

	// set initial mesh visibility (3rd person view)
	UpdatePawnMeshes();

	// create material instance for setting team colors (3rd person view)
	/*for (int32 iMat = 0; iMat < GetMesh()->GetNumMaterials(); iMat++)
	{
		MeshMIDs.Add(GetMesh()->CreateAndSetMaterialInstanceDynamic(iMat));
	}*/

	// play respawn effects
	if (GetNetMode() != NM_DedicatedServer)
	{
		if (RespawnFX)
		{
			UGameplayStatics::SpawnEmitterAtLocation(this, RespawnFX, GetActorLocation(), GetActorRotation());
		}

		if (RespawnSound)
		{
			UGameplayStatics::PlaySoundAtLocation(this, RespawnSound, GetActorLocation());
		}
	}
}


void ATOCharacter::Tick(float DeltaSeconds)
{
	Super::Tick(DeltaSeconds);


	

	
}


void ATOCharacter::Destroyed()
{
	Super::Destroyed();
	DestroyInventory();
}

void ATOCharacter::BeginPlay()
{
	// Call the base class  
	Super::BeginPlay();

	//Attach gun mesh component to Skeleton, doing it here because the skeleton is not yet created in the constructor
	//FP_Gun->AttachToComponent(Mesh1P, FAttachmentTransformRules(EAttachmentRule::SnapToTarget, true), TEXT("WeaponSocket"));
	Mesh1P->SetHiddenInGame(false, true);

	//TP_Gun->AttachToComponent(GetMesh(), FAttachmentTransformRules(EAttachmentRule::SnapToTarget, true), TEXT("WeaponSocket"));
	GetMesh()->SetHiddenInGame(false, true);
	Reset();
}




//////////////////////////////////////////////////////////////////////////////////////////
//Mov & Inputs


void ATOCharacter::MoveForward(float Value)
{
	if (Value != 0.0f)
	{
		// add movement in that direction
		AddMovementInput(GetActorForwardVector(), Value);
	}
}

void ATOCharacter::MoveRight(float Value)
{
	if (Value != 0.0f)
	{
		// add movement in that direction
		AddMovementInput(GetActorRightVector(), Value);
	}
}

void ATOCharacter::TurnAtRate(float Rate)
{
	// calculate delta for this frame from the rate information
	AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds());
}

void ATOCharacter::LookUpAtRate(float Rate)
{
	// calculate delta for this frame from the rate information
	AddControllerPitchInput(Rate * BaseLookUpRate * GetWorld()->GetDeltaSeconds());
}






// Called to bind functionality to input
void ATOCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);
	// set up gameplay key bindings
	check(PlayerInputComponent);

	PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
	PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);

	PlayerInputComponent->BindAxis("MoveForward", this, &ATOCharacter::MoveForward);
	PlayerInputComponent->BindAxis("MoveRight", this, &ATOCharacter::MoveRight);


	PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
	PlayerInputComponent->BindAxis("TurnRate", this, &ATOCharacter::TurnAtRate);
	PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
	PlayerInputComponent->BindAxis("LookUpRate", this, &ATOCharacter::LookUpAtRate);


	PlayerInputComponent->BindAction("NextWeapon", IE_Pressed, this, &ATOCharacter::OnNextWeapon);
	PlayerInputComponent->BindAction("PrevWeapon", IE_Pressed, this, &ATOCharacter::OnPrevWeapon);

}


//////////////////////////////////////////////////////////////////////////////
//


void ATOCharacter::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);

	// only to local owner: weapon change requests are locally instigated, other clients don't need it
	DOREPLIFETIME_CONDITION(ATOCharacter, Inventory, COND_OwnerOnly);



	// everyone

	DOREPLIFETIME(ATOCharacter, Health);

}

void ATOCharacter::Reset()
{
	Health = HealthMax;
	DamageInfoArray.Empty();

	
		
}

void ATOCharacter::OnRep_CurrentWeapon(AItems* LastWeapon)
{
	SetCurrentWeapon(CurrentWeapon, LastWeapon);
}



ETeam_Enum ATOCharacter::GetTeam() const
{
	ABasePlayerState * PS = Cast<ABasePlayerState>(PlayerState);
	if (PS)
	{
		return PS->GetTeam();
	}

	return ETeam_Enum::None;
}


//////////////////////////////////////////////////////////////////////////
// Meshes

void ATOCharacter::UpdatePawnMeshes()
{
	bool const bFirstPerson = IsFirstPerson();

	Mesh1P->MeshComponentUpdateFlag = !bFirstPerson ? EMeshComponentUpdateFlag::OnlyTickPoseWhenRendered : EMeshComponentUpdateFlag::AlwaysTickPoseAndRefreshBones;
	Mesh1P->SetOwnerNoSee(!bFirstPerson);

	GetMesh()->MeshComponentUpdateFlag = bFirstPerson ? EMeshComponentUpdateFlag::OnlyTickPoseWhenRendered : EMeshComponentUpdateFlag::AlwaysTickPoseAndRefreshBones;
	GetMesh()->SetOwnerNoSee(bFirstPerson);
}



//////////////////////////////////////////////////////////
//Inventory

void ATOCharacter::AddWeapon(AItems* Weapon)
{
	Weapon->OnEnterInventory(this);
	Inventory.AddUnique(Weapon);

	/*if (Weapon && Role == ROLE_Authority)
	{
		Weapon->OnEnterInventory(this);
		Inventory.AddUnique(Weapon);
	}
	else ServerAddWeapon(Weapon);*/
}

bool ATOCharacter::ServerAddWeapon_Validate(AItems* Weapon)
{
	return true;
}

void ATOCharacter::ServerAddWeapon_Implementation(AItems* Weapon)
{
	AddWeapon(Weapon);
}



void ATOCharacter::RemoveWeapon(AItems* Weapon)
{
	if (Weapon && Role == ROLE_Authority)
	{
		Weapon->OnLeaveInventory();
		Inventory.RemoveSingle(Weapon);
	}
}


void ATOCharacter::SpawnDefaultInventory()
{
	if (Role < ROLE_Authority)
	{
		return;
	}

	int32 NumWeaponClasses = DefaultInventoryClasses.Num();
	for (int32 i = 0; i < NumWeaponClasses; i++)
	{
		if (DefaultInventoryClasses*)
		{
			FActorSpawnParameters SpawnInfo;
			SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
			AItems* NewWeapon = GetWorld()->SpawnActor<AItems>(DefaultInventoryClasses*, SpawnInfo);
			AddWeapon(NewWeapon);
		}
	}

	// equip first weapon in inventory
	if (Inventory.Num() > 0)
	{
		EquipWeapon(Inventory[0]);
	}
}




void ATOCharacter::EquipWeapon(AItems* Weapon)
{
	
	if (Weapon)
	{
		if (Role == ROLE_Authority)
		{
			SetCurrentWeapon(Weapon, CurrentWeapon);
		}
		else
		{
			ServerEquipWeapon(Weapon);
		}
	}
}


bool ATOCharacter::ServerEquipWeapon_Validate(AItems* Weapon)
{
	return true;
}

void ATOCharacter::ServerEquipWeapon_Implementation(AItems* Weapon)
{
	EquipWeapon(Weapon);
}


void ATOCharacter::DestroyInventory()
{
	if (Role < ROLE_Authority)
	{
		return;
	}

	// remove all weapons from inventory and destroy them
	for (int32 i = Inventory.Num() - 1; i >= 0; i--)
	{
		AItems* Weapon = Inventory*;
		if (Weapon)
		{
			RemoveWeapon(Weapon);
			Weapon->Destroy();
		}
	}
}


void ATOCharacter::SetCurrentWeapon(AItems* NewWeapon, AItems* LastWeapon)
{
	
	
	AItems* LocalLastWeapon = NULL;

	if (LastWeapon != NULL)
	{
		LocalLastWeapon = LastWeapon;
	}
	else if (NewWeapon != CurrentWeapon)
	{
		LocalLastWeapon = CurrentWeapon;
	}

	// unequip previous
	if (LocalLastWeapon)
	{
		LocalLastWeapon->OnUnEquip();
	}

	CurrentWeapon = NewWeapon;

	// equip new one
	if (NewWeapon)
	{
		NewWeapon->SetOwningPawn(this);	// Make sure weapon's MyPawn is pointing back to us. During replication, we can't guarantee APawn::CurrentWeapon will rep after AWeapon::MyPawn!

		NewWeapon->OnEquip(LastWeapon);
	}
}



void ATOCharacter::OnNextWeapon()
{
	ABasePlayerController* MyPC = Cast<ABasePlayerController>(Controller);
	if (MyPC )
	{
		if (Inventory.Num() >= 2 && (CurrentWeapon == NULL || CurrentWeapon->GetCurrentState() != EWeaponState::Equipping))
		{
			const int32 CurrentWeaponIdx = Inventory.IndexOfByKey(CurrentWeapon);
			AItems* NextWeapon = Inventory(CurrentWeaponIdx + 1) % Inventory.Num()];
			EquipWeapon(NextWeapon);
		}
	}
	
}

void ATOCharacter::OnPrevWeapon()
{
	ABasePlayerController* MyPC = Cast<ABasePlayerController>(Controller);
	if (MyPC )
	{
		if (Inventory.Num() >= 2 && (CurrentWeapon == NULL || CurrentWeapon->GetCurrentState() != EWeaponState::Equipping))
		{
			const int32 CurrentWeaponIdx = Inventory.IndexOfByKey(CurrentWeapon);
			AItems* PrevWeapon = Inventory(CurrentWeaponIdx - 1 + Inventory.Num()) % Inventory.Num()];
			
			EquipWeapon(PrevWeapon);
		}
	}
}


void ATOCharacter::CanAddItem_Implementation(class AItems* ItemChecked)
{
	
}
////////////////////////////////////////////////////

const TArray<FDamageInfo> & ATOCharacter::GetDamageInfoArray() const
{
	return DamageInfoArray;
}






FName ATOCharacter::GetWeaponAttachPoint() const
{
	return WeaponAttachPoint;
}

USkeletalMeshComponent* ATOCharacter::GetSpecifcPawnMesh(bool WantFirstPerson) const
{
	return WantFirstPerson == true ? Mesh1P : GetMesh();
}

USkeletalMeshComponent* ATOCharacter::GetPawnMesh() const
{
	return IsFirstPerson() ? Mesh1P : GetMesh();
}


bool ATOCharacter::IsFirstPerson() const
{
	return IsAlive() && Controller && Controller->IsLocalPlayerController();
}



bool ATOCharacter::IsAlive() const
{
	return Health > 0;
}




FRotator ATOCharacter::GetAimOffsets() const
{
	const FVector AimDirWS = GetBaseAimRotation().Vector();
	const FVector AimDirLS = ActorToWorld().InverseTransformVectorNoScale(AimDirWS);
	const FRotator AimRotLS = AimDirLS.Rotation();

	return AimRotLS;
}










// Fill out your copyright notice in the Description page of Project Settings.

#include "TOUnderFire.h"
#include "Items.h"
#include "UnrealNetwork.h"
#include "Player/TOCharacter.h"


// Sets default values
AItems::AItems(const FObjectInitializer & ObjectInitializer)
	: Super(ObjectInitializer)
{
	ItemMesh = ObjectInitializer.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("WeaponMesh1P"));
	ItemMesh->MeshComponentUpdateFlag = EMeshComponentUpdateFlag::OnlyTickPoseWhenRendered;
	ItemMesh->bReceivesDecals = false;
	ItemMesh->CastShadow = false;
	ItemMesh->SetCollisionObjectType(ECC_WorldDynamic);
	ItemMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	ItemMesh->SetCollisionResponseToAllChannels(ECR_Ignore);
	RootComponent = ItemMesh;


	ItemMesh3P = ObjectInitializer.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("WeaponMesh3P"));
	ItemMesh3P->MeshComponentUpdateFlag = EMeshComponentUpdateFlag::OnlyTickPoseWhenRendered;
	ItemMesh3P->bReceivesDecals = false;
	ItemMesh3P->CastShadow = true;
	ItemMesh3P->SetCollisionObjectType(ECC_WorldDynamic);
	ItemMesh3P->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	ItemMesh3P->SetCollisionResponseToAllChannels(ECR_Ignore);
	//ItemMesh3P->SetCollisionResponseToChannel(COLLISION_WEAPON, ECR_Block);
	ItemMesh3P->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block);
	//ItemMesh3P->SetCollisionResponseToChannel(COLLISION_PROJECTILE, ECR_Block);
	ItemMesh3P->SetupAttachment(ItemMesh);
	
	CanbePickUp = false;

	ItemSlot = EItemSlotEnum::None; 

 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	 ItemName = "";
	 CostToPurchase = 0;
	 NumMaxItem = 1;

	 bIsEquipped = false;
	 bPendingReload = false;
	 bPendingEquip = false;
	 bReplicates = true;
	 CurrentState = EWeaponState::Idle;
}


void AItems::PostInitializeComponents()
{
	Super::PostInitializeComponents();

	/*if (WeaponConfig.InitialClips > 0)
	{
		CurrentAmmoInClip = WeaponConfig.AmmoPerClip;
		CurrentAmmo = WeaponConfig.AmmoPerClip * WeaponConfig.InitialClips;
	}*/

	DetachMeshFromPawn();
}


// Called when the game starts or when spawned
void AItems::BeginPlay()
{
	Super::BeginPlay();
	
}

void AItems::Reset()
{
	Super::Reset();

}

// Called every frame
void AItems::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}







void AItems::OnRep_Instigator()
{
	Super::OnRep_Instigator();

	
}

bool AItems::CanBePickedUp() const
{
	return !Instigator;
}

bool AItems::CanBeDropped() const
{
	return true;
}



void AItems::AttachMeshToPawn()
{
	if (MyPawn)
	{
		// Remove and hide both first and third person meshes
		DetachMeshFromPawn();

		// OnATTach remplace provisoirement la suite de ce code, pour pouvoir 
		//l'implementer par blueprint et debugger
		//OnAttach();
		

		// For locally controller players we attach both weapons and let the bOnlyOwnerSee, bOwnerNoSee flags deal with visibility.
		FName AttachPoint = MyPawn->GetWeaponAttachPoint();
		if (MyPawn->IsLocallyControlled() == true)
		{
			USkeletalMeshComponent* PawnMesh1p = MyPawn->GetSpecifcPawnMesh(true);
			USkeletalMeshComponent* PawnMesh3p = MyPawn->GetSpecifcPawnMesh(false);
			ItemMesh->SetHiddenInGame(false);
			ItemMesh3P->SetHiddenInGame(false);
			ItemMesh->AttachToComponent(PawnMesh1p, FAttachmentTransformRules::KeepRelativeTransform, AttachPoint);
			ItemMesh3P->AttachToComponent(PawnMesh3p, FAttachmentTransformRules::KeepRelativeTransform, AttachPoint);
			
		}
		else
		{
			USkeletalMeshComponent* UseWeaponMesh = GetWeaponMesh();
			USkeletalMeshComponent* UsePawnMesh = MyPawn->GetPawnMesh();
			UseWeaponMesh->AttachToComponent(UsePawnMesh, FAttachmentTransformRules::KeepRelativeTransform, AttachPoint);
			UseWeaponMesh->SetHiddenInGame(false);
		}
	}
	
}

void AItems::OnAttach_Implementation()
{

}

void AItems::DetachMeshFromPawn()
{
	ItemMesh->DetachFromComponent(FDetachmentTransformRules::KeepRelativeTransform);
	ItemMesh->SetHiddenInGame(true);

	ItemMesh3P->DetachFromComponent(FDetachmentTransformRules::KeepRelativeTransform);
	ItemMesh3P->SetHiddenInGame(true);
}


USkeletalMeshComponent* AItems::GetWeaponMesh() const
{
	return (MyPawn != NULL && MyPawn->IsFirstPerson()) ? ItemMesh : ItemMesh3P;
}


//////////////////////////////////////////////////////////////////////////
// Replication & effects

void AItems::OnRep_MyPawn()
{
	if (MyPawn)
	{
		OnEnterInventory(MyPawn);
	}
	else
	{
		OnLeaveInventory();
	}
}

void AItems::OnEnterInventory(ATOCharacter* NewOwner)
{
	SetOwningPawn(NewOwner);
}


void AItems::OnLeaveInventory()
{
	if (Role == ROLE_Authority)
	{
		SetOwningPawn(NULL);
	}

	if (IsAttachedToPawn())
	{
		OnUnEquip();
	}
}

bool AItems::IsAttachedToPawn() const
{
	return bIsEquipped || bPendingEquip;
}


 void AItems::SetOwningPawn(ATOCharacter* NewOwner)
{
	if (MyPawn != NewOwner)
	{
		Instigator = NewOwner;
		MyPawn = NewOwner;
		// net owner for RPC calls
		SetOwner(NewOwner);
	}
}

 //////////////////////////////////////////////////////////////////////////
 // Inventory

 void AItems::OnEquip(const AItems* LastWeapon)
 {
	
	
	 AttachMeshToPawn();

	 bPendingEquip = true;
	 DetermineWeaponState();

	 // Only play animation if last weapon is valid
	if (LastWeapon)
	 {
		  float Duration = PlayWeaponAnimation(EquipAnim);
		 if (Duration <= 0.0f)
		 {
			 // failsafe
			 Duration = 0.5f;
		 }
		 EquipStartedTime = GetWorld()->GetTimeSeconds();
		 EquipDuration = Duration;

		 GetWorldTimerManager().SetTimer(TimerHandle_OnEquipFinished, this, &AItems::OnEquipFinished, Duration, false);
	
	}
	 else
	 {
		 OnEquipFinished();
	 }
	 
	 if (MyPawn && MyPawn->IsLocallyControlled())
	 {
		 PlayWeaponSound(EquipSound);
	 }
 }

 void AItems::OnEquipFinished()
 {
	 AttachMeshToPawn();

	 bIsEquipped = true;
	 bPendingEquip = false;

	 // Determine the state so that the can reload checks will work
	 DetermineWeaponState();

	
 }

void AItems::OnUnEquip()
{
	DetachMeshFromPawn();
	bIsEquipped = false;
	/*StopFire();

	if (bPendingReload)
	{
		StopWeaponAnimation(ReloadAnim);
		bPendingReload = false;

		GetWorldTimerManager().ClearTimer(TimerHandle_StopReload);
		GetWorldTimerManager().ClearTimer(TimerHandle_ReloadWeapon);
	}*/

	if (bPendingEquip)
	{
		//StopWeaponAnimation(EquipAnim);
		bPendingEquip = false;

		GetWorldTimerManager().ClearTimer(TimerHandle_OnEquipFinished);
	}

	DetermineWeaponState();
}



void AItems::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);

	DOREPLIFETIME(AItems, MyPawn);

}

UAudioComponent* AItems::PlayWeaponSound(USoundCue* Sound)
{
	UAudioComponent* AC = NULL;
	if (Sound && MyPawn)
	{
		AC = UGameplayStatics::SpawnSoundAttached(Sound, MyPawn->GetRootComponent());
	}

	return AC;
}


void AItems::DetermineWeaponState()
{
	EWeaponState::Type NewState = EWeaponState::Idle;

	if (bIsEquipped)
	{
		if (bPendingReload)
		{
			if (CanReload() == false)
			{
				NewState = CurrentState;
			}
			else
			{
				NewState = EWeaponState::Reloading;
			}
		}
		else if ((bPendingReload == false) && (bWantsToFire == true) && (CanFire() == true))
		{
			NewState = EWeaponState::Firing;
		}
	}
	else if (bPendingEquip)
	{
		NewState = EWeaponState::Equipping;
	}

	SetWeaponState(NewState);
}


void AItems::SetWeaponState(EWeaponState::Type NewState)
{
	const EWeaponState::Type PrevState = CurrentState;
	/*
	if (PrevState == EWeaponState::Firing && NewState != EWeaponState::Firing)
	{
		OnBurstFinished();
	}

	CurrentState = NewState;

	if (PrevState != EWeaponState::Firing && NewState == EWeaponState::Firing)
	{
		OnBurstStarted();
	}*/
}

EWeaponState::Type AItems::GetCurrentState() const
{
	return CurrentState;
}

bool AItems::CanFire() const
{
//	return IsAlive();
	return true;
}

void AItems::OnRep_Reload()
{
	/*if (bPendingReload)
	{
		StartReload(true);
	}
	else
	{
		StopReload();
	}*/
}

bool AItems::CanReload() const
{
	return true;
}


float AItems::PlayWeaponAnimation(const FWeaponAnim& Animation)
{
	float Duration = 0.0f;
	if (MyPawn)
	{
		UAnimMontage* UseAnim = MyPawn->IsFirstPerson() ? Animation.Pawn1P : Animation.Pawn3P;
		if (UseAnim)
		{
			Duration = MyPawn->PlayAnimMontage(UseAnim);
		}
	}

	return Duration;
}


void AItems::MeshAttash_Implementation()
{
// Fill out your copyright notice in the Description page of Project Settings.

#include "TOUnderFire.h"
#include "Items.h"
#include "UnrealNetwork.h"
#include "Player/TOCharacter.h"


// Sets default values
AItems::AItems(const FObjectInitializer & ObjectInitializer)
	: Super(ObjectInitializer)
{
	ItemMesh = ObjectInitializer.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("WeaponMesh1P"));
	ItemMesh->MeshComponentUpdateFlag = EMeshComponentUpdateFlag::OnlyTickPoseWhenRendered;
	ItemMesh->bReceivesDecals = false;
	ItemMesh->CastShadow = false;
	ItemMesh->SetCollisionObjectType(ECC_WorldDynamic);
	ItemMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	ItemMesh->SetCollisionResponseToAllChannels(ECR_Ignore);
	RootComponent = ItemMesh;


	ItemMesh3P = ObjectInitializer.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("WeaponMesh3P"));
	ItemMesh3P->MeshComponentUpdateFlag = EMeshComponentUpdateFlag::OnlyTickPoseWhenRendered;
	ItemMesh3P->bReceivesDecals = false;
	ItemMesh3P->CastShadow = true;
	ItemMesh3P->SetCollisionObjectType(ECC_WorldDynamic);
	ItemMesh3P->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	ItemMesh3P->SetCollisionResponseToAllChannels(ECR_Ignore);
	//ItemMesh3P->SetCollisionResponseToChannel(COLLISION_WEAPON, ECR_Block);
	ItemMesh3P->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block);
	//ItemMesh3P->SetCollisionResponseToChannel(COLLISION_PROJECTILE, ECR_Block);
	ItemMesh3P->SetupAttachment(ItemMesh);
	
	CanbePickUp = false;

	ItemSlot = EItemSlotEnum::None; 

 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	 ItemName = "";
	 CostToPurchase = 0;
	 NumMaxItem = 1;

	 bIsEquipped = false;
	 bPendingReload = false;
	 bPendingEquip = false;
	 bReplicates = true;
	 CurrentState = EWeaponState::Idle;
}


void AItems::PostInitializeComponents()
{
	Super::PostInitializeComponents();

	/*if (WeaponConfig.InitialClips > 0)
	{
		CurrentAmmoInClip = WeaponConfig.AmmoPerClip;
		CurrentAmmo = WeaponConfig.AmmoPerClip * WeaponConfig.InitialClips;
	}*/

	DetachMeshFromPawn();
}


// Called when the game starts or when spawned
void AItems::BeginPlay()
{
	Super::BeginPlay();
	
}

void AItems::Reset()
{
	Super::Reset();

}

// Called every frame
void AItems::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}







void AItems::OnRep_Instigator()
{
	Super::OnRep_Instigator();

	
}

bool AItems::CanBePickedUp() const
{
	return !Instigator;
}

bool AItems::CanBeDropped() const
{
	return true;
}



void AItems::AttachMeshToPawn()
{
	if (MyPawn)
	{
		// Remove and hide both first and third person meshes
		DetachMeshFromPawn();

		// OnATTach remplace provisoirement la suite de ce code, pour pouvoir 
		//l'implementer par blueprint et debugger
		//OnAttach();
		

		// For locally controller players we attach both weapons and let the bOnlyOwnerSee, bOwnerNoSee flags deal with visibility.
		FName AttachPoint = MyPawn->GetWeaponAttachPoint();
		if (MyPawn->IsLocallyControlled() == true)
		{
			USkeletalMeshComponent* PawnMesh1p = MyPawn->GetSpecifcPawnMesh(true);
			USkeletalMeshComponent* PawnMesh3p = MyPawn->GetSpecifcPawnMesh(false);
			ItemMesh->SetHiddenInGame(false);
			ItemMesh3P->SetHiddenInGame(false);
			ItemMesh->AttachToComponent(PawnMesh1p, FAttachmentTransformRules::KeepRelativeTransform, AttachPoint);
			ItemMesh3P->AttachToComponent(PawnMesh3p, FAttachmentTransformRules::KeepRelativeTransform, AttachPoint);
			
		}
		else
		{
			USkeletalMeshComponent* UseWeaponMesh = GetWeaponMesh();
			USkeletalMeshComponent* UsePawnMesh = MyPawn->GetPawnMesh();
			UseWeaponMesh->AttachToComponent(UsePawnMesh, FAttachmentTransformRules::KeepRelativeTransform, AttachPoint);
			UseWeaponMesh->SetHiddenInGame(false);
		}
	}
	
}

void AItems::OnAttach_Implementation()
{

}

void AItems::DetachMeshFromPawn()
{
	ItemMesh->DetachFromComponent(FDetachmentTransformRules::KeepRelativeTransform);
	ItemMesh->SetHiddenInGame(true);

	ItemMesh3P->DetachFromComponent(FDetachmentTransformRules::KeepRelativeTransform);
	ItemMesh3P->SetHiddenInGame(true);
}


USkeletalMeshComponent* AItems::GetWeaponMesh() const
{
	return (MyPawn != NULL && MyPawn->IsFirstPerson()) ? ItemMesh : ItemMesh3P;
}


//////////////////////////////////////////////////////////////////////////
// Replication & effects

void AItems::OnRep_MyPawn()
{
	if (MyPawn)
	{
		OnEnterInventory(MyPawn);
	}
	else
	{
		OnLeaveInventory();
	}
}

void AItems::OnEnterInventory(ATOCharacter* NewOwner)
{
	SetOwningPawn(NewOwner);
}


void AItems::OnLeaveInventory()
{
	if (Role == ROLE_Authority)
	{
		SetOwningPawn(NULL);
	}

	if (IsAttachedToPawn())
	{
		OnUnEquip();
	}
}

bool AItems::IsAttachedToPawn() const
{
	return bIsEquipped || bPendingEquip;
}


 void AItems::SetOwningPawn(ATOCharacter* NewOwner)
{
	if (MyPawn != NewOwner)
	{
		Instigator = NewOwner;
		MyPawn = NewOwner;
		// net owner for RPC calls
		SetOwner(NewOwner);
	}
}

 //////////////////////////////////////////////////////////////////////////
 // Inventory

 void AItems::OnEquip(const AItems* LastWeapon)
 {
	
	
	 AttachMeshToPawn();

	 bPendingEquip = true;
	 DetermineWeaponState();

	 // Only play animation if last weapon is valid
	if (LastWeapon)
	 {
		  float Duration = PlayWeaponAnimation(EquipAnim);
		 if (Duration <= 0.0f)
		 {
			 // failsafe
			 Duration = 0.5f;
		 }
		 EquipStartedTime = GetWorld()->GetTimeSeconds();
		 EquipDuration = Duration;

		 GetWorldTimerManager().SetTimer(TimerHandle_OnEquipFinished, this, &AItems::OnEquipFinished, Duration, false);
	
	}
	 else
	 {
		 OnEquipFinished();
	 }
	 
	 if (MyPawn && MyPawn->IsLocallyControlled())
	 {
		 PlayWeaponSound(EquipSound);
	 }
 }

 void AItems::OnEquipFinished()
 {
	 AttachMeshToPawn();

	 bIsEquipped = true;
	 bPendingEquip = false;

	 // Determine the state so that the can reload checks will work
	 DetermineWeaponState();

	
 }

void AItems::OnUnEquip()
{
	DetachMeshFromPawn();
	bIsEquipped = false;
	/*StopFire();

	if (bPendingReload)
	{
		StopWeaponAnimation(ReloadAnim);
		bPendingReload = false;

		GetWorldTimerManager().ClearTimer(TimerHandle_StopReload);
		GetWorldTimerManager().ClearTimer(TimerHandle_ReloadWeapon);
	}*/

	if (bPendingEquip)
	{
		//StopWeaponAnimation(EquipAnim);
		bPendingEquip = false;

		GetWorldTimerManager().ClearTimer(TimerHandle_OnEquipFinished);
	}

	DetermineWeaponState();
}



void AItems::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);

	DOREPLIFETIME(AItems, MyPawn);

}

UAudioComponent* AItems::PlayWeaponSound(USoundCue* Sound)
{
	UAudioComponent* AC = NULL;
	if (Sound && MyPawn)
	{
		AC = UGameplayStatics::SpawnSoundAttached(Sound, MyPawn->GetRootComponent());
	}

	return AC;
}


void AItems::DetermineWeaponState()
{
	EWeaponState::Type NewState = EWeaponState::Idle;

	if (bIsEquipped)
	{
		if (bPendingReload)
		{
			if (CanReload() == false)
			{
				NewState = CurrentState;
			}
			else
			{
				NewState = EWeaponState::Reloading;
			}
		}
		else if ((bPendingReload == false) && (bWantsToFire == true) && (CanFire() == true))
		{
			NewState = EWeaponState::Firing;
		}
	}
	else if (bPendingEquip)
	{
		NewState = EWeaponState::Equipping;
	}

	SetWeaponState(NewState);
}


void AItems::SetWeaponState(EWeaponState::Type NewState)
{
	const EWeaponState::Type PrevState = CurrentState;
	/*
	if (PrevState == EWeaponState::Firing && NewState != EWeaponState::Firing)
	{
		OnBurstFinished();
	}

	CurrentState = NewState;

	if (PrevState != EWeaponState::Firing && NewState == EWeaponState::Firing)
	{
		OnBurstStarted();
	}*/
}

EWeaponState::Type AItems::GetCurrentState() const
{
	return CurrentState;
}

bool AItems::CanFire() const
{
//	return IsAlive();
	return true;
}

void AItems::OnRep_Reload()
{
	/*if (bPendingReload)
	{
		StartReload(true);
	}
	else
	{
		StopReload();
	}*/
}

bool AItems::CanReload() const
{
	return true;
}


float AItems::PlayWeaponAnimation(const FWeaponAnim& Animation)
{
	float Duration = 0.0f;
	if (MyPawn)
	{
		UAnimMontage* UseAnim = MyPawn->IsFirstPerson() ? Animation.Pawn1P : Animation.Pawn3P;
		if (UseAnim)
		{
			Duration = MyPawn->PlayAnimMontage(UseAnim);
		}
	}

	return Duration;
}


void AItems::MeshAttash_Implementation()
{

}
}


Just a forum note but if you’re going to post code, please use the code tags. My scrollbar was almost invisible…

code ] and /code ] (no spaces)