Server Function Containing Timers

I am running into a interesting situation and was wondering if anyone else has figured a better way to do this. I have a function, “EquipWeapons()”, and if Role < ROLE_Authority then I call

	UFUNCTION(reliable, server, WithValidation)
	void ServerEquipWeapon(class AArenaRangedWeapon* ToEquip, class AArenaRangedWeapon* ToUnEquip, bool IsEnteringCombat);

ServerEquipWeapon() has two GetWorldTimerManager().SetTimer(…) in the function call. What I have noticed is that the client won’t perform the function until the server is done running it. So oh the servers side, they see the character immediately equip the weapon but on the client side, the character stands around and as soon as the server is done, he equips the weapon.

Any found a way to avoid this?

Thanks!

can you put the code where u call function here ? your description kind of confused. ServerEquipWeapon is called on client and the ServerEquipWeapon_Implemenation will run on server, so i don’t know where u put your timer

Of course sorry about the confusion, here are the functions in call order. Basically what I am doing is I first check if the player is entering combat, if so I just equip the main weapon. If the player is already in combat (meaning they have a weapons equipped) I first unequip the main weapons and once that action/animation is over I equip the off weapon.

void AArenaCharacter::EquipWeapon(AArenaRangedWeapon* ToEquip, AArenaRangedWeapon* ToUnEquip, bool IsEnteringCombat)
{
	if (ToEquip)
	{
		if (Role == ROLE_Authority)
		{
			if (IsEnteringCombat == true)
			{
				SetCurrentWeapon(ToEquip, ToUnEquip);
				FinishEquipWeapon();
			}
			else
			{
				SetCurrentWeapon(ToEquip, ToUnEquip);
				StartEquipWeapon();
				GetWorldTimerManager().SetTimer(this, &AArenaCharacter::FinishEquipWeapon, 1.5f, false);
			}
		}	
		else
		{
			ServerEquipWeapon(ToEquip, ToUnEquip, IsEnteringCombat);
		}
		IsEnteringCombat = false;
	}
}

So if this was initiated by the client, the logic is passed off for the server:

bool AArenaCharacter::ServerEquipWeapon_Validate(AArenaRangedWeapon* ToEquip, AArenaRangedWeapon* ToUnEquip, bool IsEnteringCombat)
{
	return true;
}

void AArenaCharacter::ServerEquipWeapon_Implementation(AArenaRangedWeapon* ToEquip, AArenaRangedWeapon* ToUnEquip, bool IsEnteringCombat)
{
	EquipWeapon(ToEquip, ToUnEquip, IsEnteringCombat);
}

The above basically just calls the same function but on the server. The last call happens inside “StartEquipWeapon()” which calls the following function in the weapon calss:

void AArenaRangedWeapon::OnHolster(bool IsPrimary)
{
	if (MyPawn)
	{
		// For locally controller players we attach both weapons and let the bOnlyOwnerSee, bOwnerNoSee flags deal with visibility.
		FName AttachPoint;
		if (IsPrimary == true)
		{
			bPendingHolster = true;

			float Duration = PlayWeaponAnimation(HolsterAnim);
			if (Duration <= 0.0f)
			{
				Duration = 0.5f;
			}
			GetWorldTimerManager().SetTimer(this, &AArenaRangedWeapon::OnHolsterPrimary, FMath::Max(0.1f, Duration - 0.70f), false);
		}
		if (IsPrimary == false)
		{
			bPendingHolster = true;

			float Duration = PlayWeaponAnimation(HolsterAnim);
			if (Duration <= 0.0f)
			{
				Duration = 0.5f;
			}
			GetWorldTimerManager().SetTimer(this, &AArenaRangedWeapon::OnHolsterSecondary, FMath::Max(0.1f, Duration - 0.70f), false);
		}
	}
}

Sorry I had to post my reply as an answer to the question since it was too long to be submitted as a comment.