Hi everyone! I am working on multiplayer game and trying to implement some features inside Epic Shooter Game. One of features is modular weapons. So, inside base weapon actor I place additional skeletal mesh components and set mesh at runtime based on Datatable data. Moreover, this replicates through the net. The problem is after loading meshes using **StreamableManager.LoadSynchronous **and calling **SetSkeletalMesh **Shooting process causes log to say that there is no mesh for component. But it still visible in game. In Addition, when you switch weapon new one appears without meshes. (as the first one if you press Q again). Honestly, have no idea whats the matter. BUT on local client all works perfectly.
The flow of methods:
void ExtractModulesData();
|
UFUNCTION(Server, Reliable, WithValidation)
void SetupModulesServer(const TArray<FName>& PathArray, const TArray<FName>& SocketNameArray);
|
UFUNCTION(Reliable, NetMulticast, WithValidation)
void SetupModulesLocally(const TArray<FName>& PathArray, const TArray<FName>& SocketNameArray);
**void ExtractModulesData(); - **Works well and it just get data from datatables.
**UFUNCTION(Server, Reliable, WithValidation)
void SetupModulesServer(const TArray& PathArray, const TArray& SocketNameArray); - **Send RPC to Server
void AShooterWeapon::SetupModulesServer_Implementation(const TArray<FName>& PathArray, const TArray<FName>& SocketNameArray)
{
SetupModulesLocally(PathArray, SocketNameArray);
}
**UFUNCTION(Reliable, NetMulticast, WithValidation)
void SetupModulesLocally(const TArray& PathArray, const TArray& SocketNameArray); - **Performs mesh loading and setting to components on clients or Listen Server
void AShooterWeapon::SetupModulesLocally_Implementation(const TArray<FName>& PathArray, const TArray<FName>& SocketNameArray)
{
if (GetNetMode()==NM_DedicatedServer) return;
UAssetManager& AssetManager = UAssetManager::Get();
FStreamableManager& StreamableManager = AssetManager.GetStreamableManager(); MuzzelComp->SetSkeletalMesh(StreamableManager.LoadSynchronous<USkeletalMesh>(FSoftObjectPath(PathArray[0]), true, &MuzzelHandle)); MuzzelComp->AttachToComponent(Frame,FAttachmentTransformRules::KeepRelativeTransform,SocketNameArray[0]);
ForeGripComp->SetSkeletalMesh(StreamableManager.LoadSynchronous<USkeletalMesh>(FSoftObjectPath(PathArray[1]), true, &ForeGripHandle));
ForeGripComp->AttachToComponent(Frame,FAttachmentTransformRules::KeepRelativeTransform,SocketNameArray[1]);
StockComp->SetSkeletalMesh(StreamableManager.LoadSynchronous<USkeletalMesh>(FSoftObjectPath(PathArray[2]), true, &StockHandle));
StockComp->AttachToComponent(Frame,FAttachmentTransformRules::KeepRelativeTransform,SocketNameArray[2]);
HandleComp->SetSkeletalMesh(StreamableManager.LoadSynchronous<USkeletalMesh>(FSoftObjectPath(PathArray[3]), true, &HandleHandle));
HandleComp->AttachToComponent(Frame,FAttachmentTransformRules::KeepRelativeTransform,SocketNameArray[3]);
MagazineComp->SetSkeletalMesh(StreamableManager.LoadSynchronous<USkeletalMesh>(FSoftObjectPath(PathArray[4]), true, &MagazineHandle));
MagazineComp->AttachToComponent(Frame,FAttachmentTransformRules::KeepRelativeTransform,SocketNameArray[4]);
if (!PathArray[5].IsNone()) ScopeComp->SetSkeletalMesh(StreamableManager.LoadSynchronous<USkeletalMesh> (FSoftObjectPath(PathArray[5]), true, &ScopeHandle));
ScopeComp->AttachToComponent(Frame,FAttachmentTransformRules::KeepRelativeTransform,SocketNameArray[5]);
if (ForeGripComp->SkeletalMesh) {
if (!PathArray[6].IsNone()) GripComp->SetSkeletalMesh(StreamableManager.LoadSynchronous<USkeletalMesh> (FSoftObjectPath(PathArray[6]), true, &GripHandle));
GripComp->AttachToComponent(ForeGripComp,FAttachmentTransformRules::KeepRelativeTransform,SocketNameArray[6]);
}
if (!PathArray[7].IsNone()) GunPointComp->SetSkeletalMesh(StreamableManager.LoadSynchronous<USkeletalMesh> (FSoftObjectPath(PathArray[7]),true, &GunPointHandle)); GunPointComp->AttachToComponent(MuzzelComp,FAttachmentTransformRules::KeepRelativeTransform,SocketNameArray[7]);
}
And Flow starts in BeginPlay of weapon. Yeah, it is bad as well, but it is more convinient to find mistake. (And Still I haven’t found it)
Sorry for Weird Code. Just want to be sure it works even with this code.
How it looks after pressing Q on Client 3
Result in Editor after play started: