Download

Applying Replication in C++ for spellcasting.

Hi,

I’m very new to gameplay programming and unreal, I’m trying to create a small networked game in order to be able to play around with as many of unreal’s features as I can in a single project. I’m doing it mostly in C++ right now, and network replication is giving me a little bit of a headache trying to figure this out. This code is super messy right now because I’ve been hacking away at it trying to get it to work, so I apologize for that.

My scenario is that I have a character with a selection of spells. I have gotten replication working for spell switching, and the character’s currently selected spell appears above his head in a text renderer. However I am having trouble handling the casting mechanic in C++.

This is the flow that I’m trying to accomplish:

  1. Player Hits Cast
  2. Projectile and Particles appear in players hand
  3. After a specific duration, the spell is released in the direction that actor’s camera is facing

This is what I have currently:

  • Both player and spell have bReplicates=true
  • Spell is replicating launch with DOREPLIFETIME
  • Player is replicating bAmCasting, and the integer for which spell is currently selected.

The player’s input is mapped to this function:



void ADuelCharacter::OnShootSpell(){
	if (!bAmCasting) ServerBeginCast();
}


With ServerBeginCast here:


	
UFUNCTION(Reliable, Server, WithValidation)
void ServerBeginCast();


Implementation:



void ADuelCharacter::ServerBeginCast_Implementation(){
	//Just in case.
	if (Role == ROLE_Authority && !bAmCasting){
		bAmCasting = true;
		OnRep_Casting();
	}
}



	
UPROPERTY(Replicated, ReplicatedUsing = OnRep_Casting)
bool bAmCasting;




void ADuelCharacter::OnRep_Casting(){
	if (bAmCasting){
		ServerDoCastSpell();
	}
}


	
UFUNCTION(Server, Reliable, WithValidation)
void ServerDoCastSpell();



void ADuelCharacter::ServerDoCastSpell_Implementation(){
      //...This code spawns the actor and attaches it to a socket on the character.
     //Then it sets a timer to launch the spell from the player's hand.
     GetWorldTimerManager().SetTimer(this, &ADuelCharacter::LaunchSpellTimer, CastingSpell->CastTime);
}


The timer method grabs the camera’s current direction and calls ServerLaunchSpell with that as an input.



void ADuelCharacter::LaunchSpellTimer(){
	FRotator Rot;
	FVector Loc;
	GetActorEyesViewPoint(Loc, Rot);
	ServerLaunchSpell(Rot.Vector());
}


Which is implemented as:


void ADuelCharacter::ServerLaunchSpell_Implementation(FVector LaunchDirection){
	if (CastingSpell){
		CastingSpell->ServerLaunch(LaunchDirection);
		bAmCasting = false;
	}
}

And the spell’s ServerLaunch method:


void ASpell::ServerLaunch_Implementation(FVector LaunchDirection){
	if (Role == ROLE_Authority && ProjectileMovement){
		launched = true;
		ProjectileMovement->InitialSpeed = 1500.f;
		ProjectileMovement->MaxSpeed = 2000.f;
		ProjectileMovement->ProjectileGravityScale = .3f;
		ProjectileMovement->Velocity = LaunchDirection * ProjectileMovement->InitialSpeed;
		OnRep_Launched();
	}
}

And OnRep_Launch detaches the spell from the players hand so it can move with its velocity.:


void ASpell::OnRep_Launched(){
	//Set this velocity in the Shoot Direction
	if (launched)
		this->DetachRootComponentFromParent();
}

I’d appreciate any feedback (even on any improvements I can make to the coding style, bearing in mind that this code is expected to be super messy right now because of how much i’ve been doing trying to get this network code to work).

If I’ve missed anything that is important to discerning what this is doing, let me know and I can add it.

So I think I know the problem I was having. The ProjectileMovement Component that I have on my spell isn’t being replicated with the rest of the spell (even though I now have it set to replicate explicitly), therefore the change in velocity I make in the ServerLaunch_Implementation method doesn’t get replicated to the client. In fact, on the client it even seems like ProjectileMovement is null, even though it’s present on the server!