I did the same thing that you are doing. Modifying the ShooterGame to include jetpacks. First I started off with the examples given here:
https://forums.unrealengine.com/showthread.php?48-Victor-s-ShooterGame-Jetpack-TUTORIAL
I also created it successfully with replication. I have some nice samples for you in regards to that:
The declarations:
UCLASS()
class SHOOTERGAME_API UJetpackCharacterMovement : public UShooterCharacterMovement
{
GENERATED_BODY()
public:
UJetpackCharacterMovement( const class FObjectInitializer& ObjectInitializer );
/**Override the Perform Movement function so we can add the jetpack logic there */
virtual void PerformMovement( float DeltaTime ) override;
/** Upwards Strenght of the jetpack, the more it is, the bigger is the acceleration for the jetpack, if its too low, the gravity has more power and you dont even fly */
UPROPERTY( Category = "Character Movement", EditAnywhere, BlueprintReadWrite )
float JetpackStrength;
/** maximum fuel for the jetpack, this goes in seconds, and its depleted with simple time, so if its 2, you can only fly for 2 seconds */
UPROPERTY( Category = "Character Movement", EditAnywhere, BlueprintReadWrite )
float JetpackMaxFuel;
/** Multiplier for the jetpack fuel regeneration, uses the time, if its 0.5, and the JetpackMaxFuel is 2 seconds, that means that it will take 4 seconds to be back at 100% */
UPROPERTY( Category = "Character Movement", EditAnywhere, BlueprintReadWrite )
float JetpackRefuelRate;
/** Holds the current fuel amount */
float Jetpackfuel;
};
The definitions:
UJetpackCharacterMovement::UJetpackCharacterMovement( const FObjectInitializer& ObjectInitializer )
: Super( ObjectInitializer )
{
JetpackStrength = 3000.0f;
JetpackMaxFuel = 10.0f;
JetpackRefuelRate = 0.5;
Jetpackfuel = 10.0f;
}
void UJetpackCharacterMovement::PerformMovement( float DeltaTime )
{
AShooterCharacter* ShooterCharacterOwner = Cast<AShooterCharacter>( GetPawnOwner() );
if ( ShooterCharacterOwner )
{
// using jetpack, so fly up
if ( ShooterCharacterOwner->bIsUsingJetpack )
{
// make fuel decrease, as you are flying
Jetpackfuel -= DeltaTime;
// jetpack is depleted, disable it and stop flying
if ( Jetpackfuel < 0 )
{
ShooterCharacterOwner->StopJetpack();
ShooterCharacterOwner->DisableJetpack();
}
// Add some acceleration to the Upward velocity, so the character is propulsed upwards
Velocity.Z += JetpackStrength * DeltaTime;
}
else if ( ShooterCharacterOwner->bIsJetpackEnabled == true )
{
// only refuel the jetpack when you are not flying and the jetpack is enabled
Jetpackfuel += DeltaTime * JetpackRefuelRate;
if ( Jetpackfuel >= JetpackMaxFuel )
{
Jetpackfuel = JetpackMaxFuel;
}
}
}
// do the CharacterMovement version of PerformMovement, this function is the one that does the normal movement calculations.
Super::PerformMovement( DeltaTime );
}
Then I just added the jetpack movement as a component to the character by injecting it into the Character Movement, the tutorial will show you that.
Rather than having the Jetpack be an attached actor, just use it as a movement component, and if you want different jetpacks, copy the properties over.
In regards to knowing who owns what in Client-Server model for UE4, I would go here:
https://docs.unrealengine.com/latest/INT/Gameplay/Networking/Actors/Roles/index.html
And here I will include the definition of the input for jetpacks as it worked just fine for me:
void AShooterCharacter::StopJetpack() //for jetpack button released
{
if ( Role < ROLE_Authority )
{
ServerSetJetpack( false );
}
bIsUsingJetpack = false;
}
void AShooterCharacter::StartJetpack() //for jetpack button pressed
{
if ( bIsJetpackEnabled )
{
if ( Role < ROLE_Authority )
{
ServerSetJetpack( true );
}
bIsUsingJetpack = true;
}
}