#multiplayer
1 messages ยท Page 641 of 1
this is what is keeping your relevancy hanging for a while
(defaults to 5.f iirc)
NetConnectionClassName=OnlineSubsystemSteam.SteamNetConnection
RelevantTimeout=2
bNeverApplyNetworkEmulationSettings=true``` for example
in the sessions interface, what's the callback for when the host gets disconnected or destroys his session? because I want the clients to destroy their session as well at that time1
their sessions automatically get destroyed along with the hosts
I'm trying to test multiplayer, and it's playing as two separate games where what one "player" does isn't visible to the other.
but when I try to create a new session on a client it says the session already exists
I mean after the host leaves
Are you testing through the editor? I have similar issues when doing so
yes
no not in the editor, in your game does the session get destroyed when the host leaves?
they can see each other but not when they move or? tell us more!
Yeah, the session gets destroyed for each client as a result of a connection error
https://gyazo.com/8ac27cd300a8514b4145cd6d79a49e52 which can be caught with this
@lone pine it sounds like your clients are not connecting to the hosts session but try running outside of editor as testing networking from within is not reliable
ah alright I'll check for the c++ version
Oh you're doing it through C++, I decided to go the BP route but it's UEngine::HandleNetworkFailure() and the failure type is ENetworkFailure::ConnectionLost. If their connection is lost I don't quite understand how they would still have a valid session, you're sure your clients are all in the same session?
oh okay,,, and yea they are in the same session but I didn't override HandleMatchHasStarted or ended so im starting the session manually cause im doing a lobby, maybe that's why?
the test scenario is:
- A player creates a session and goes to lobby map
- Other players join this lobby using ClientTravel
- Host player clicks leave session, then other players get to main menu with network failure
- Whenever one of those clients try to create or join another session it says "session already exist" OR "cant join twice" !
so I guess that means that those clients still haven't destroyed their session, Right?
oh I did override it but left it empty without calling super because I only want to start when the host clicks the start button
neither player is visible to the other, they don't see the world changes each other make, and they both use the player 0 start position.
im testing with two clients on the same computer
Hello, is their any other way of saving a lot of variables for each player instead of using a mysql/mariaDB?
Understanding Ue4 is hard enough, but learningn HTTP, php, mySQL too is just to much.
Well yeah, multiplayer games are hardly the stuff of one person
quick question: for a P2P, game instance subsystems exist in all machines, right?
They're completely local so no matter the multiplayer mode there's one on each
Sure, use the built in savegame system to save player data on the server. When they reconnect, load the data for that player.
@silent valley will look into that thanks
IOnlineSession has RegisterPlayer functions. But it needs a SessionName (FNamedOnlineSession), I only have access to the FOnlineSession object.
I want to register players from the client on the server before they are connected to the server. Will I be able to called these RegisterPlayer methods on the client to register players on sessions? Or is this only callable on the server where the session was created? (seems like it)
Hi, does someone know if a created session destroys itself when all players leaves including the server?
Or only when server calls destroy session
Shoooould require a DestroySession call
What sorts of games are viable for a ListenServer setup
anything non-competative with <16 (<=4 if you're networkign in BP) or so players (depending on your skill)
Does anyone know why when calling WidgetComponent->SetWidgetClass(WidgetClass); would cause WidgetComponent->GetUserWidgetObject()to return null on the same tick ONLY on clients?
On the listen server host it works as expected
Since PS is replicated, do i need to replicate my variables inside or it is automatically done ?
Yes you do need to replicate each variable
Just because a class is replicated doesn't mean each variable automatically replicates
As mostly you only want a small number of properties to replicate
K, thx you !
Hey uhm, i'm having a UInventorySystemComponent which is a member inside of the player class.
I'm not really sure why the client isn't able to create a widget there.
I have this here in the BeginPlay of the InventoryComponent.
M_InventoryWidget = CreateWidget<UPlayerInventory>(M_OwningPlayer->GetController<APlayerController>(), M_InventoryWidgetRef, "Inventory");
M_InventoryWidget->AddToViewport();
M_InventoryWidget->SetVisibility(ESlateVisibility::Collapsed);
Works just fine for the server, but the client will get a crash at the SetVisibility line cuz M_InventoryWidget is a nullptr
xD
WidgetComponent->SetWidgetClass(WidgetClass); to set it, calling WidgetComponent->GetUserWidgetObject() right after returns null only on the client
First thing you should do is remove the "Inventory" text, just leave the name blank or you might get a clash with object names
Server works fine
My second guess would be that GetController() returns null, so creating the widget fails
So possibly a race condition
Removed the name, still a crash.
I gonna check the controller
In my case Jambax I'm calling it from the PlayerController Begin Play, is there any possible reason it would be null here?
// In begin play on the player controller
WidgetComponent->SetWidgetClass(WidgetClass);
WidgetComponent->GetUserWidgetObject(); // NULL only on client unless I delay calling this until later
AFAIK you can't guarantee that the "possession" will have replicated before BeginPlay
So the Pawns' Controller property and/or the Controllers' Pawn property may not be set yet
Yeah, you were right.
The controller was not valid, but i don't understand why ๐
Any ideas on why the widget object would be null in the controller itself?
It's because the Possession hasn't yet replicated, there are inherent race conditions there between the controller and the pawn.
I override SetPawn() in my controller, and call an event on the AHUD object, since that's the only place where you can be sure everything is up-to-date.
Phew, seems kinda weird to me to extend the PlayerController class just for this :c
Pretty common for multiplayer tbh, you have to code around the expected race conditions
A pawn isn't necessary in my case though right so I'm really confused as to why it only works on the server and not client on the same tick.
Not sure why a widget comp would behave differently on server vs client though
It's strange
I though it was due to a race condition
AS the OnRep that inits the UI happend before BeginPlay
But then I also created the widget in the OnRep and the same thing happened
Seems null at least for a short time after it is created, maybe a tick or two? Only on the client
Haven't encountered this before
Actually, would it maybe work to create the widget through the player class's BeginPlay or is there still the same problem ?
Same issue
Same problem
The only place you can garauntee that both the pawn and controller are updated is from AController::SetPawn, which is called on Server and Client despite the name
It can be a good idea to init / create stuff like this using GS delegates like OnMatchStarted
So you can be sure that the player is loaded in and the PC ready
If Pawn replicates first, it will have the controller but controller won't have the pawn. If Controller replicates first, controller will have pawn but pawn won't have controller.
For some reason, Epic decided that both Controller and Pawn should have replicated pointers to each other - so at least one of them will be out-of-date at some point.
Alright, PlayerController extending it is then ๐
You'll more than likely need to extend the PC for other stuff anyway
So don't see it as a bad thing
PC is almost always extended, since it's a pretty core thing
๐
Ok I guess the only solution I can see for this widget issue is to make another function on a timer to get the reference slightly later
Yuck...
But it's all that seems to be working
Check out what SetWidgetClass does
It doesn't do anything unless the world has BegunPlay
Whether the world has "Begun Play" is replicated via GameState - so there's another race condition ๐
Since the OnRep fires BEFORE begin play
joys of multiplayer
Mystery solved
Thanks a lot
Was really thinking I'm an idiot for missing something obvious for hours haha
Using BeginPlay for initialising stuff in MP games is probably the cause of 90% of "random" bugs tbh
I'm going to steer away from it and move this code to a state based thing like I suggested earlier ๐
So when the match actually starts
So the PC has definitely called BeginPlay by then
I think i've used a custom player controller once (Or maybe it was for the AI controller). How do i tell my PlayerClass again that it should use my custom one ? ๐
It's a double-edged sword because you either have to have different objects talk to each other to notify them of state updates, but that ties objects and systems together, OR you can have a global event system that different thing subscribe to etc.
@vague fractal controller class is set in GameMode ๐
Yeah I'm doing the subscribe thing
GS has the events, broadcasts them
Anything can hook in
See for me even GameState is too damn late ๐
I see, thanks ^^
I'm using a WorldSubsystem now for those events since you can guarantee it'll be initialised before any actors or UI widgets etc.
So if in some 1/100 situation the HUD is received before GameState, it can still safely initialise etc.
Ah that is a good idea
What do you do for cases where an actor spawns and has an OnRep calling before its BeginPlay?
I actually realized I have the exact same problem in another actor there
OnReps etc. are always called before BeginPlay IIRC
This could happen at any time during gameplay
So if the OnRep Inits UI
Not sure how to get around it without introducing a delay
I guess a timer for next tick isn't that bad
For any stuff that needs beginplay to have 100% been called
Well the trouble is you can't even be sure BeginPlay() will call next tick
Oh really it's possible to take more? Damn..
Since if the GameState takes a few extra frames to replicate etc.
Then I guess a timer for like 0.1f
Yuck
๐
Is this even the case on an actor spawned mid match?
Where BeginPlay has been called already ages ago
But just on the actor itself it hasnt
Yeah unlikely in mid-match as presumably the world is already in the "BegunPlay" state
Ok cool might be able to get away with the next tick timer
Would you do something similar to avoid the race condition here?
AS I can't see another way around it
I'd never use a timer to get around it ๐
Since it's a time bomb waiting to go off really
Well if something gets inited right after spawning, how do you ensure that BeginPlay is called before it gets inited and therefore is safe to init UI?
Do you spawn it invisible and init slightly later?
Usually I have multiple call sites to the same "Init" function, and the Init function checks everything is available
But as for UI/HUD, all my UI/HUD manages itself and it's own lifetimes
Then subscribes to events when needed
Say a pickup in this case, it spawn an interact widget component UI that populates itself from the data coming in on the ONRep
So if the onrep happens before beginplay
It won't be valid on the client
So my options are: delay the init until later or call the init function again on begin play and check if not already inited?
So I guess in that case it's a self-contained UI/object system - so I would call the Init from both BeginPlay and OnRep
Ok will do that, thanks!
And will just check if null to see if it has already been created
Another annoying thing is then having to store that data coming in via the ONRep as a property in the class
To ensure it's available for the late begin play edgecase init
Multiplayer design ๐
We love it
Yeah honestly it's pretty common to have that setup. It's better to do that than get 6+ months into DEV and have a bug that says "2/99 times the UI doesn't show up for this pickup"
Because f*ck debugging that ๐
Been there.. learnt the lesson ๐
Good to know I'm not doing something stupid
And it's common ๐
Yeah will definitely save the headache
Like it works fine on 3/4 players
WHy not the 4th!
Down to this issue usually it seems
I mean when I say common I mean that as "well that's what we're doing" but it works out well ๐
๐
HLL has endless bugs but thankfully few of them are network-specific things anymore..
It's pretty stable when it comes to that stuff
Out of curiosity how do you manage your time when it comes to fixing stuff?
Critical first, then gameplay features then if you have time smaller bugs?
I've been trying to fix all bugs as they come to prevent them building up
But can be very time consuming
And would be more beneficial to get game work done instead
If you can fix it, fix it. If you cannot easily fix it, consider doing something you can do. Chances are the solution might even come to you when you're not considering it.
But what about thinking "oh that's easy, will take 5 minutes"
And it takes up 3 hours
Because of some strange edge case that is hard to track down
I guess with time and experience I'll be better at judging how long it will take
My experience is limited to two months professionally so far. But I find that it can be worse to force yourself to keep trying to fix something. Also from experience, you don't even know about the edge cases you don't know. I have spent hours trying to reproduce a bug that a few people reported multiple times and I can never get it to happen. Patch it up best you can and move on. Chances are that you'll either come up with a better solution later, or you could even end up just throwing it all out and overhauling. And that's gonna feel shitty if you do that after spending countless hours fixing it.
I can't answer that tbh that's more of a production thing, somebody else prioritises what is more critical etc.
For personal stuff though.. write it down in trello, add a "FIXME" and forget about it until it goes away by itself ๐
Ugh so the OnRep happens BEFORE begin play on the client but after on the server
So the double function call really is the way to go for many of these cases
Haha yep
Also doesn't the "Average" network emulation profile seem like a very poor connection in reality?
It seems to be around 200 ping
The "Poor" profile is 660 ping...
I suppose they might only mean it on either outgoing or incoming, not both
But I would say average would be something like 50-100 right?
And poor 200+
Trying to test in "pretty bad but reasonable" conditions
As 660 ping isn't something that will ever provide a good experience
Hello! all happy french mother's day
I have been using FSocket to bind a custom port in the network to send some packet in parallel to Unreal's
So when a client connects, after coinnection to the server it then connects to the second port too through TCP.
It works fine normally, but with Steam's network OSS it fails
I'm assuming that for obvious security reason, the server needs to tell Steam to accept connection on both port, but I have no clue how to actually do this?
Or is it automatic with FSocket and the answer is somewhere else?
PS : When I connect I correctly user steam.123123123 as the IP
@grizzled stirrup hell if I know we have players trying to play on servers with like 300+ ping, god knows why
I don't think i'll ever consider a server unless it's like <60 ping but living in the UK probably factors into that decision too ๐
Please i 'm stuck on How to replicate dynamic material instances changes (color) on all clients
I trigger a multicast on the event who changes the parameter values on the DMIs
The DMIS variables are replicated , (replication condition is replay or owner)
the color change on the owner client but not on the other clients
Share code
When they replicate down you'll still need to set the params on the client
Is there anywhere I can read more about the work currently being done towards a general network prediction solution, and how I can use it?
@grizzled stirrup wait i share it
the event multicasted calls a function
where it change the parameter values on materials
a function is not replicable so ...
the server calls the event on all clients if i understand
replication is so hard to understand ...
the color changes on owning client but not on other clients
660 ping means 0.66 secs to receive a network update from server lol
At some point players also should respect you and have a good connection before pressing play ๐
Testing at net pktlag=500 means "it even works in extreme conditions" but it does not need to provide a good experience
@lost duneThat is an input event into a multicast. Clients cannot multicast. Clients can only ever talk to the server. You have to server RPC from clients, and then multicast. Although you really should just create a property to set and let it replicate from the server, and use an OnRep to change the rune thing.
Is it possible to have virtual OnRep methods ?
EDIT: Yeah, seems to work ๐
So you have to change the value on the server and than have the variable be replicated. So your client can make a rpc call to server to change the value. The sever will change it. Than it will be replicated to all clients
Noticed an issue that happens maybe 1 in 100 times but it's still game breaking when it does. I override my pawn's onrep controller so that as soon as the controller ref gets replicated to the client it gets triggered, but sometimes it just doesnt get called.
void AMyExamplePawn::OnRep_Controller() {
Super::OnRep_Controller();
ClientOnPossessed(Controller);
}
```ClientOnPossessed contains some critical setup steps for the client which rely on a valid controller reference. Anyone know why it might not get called sometimes, or have a suggestion for an alternate design to make this unnecessary?
(to clarify, its not that the controller ref isn't valid, it's that the function doesnt get called at all)
I'm confused. Why do you need to replicate the controller pointer to the client? Client already has access to it's controller.
So, the server replicates the controller ptr to the client. I am overriding the onrep for unreal engine's pre-existing replication there
because i need something to happen when the replication happens
and 1 in 100 times the onrep just doesnt fire, which causes stuff to break
I find the restart functions much easier for that stuff.
never heard of that, can you explain what you mean?
was using rpcs before but it'd fail pretty frequently, probably because sometimes the rpc would call before the pawn was finished initializing on the client
i can guess that's also whats happening with the onrep but i would have thought that once the replication does make it through it should still call the onrep
It's part of the possession chain. OnPossess is ran on server. This calls ClientRestart with a pawn input. Client version of the controller at some point calls GetPawn()->PawnClientRestart()
They're terribly named, and even worsely commented functions probably dating back to UT days.
But they're part of the possession chain, and virtual in C++.
Oh. Yeah i would have never have found those, i did look for them too and i kept thinking "why isn't there already a clientside equivilent of OnPossess??"
Ill give those a try and hopefully those are reliable
thanks!
Is there something similar for the playerstate by the way?
For which?
For when the playerstate becomes valid on the client pawn
Yep. A little further up in the base Controller class.
It has an OnRep for playerstate.
I have a memory of there being something in Gamestate to do with that as well.
Ah. right.
AddPlayerState in the GameState. It's how PlayerStates are added to the PlayersArray in the GameState. PlayerState gets replicated, and when it does, it'll add itself to the client's GameState array. It does it by calling AddPlayerState, which is virtual. Could override there too.
Thats handy as well, thanks
@kindred widget thank you i dident know OnRep exists
Why does unreal 4.26 always spawn players at 0,0,0 when opening a listen server or connecting to one
Are functions that are bound to an input button... bound in the client only?
Or do I have to do something like !HasAuthority() so that it doesn't bind it in the server too?
(so that the server is not continuously checking for input from a keyboard that does not exist)
For example, in my custom Character.cpp I have:
PlayerInputComponent->BindAction("BasicAttack", IE_Pressed, this, &AHVS_Character::DoPrimaryAttack);
but maybe I should have:
if (!HasAuthority())
{
PlayerInputComponent->BindAction("BasicAttack", IE_Pressed, this, &AHVS_Character::DoPrimaryAttack);
}
local only.
Yea input is already local only as kaos said
Hello everyone.I am getting pending kill error on third client but remianing two clients are working pretty good.I kept "max no of players as 3" and "netMode as Play as client".Third client is pretty blank and pawn is not even spawning.Thank you
Just found that there is something wrong in my pawn class.If i change my pawn class i can see 3 clients individually.There is something wrong but there are no compile errors as well.
The third window is client.It is pointed towards sky and completely non-responsive
What is marked as pending kill? You need to give us more info
This is other pawn which worked for 3 clients but not working for 10 clients.Same problem when ran as 10 clients
The third client is giving isLocallyControlled as false in it's own window.But remianing two clients are giving as true and creating their UI but third client is not creating it's UI.
@twin juniper add a few of those player start things into your level
I had an issue where it couldn't spawn the player
okay i will try
ChaosDuck my saviour it worked
I am using spawn players at camera location for convenience.Somehow it got messed.
Thank you @slate basin @thin stratus for helping
How do I use this GetLifetimeReplicatedProps?
So I have this in the protected section of my header. virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
Implementing it would be the first step :P
You usally also don't need to declare it
If you have a replicated marked property, it should automatically declare it via the GENERATED_BODY() macro or so
I have this in the cpp file. https://gyazo.com/32f93adc5afed092c5c671d8b1a0bc82
I kept getting errors: https://gyazo.com/3ff87bef5fefa749393f9939054490ab
@thin stratus Do you have any idea?
Try including
Net/UnrealNetwork.h
Something like that
You are lacking the header that declares the macro
Yea got it working. Ahy it's needed by the way?
Sorry?
I'm stepping through the InactivePlayerState code and I'm largely confused. If I reconnect, it replaces the NEW PlayerState with the INACTIVE/OLD PlayerState.
And then calls OverrideWith on the OLD PlayerState passing in the NEW PlayerState. ?!
I would have thought that it grabs the OLD/Inactivate one and calls OverrideWith on the NEW one.
Specially since the Input is called OldPlayerState.
Like, what am I supposed to do in OverrideWith? I basically got my old PS back and that gives me the option to nuke some data on it?
But OnReactivated could already be used for that
This looks buggy :D
APlayerState* OldPlayerState = PC->PlayerState; <<<<<<<<<<<< This is not the "Old" PlayerState. It's the new one from me just reconnecting.
PC->PlayerState = CurrentPlayerState;
PC->PlayerState->SetOwner(PC);
PC->PlayerState->SetReplicates(true);
PC->PlayerState->SetLifeSpan(0.0f);
OverridePlayerState(PC, OldPlayerState); <<<<<<<<<<<<<<<<< Override the Inactive PlayerState with the one I just got new but is labeled old, why?
GameState->AddPlayerState(PC->PlayerState);
InactivePlayerArray.RemoveAt(i, 1);
OldPlayerState->SetIsInactive(true);
// Set the uniqueId to nullptr so it will not kill the player's registration
// in UnregisterPlayerWithSession()
OldPlayerState->SetUniqueId(nullptr);
OldPlayerState->Destroy();
PC->PlayerState->OnReactivated();
return true;
Looking through UTs code they either have a bug there or I'm missing something.
In PlayerState::EndPlay, they remove the player from its team.
So the PlayerState pointer in the Team and the Team pointer in the PlayerState will be nullptr.
But before that happens, it duplicates the PlayerState to make an inactive one.
So that one now has a team but isn't part of that actually.
When coming back, I get that InactivePlayerState, which has a Team I don't belong in, and the PlayerState that just joined but got replaced with the Inactive One got a Team, which is instantly "nulled" again.
I don't see UT ever handling that case
Why the hell are they not calling SetInactive to true on the InactivePlayerState? They only seem to do that when finding the Inactive one and then only on the new one that gets destroyed the same frame.
I must be missing something, is anyone actively using OverrideWith and InactivePlayerState? Just logically it seems utterly wrong
I guess I can override the outdated Team with the new one in OverrideWith, that would make sense.
But the SetInactive call is strange to me.
But even if I do that (UT does it), the Team would have the other PlayerState in it. So that would still be a mismatch..
Hey guys, quick question, is there a delegate that is fired when server travel finishes which can also be bound from Blueprints?
Specifically, I would like to be notified when a pawn "enters the new level" basically
@thin stratus i have the PS save sufficient data to fully restore the PlayerPawn on reconnect
Yeah I now changed it so my Restored PlayerState tells the TeamState that it got restored, passing in itself and the "old" PlayerState, so I can update the arrays properly.
Seems to work so far
that function you pasted is just a little weird ๐
I can live with a good chunk of it. I do however think the SetIsInactive is missing/wrong
Well no, unless you rely on "IsInactive" to return true for the inactive playerState
they are already swapped by that time, the "OldPlayerState" has no data except the unique net ID in it at the time, and is promptly destroyed right after
well, has no data except what the OverrideWith can copy
i do find the local variable naming... unfortunate
by the looks of it IsInactive only prevents it from registering with the gamestate
Anyone for my question? I'm getting kinda desperate...
Hey guys, quick question, is there a delegate that is fired when server travel finishes which can also be bound from Blueprints?
Specifically, I would like to be notified when a pawn "enters the new level" basically
i have made basic replication like player A shoots player b and player B's health is reduced. It works perfectly when playing in editor(with 2 clients set to play as client) but when i package the project as a server and run the server, the logs show a warning that the actor is not relevant :
LogNet: Warning: Actor BP_serverIndicator_C / BP_serverIndicator_2 has no root component in AActor::IsNetRelevantFor. (Make bAlwaysRelevant=true?)
and replication also stops working showing this error:
ThirdPersonCharacter_C /Game/ThirdPersonBP/Maps/ServerMp.ServerMp:PersistentLevel.ThirdPersonCharacter_C_2147482549
Function /Game/ThirdPersonBP/Blueprints/ThirdPersonCharacter.ThirdPersonCharacter_C:ExecuteUbergraph_ThirdPersonCharacter:064E
[2021.05.31-10.31.03:093][308]LogScript: Warning: Script call stack:
Function /Game/ThirdPersonBP/Blueprints/ThirdPersonCharacter.ThirdPersonCharacter_C:ServerFire
Function /Game/ThirdPersonBP/Blueprints/ThirdPersonCharacter.ThirdPersonCharacter_C:ExecuteUbergraph_ThirdPersonCharacter
how can i fix this issue?
@ancient bramble Are you using C++ for that Actor?
That is correct (as far as I've seen), I kinda explained myself in the wrong way. Let's just say, I'd like to be informed when a server travel ends for a controller, is there anything like that?
no im not
HandleSeamlessTravelPlayer in the GameMode I guess
this is my replication settings for ThirdPersonCharacter
i mean it works normally when i click play but it doesnt work when i connect to the local headless server
Anybody tried replicating a component property in the actors' replication list?
Actually.. forget that ๐
Is the Server Map maybe wrong and there are no spawn points on that one or something like that?
Or is it only the firing of the weapon?
You probably have code problems. Hard to help with just he information we have
i have a player start, its spawning fine
and the map is also the same
Then I would start placing print strings and see what the log offers
i just type the command open 127.0.0.1 in the console to connect btw
Remove pawn from the world and try it, does it spawn you one?
you mean inside the game mode i should make the pawn to none?
nope i removed the default pawn to none and it doesnt spawn in the player character
Game Mode should have whatever class you want as Default Pawn. Remove the pawn from the map tho, and make sure there's a PlayerStart actor on the map.
Then when you start up it'll spawn you a pawn and place it at the PlayerStart
yeah thats what it does by defualt right, i havent touched anything but it still shows up like this
i mean if it works when you click play but doesnt when you connect to the headless server then somewhere else is the problem right?
also there is no pawn in the map, just the player start
so when the player joins a server i should spawn a pawn in the player start, then posssess the pawn to a specific controller?
i just want to test if the player spawns and the replication works on a local headless server
but it doesnt
should i keep the auto possess player to player 0 or 1
Neither
Just set it to not auto possess
The GameMode already takes care of this if you have the default pawn selected
yeah i set it disabled
I'm working on a shooter and if the client's ping reaches a certain point, when they shoot and their bullets hit an enemy the bullets freeze and sit there until their lifespan is up.
Is there some way to mitigate this?
Predict the hit and hide it locally
What is better ? Trust client on the hit and then verify it server side later or predict it on the server before sending it to the client ? ๐ค
Just predict visuals and keep damage on Server
Fortnite does trust the client and then verify on the server ๐ค
to be sure he dont lied ?
Poor take and not really needed here (:
And trusting the client would indeed mean that the Server accepts without verifying
Hello!
I want to create a system in C++ to replicate animations montages, the gameplay of my game will heavily use it so I need to make sure it get replicated properly:
When the client do the action, it should instantly play it
The server will do the verification then replicate it to others clients
If a client is late to get it, it will play it and set the position of the animmontage where it is currently.
Is there any built-in system to do it?
I want to use that mainly for the characters to replicate animations on things that aren't players like the environment.
K k
Might sound a bit weird, but is there any way to wait until an RPC call is finished before you execute other code ?
You'll need to somehow send back a confirmation or some other bit of data to let you know to proceed. You could have the 1st RPC call back into the caller to do the next bit
I could see how that works, i'm just not really sure how to keep my DragDropOperation alive for the time ๐
@vague fractalWhat exactly are you trying to do? Drag and drop inventory?
Basically.
Currently i'm at the "Let the dropped inventory item spawn into the world" which works just fine.
The problem is just that i have to update the inventory once i drop it.
This works also just fine for the server, but for the client it doesn't work.
I assume it's cuz the RPC call isn't fully finished at the point where i call the UpdateInventory method
I guess i could do it with a other way, but that way is kinda more lazy cuz i'd check if the inventory item amount got changed since the last tick
@vague fractal Have the drop be the first thing that the server knows about. You should have some sort of Inventory to World function, the drop would call that
That function is what would do the actual removal from inventory and spawning into world.
I think i have that already
As far as the server is concerned, whether you drag and drop or just use a hotkey or any other method, dropping an item is done the same for all of them.
Then what's the problem? Just at the end of the drag and drop, you call that event with whichever item you're trying to drop. There shouldn't have to be any sort of waiting or call back
I have it like here
void Foo::NativeOnDrop(...)
{
OwningPlayer->GetInventorySystemComponent()->Server_DropItem(InventoryItem->GetItem());
PlayerInventory_DragDropOperation->OwningPlayerInventory->UseActiveSortButton();
}
So is the problem the timing of the sort?
just have sort happen after inventory is updated
nothing to do with the drop function
Ye, that was basically my second plan. As in the inventory checks if the item amount got changed since the last tick
RepNotify
Dont check things on tick unless they're needed like maybe for physics or movement etc
I think i'm not able to use this method due to how i made the things ๐
You should be able to, your inventory is a replicated struct or array righT?
Yeah, but it's stored in my UInventorySystemComponent.
Problem here is that my UPlayerInventory isn't stored anywhere cuz i wasn't able to store it.
The problem was that when i create the inventory on the client the Pawn or Controller were not synced or similar
You could either have the inventory sort every time it changes, or just have a manual sort button if ppl might want to have their inventory laid out in a certain way like WoW has it.
what if you can disable destroy and spawn new playerstate when player leaves?
is this possible tho?
then player reclaim the owner of the current playerstate when they rejoin the game
Wait, so the server doesn't know what's in a players inventory?
It should since it's using the original items from the UInventorySystemComponent
So what exactly is a UPlayerInventory?
Basically just the visual inventory (UUserWidget)
Then just have the RepNotify call Update on the widget after sorting
RepNotify -> Sort -> Update Widget
But for that i'd have to store my widget somewhere. Otherwise i'm not sure how to reach the widget for his methods
Where are you creating the widget from, HUD or PlayerController or where?
That's also done in my UInventorySystemComponent once the player presses the button to open the inventory
K so then the component can store a ref to the widget and tell it to update when the RepNotify fires
I've tried that. On client i'll only get a nullptr once i try to store it in a member variable.
But it does work just fine if i work with a local variable
ya something sounds fucky here. is the UI in screen space or world space (3d)? I'd recommend haveing all the UI handled in the PlayerController or HUD and not in the inventory component. If you're reusing the same inventorycomponent on chests and mobs and AI characters etc, it's unnecessary.
The UI is in screen space
UE4 does that by default.
Which was the thing that broke stuff for me, cause I expected it to work slightly different
Tbh, i think the easiest way here would be really just to check if the item amount from the player got changed since the last tick.
Cuz currently i'm creating and destroying the PlayerInventory once the player wants to open/close it.
So the price of using Tick in there shouldn't be high at all
so you can't change it and remove the destroy/overriding PS?
I could, but I want to use it. It's also sort of working now
I see, i was thinking to disable that function so i dont need to mess with copyproperties (even if it works for now)
because it wasting bandwidth to copy new PS replications to all players again
It's not replicating the Inactive ones
mean the new one, when players leaved New PS goes spawning isnt is it?
Yeah, they duplicate the old one and set it to not replicate
The new one that is created when they rejoin
Is probably not replicating much
as that all happens in the same frame
oh thats weird
at the my project it was happening on leaves
and after firing a rpc it goes replicated automatically to all players

but how does it works on my project tho
even i can get Level integer from that spawned new PS
if i can match the player ID
You can't even access that by yourself
So whatever you are accessing is not the duplicated one
It's not part of the PlayerArray
but when i firing that RPC from copyproperties (before leaving and after) it shows different PS names like spawned new one
Idk, all I know is that it's marked as not replicated
interesting
Hey everyone, I'm looking for a person who's very well-versed in designing multiplayer in UE4/UE5, I've questions that I'd like to ask to a competent person who'd be nice enough to give me 10-15 minutes of their time. Preferably someone who's released and tested multiplayer. You'd be saving me a lot of effort and time and anxiety.
#instructions @twin juniper
whoops, sorry.
didn't know that existed.
Not asking around for a job listing or anything, by the way. Just have a question about the general topic.
i can write an entire game in 10-15mins..
lol
#define true ((rand()&15)!=15)
but mine is true most of them time ๐
ah true
#define return if (rand() % 100 < 2) throw std::exception(); else return
๐
Does anyone know a good tutorial on beacons, especially LobbyBeacons? To be used on dedicated servers.
hey y'all I'm getting back into UE4 and I'm currently setting up my GameMode and GameState. I wanted to start with something simple like networked spawning/respawning of a simple player pawn that I made but I'm running into an issue I don't recall having last time I set a respawn system up.
the problem is that the player respawns but doesn't get transported to the transform of my invisible "spawn" actor. I've tried setting the transform to a static value at 0,0,500 but it behaves the exact same.
the way I have this set up is:
"run on server" RPC is called within the playercontroller
the player controller RPC calls the multicast function in the gamestate
the gamestate RPC calls another multicast function in the gamemode that calls the "Restart Player from Transform" node
it's been a while since I've done any work in UE4 so there's probably something simple I'm missing
@cerulean escarp Don't reinvent the wheel. The GameMode has functions for this. Override them if you have to.
I know... I'm using that function to respawn the character
"Restart Player at Transform"
the difference here is that I'm making a bridge between the player and the gamemode in order to allow the player to call the respawn function
What happens if my servers arent optimized well? I know that the lobby will eventually crash if im overloading the server too much, but does replicating less events/variables do anything noticable? Will it affect ping, data loss, etc?
@cerulean escarp Why are you multicasting those? It should just go
input -> run on server -> do stuff
GameMode only exists on the server anyway
I tried that and it still just resets my camera without moving the player to the spawn location
also just to clarify something, I was under the impression that custom events which are intended to be called outside of the GameMode should be set to multicast. do they have to be set as an RPC in any form or can they just be non-replicated custom events?
alright so I just made it work by using the input -> run on server -> do stuff logic along with destroying the player pawn before calling the Restart Player function in the GameMode and that worked
What is the players Pawn in this scenario? You doing anything weird or just have a pawn with a camera on it?
it's just a character with movement code and a camera attached
And that class is set as default pawn in GameMode? And you're initially starting it the normal way?
Does player pawn exist on the map at startup or do you let GameMode spawn it?
yep it's the default pawn in my GameMode and the GameMode spawns it on one of two PlayerStarts I have placed in the test world
I ditched the weird actor search method I had posted earlier since I realized PlayerStarts have spawn tags
Just try this. Input on Controller or Pawn -> Run on Server -> Get GameMode -> Restart Player
That should snap you back to however you were when first loading.
that didn't work, it seems to restart my character but in place rather than moving it back to the player start
How is it initially finding player start? Just the normal way or something custom event?
the default way
Youre calling RestartPlayer and not RestartsAtLocation right?
the one that works I was using Restart Player at PlayerStart but when I did what you suggested I used just RestartPlayer
Hmm that's strange. I'm not 100% sure on the call order between the different restarts.
alright, well it works and is replicating properly between clients on the server so I think it's ok to use
just doesn't seem right to me to have to destroy the player pawn before restarting them
Is that what you're having to do? Manually destroy then restart?
yeah
last time I set up player spawns on a different project that I no longer have I didn't have to do that
Yeah something seems fishy
You sure you're not overriding any of the start spot functions?
I don't believe so
only event that I have in the GameMode is the custom event I use to call the Destroy Actor and Restart Player at PlayerStart nodes
IS it a good thing to store Characters in the game mode? Or where else can I store them
@lost dune what do you mean by storing them?
why would you store them?
alright I disabled the custom event and now the only thing I'm doing is in the player controller calling a run on server event that runs the RestartPlayer node directly inside of the playercontroller
no code at all in the GameMode
and it does the same thing where it just restarts the player in place without taking it to a spawn
In my game mode, on post login event, I spawn a new character and add him in an array of characters
@cerulean escarp WTF that's weird. You'd think it'd at least do what it does the first time.
ikr that's why I've been so confused
Unless it defaults to something other than RestartPlayer. Try the other options.
Couldn't it be in the game state?
PostLogin kinda works, HandleStartingNewPlayer is better
unlike PostLogin, it works with seamless travel
Ok
keeping an array of characters is optional
especially considering its the one fully safe use of GetPlayerCharacter[Index] function
none of the RestartPlayer options worked until I added a Destroy Actor node before it
Dafuq
GetGameMode - > GetNumPlayers -> For (0 to NumPlayers - 1) -> GetPlayerCharacter[Index]
this is wack
will get you all the player characters, without the need for caching them anywhere, works only on server
I suppose it's alright to use though since it replicates properly
@winged badger Isn't player pawn stored in PlayerState by default or nom
Excellent thank you
it is, but this is less nodes to iterate them all
as you don't have to pull pawns from PlayerStates in PlayerArray here
it is the version that works on clients as well, so... @lost dune
@winged badger Any insight into this RestartPlayer BS?
GetGameState -> GetPlayerArray -> Foreach -> GetPawn (might be something similar, function name) will also iterate over all Pawns
i didn't read from start it was a little long
Should it default to restarting in place without using start spot like first startup?
It's respawning pawn but keeping location. Uses start spot if pawn is destroyed first
You'd think it'd do the same as first startup
there is a ShouldSpawnAtStartSpot function in the GM
that caches it in AActor* StartSpot in the PC
and by default returns StartSpot != nullptr
Ah
if it returns true it will skip choose/find playerstart
i find it best to override it to return false;
@cerulean escarp There you go
as ontop of everything else, it caches the StartSpot before you can get any team information in
its really terrible
@cerulean escarp why are you multicasting stuff from GameMode?
I'm not anymore
good
Can someone help me with set master pose for multiplayer client server? The same node call works fine in single player, but in multi its stuck on idle animation
@winged badger I already reamed him for that one
lol
Show what you're doing right now
animations don't replicate
nor can you replicate stuff inside anim BP without significant (and very much nor recommended) custom work
you replicate what you need via pawn/character
your BlueprintUpdateAnimation does TryGetPawn->Cast
then it reads and caches everything
and uses only what it cached during updateanimation in anim graph
no BP logic, just read the cached variables in anim graph
or you lose the multithreading for animations
i'm lost
I just replicate the variables responsable for the animations
the Anim BP get them and choose the anim to play
why it works for the "character mesh" and not for the armors skeletal meshes
they use the same animBP and share the same skeleton
@lost dune Show your TryGetPawn
No
The skeletal meshes(armor pieces) are animated but stuck on idle anim
its not like if they were not animated at all
You using Master Pose Component?
Then one of your driving variables isn't being replicated
Show the anim graph
Also snipping tool
Win alt S
What's the transition rule to strafing?
Dude use the snipping tool, half of these screenshots is discord lol
sorry ๐
@lost dune k and show where you set bStrafeLeft in the character BP
There it is
Input is only on local client
Any particular reason you're doing it that way and not a velocity driven blend space?
No , i 'm just finishing learning the basics and re implementing it
Ok so I would either switch over to a blend space (the good version) OR start calculating the movement booleans based on velocity (the bad version)
Either way, you don't need those bools on the character. Not the movement ones anyway.
but my character is rolling pressing R key , i have to do a boolean for that
the question is why the character mesh is correctly animated and not the armor pieces , sharing the same ABP
Is character mesh correct in multiplayer?
Yes
Even strafing?
The armor pieces are ""spawned"" using set child actor class on the child actors of the armor pieces
just after that i call set master pose , it fails
ohh , it dosent fail , its stuck on idle
What are all the errors you're getting?
there are a lot for the moment i have not cleaned yet the output log , but i check right now
Anyway, for multiplayer, your set up is pretty screwed up. I would recommend taking a look at the third person template and seeing how they do their animation blueprint. Don't even worry about armor right now.
Anybody know an easy way to get a user's public IP address (for PC)? to then get their general geolocation
I mean if ur the server u can
is it possible to get client's IP?
@twin moat ^^
ok thanks
Is it possible and faiseable to copy pose of the character mesh to his skeletal mesh armor ( instead of using anim BP)
I think you only need Master Pose component. No need to assign an AnimBP - https://www.youtube.com/watch?v=yQQYyHzTrS4
Super simple method to do clothing/armor attachments. Uses Synty's Polygon Battle Royale and UE4 Third Person template
How would I go about teleporting all clients to a position?
I have a "host" client who has an interactable Widget on their hand and when they press a button it casts to the GameState and runs a Server event with the positions of the teleport, which then runs a multicast that lets the client camera fade out, checks if the client is the host/client and teleports them to specific positions based on that data.
It works when you're playing solo, but the moment another user joins it (the widget) stops working entirely
great
I have forwarded with it , but now the armor is not animated at all in multiplayer (works fine in single player) the set master pose fails in multiplayer i don't know why
@lost duneYou need to spawn the armor on the server and everywhere, set master pose locally
Yes
Are you parsing the components that need to be animated/attached across to the server?
Also why not just do/attach them to targets
attach component to component?
Yeah, or attach component to bone, that way you don't have to update it realtime
Unless thats what you're doing
They are skeletal meshes deformed by multiple bones
if they are attached to a single bone it will go throug the vody
body
the spaulders and helm are static meshes
for them its simply attached
but gloves boots breast and legs are skeletal
NEW , well animated in the BP editor with set master pose in construction script
It's a multiplayer issue
I'd still love a hand with this ๐
Anyone know anything about 3d widget replication?
yes ofc it stops working with multiple elements. Your GetPlayerPawn(0) should be ran locally, not from the server
since GetPlayerPawn(0) from the server is just the Host; no one else is considered
Eeh never mind; I misread on the GetPlayerPawn(0).
How are you getting to run the Teleport to Entrance?
GameState doesn't have a replication owner per say, and thus can only run Net Multicasts when you're already the server
Furthermore, this type of action doesn't make much sense to run from the GameState
Yeah I moved it from the GameState to the parent widget actor
Its running via a Widget button press
Widget is spawned on everyones end via joining a session and if you aren't the host then it disables yours/hides it
I assume Widgets aren't replicated so I've tried to basically push it over to the actor that has it as a Widget Component
It works fine when you're in SP or alone in a server but the moment another users joins it just stops working
oh yeah and this, ofc you actually need the TP
I was running Teleport in Server but moved it back to Client
Based on this forum post I'm reading you can only call RPCs from controlled pawns?
๐ค
however it is 6 ears old
Hi, I have a problem which I am not sure how to handle correctly. I've got a multiplayer game where I want to open doors so that if someone opens a door it opens for everyone and everyone should be able to use doors. Problem is that server owns my door actors. and I cannot trigger Run On Server event on interaction from client. It took me a while to figure out that I have to first make the client owner of that actor before I can run the events. So now It all works but on every interaction I first make the client owner of that actor and then run on the server, multicast to make it happen for everyone. For me it sounds like there should be smarter way of doing this. can I ignore the ownership alltogether somehow ? to make it so that every client can run the "Run On Server" events
You're correct, there is a better way to do that. Send a Server RPC through either your player character or player controller.
Yeah, there are a ton of better ways to do it but at this point its just a duct-tape fix for something that has to go out tomorrow. I'm hoping running it through the Pawn will fix it ๐ฌ
that was a response to Proge, not you. But yes, you can only call an RPC on an owned actor.
ah ok
It doesn't need to be a pawn, it can be the player controller or any other actor that's owned by that client.
is APawn::AddMovementInput a server RPC? If so, how can I tell that it is?
If not, then then why does calling MoveForward() (which is bound to my forward axis input and is client sided) able to move my character in both client and server?
It isn't.
It sends the input to the movement component (if there is one). If this is a character, what it does from there is complicated.
tldr: CharacterMovementComponent applies the input locally and also sends it to the server. But that can get rolled back if the server disagrees on the result.
There's an overview of how CMC networking and prediction works here - https://docs.unrealengine.com/4.26/en-US/InteractiveExperiences/Networking/CharacterMovementComponent/
It's not as simple as just sending a server RPC.
oh I see, that makes sense. I see that AddMovementInput sends the input to the movement component's UPawnMovementComponent::AddInputVector but after that I get lost lol
oh thanks for the link, i'll take a look!
@turbid radish RPC's cost more bandwith, you could also share a variable "bool DoorOpenState" and use a rep_notify function which will play your door opening or closing animation on clients.
Thnx ill investigate.
Here is a good link from the UE4 Documentation that should help you, you can read it all or take a look to the Variable Replication section:
https://docs.unrealengine.com/4.26/en-US/InteractiveExperiences/Networking/Overview/
Setting up networked games for multiplayer.
https://www.youtube.com/watch?v=lPOSiM_-g74
any1 know how to fix this issue?
@turbid radish Simplest robust method
Input -> Run on Server -> set replicated variable -> Repnotify
Bool bIsOpen or float OpenAlpha
Depending on if a door can be half open
@ancient bramble Have you set a rootcomponent in your blueprint/cpp constructor ?
i didnt do anything i just have the default third person gamemode and set auto posses to disabled.
im using blueprints for the replication part
i just have a player start on the map, and that it
I am more comfortable with cpp but the logic is the same.
You have a blueprint called BP_serverIndicator_2 which is shared on network but does not have a rootComponent assigned.
And BP_serverIndicator
Which means there is one per player.
What are you doing with this serverIndicator?
nothing, i dont even have that blueprint
i mean it plays fine when i click play, so it should play fine when i connect to a headless server right?
I see it in your folder ThirdPersonBP/Blueprints his name is BP_serverIndicator
In theory but not always, maybe this warning is not related to your issue but it's good practice to remove all your warnings so you can see what's going on clearer.
that the text renderer
bp_ServerIndicator is the text rendering actor
it was set to replicate
i changed it
ok the warnings are gone
but still the replication is failing
[2021.06.01-05.59.20:299][545]LogScript: Warning: Accessed None trying to read property K2Node_CustomEvent_Gun
ThirdPersonCharacter_C /Game/ThirdPersonBP/Maps/ServerMp.ServerMp:PersistentLevel.ThirdPersonCharacter_C_2147482549
Function /Game/ThirdPersonBP/Blueprints/ThirdPersonCharacter.ThirdPersonCharacter_C:ExecuteUbergraph_ThirdPersonCharacter:064E
[2021.06.01-05.59.20:300][545]LogScript: Warning: Script call stack:
Function /Game/ThirdPersonBP/Blueprints/ThirdPersonCharacter.ThirdPersonCharacter_C:ServerFire
Function /Game/ThirdPersonBP/Blueprints/ThirdPersonCharacter.ThirdPersonCharacter_C:ExecuteUbergraph_ThirdPersonCharacter```
Are both of your windows clients ?
yes
This is odd, can you try:
- Make sure your BP_Character is replicated
- Make sure all the subComponents of BP_Character are set to replicated
- Give it a try
are there some cons with calling a server rpc without HasAuthority check ?
Since only the Server has authority, yes
Thatโs literally like ยซย hey client, I authorize u to do what the server can do, do it !!ย ยป
So yeah HasAuthority is smth important (not just for RPC.)
are you saying you should always do the HasAuthority check regardless
void DoSomething()
{
if (!HasAuthority())
{
DoSomething_Server();
return;
}
// Do the something
}
void DoSomething_Server()
{
DoSomething();
}
So it should always be like this ?
And when you want to do something you should be calling the DoSomething() and not DoSomething_Server() ?
Even if you know you are server ? E.g. GameMode
And also as a good practice ?
What's you function is doing there is checking if this code is executed by the client, if yes then you call the RPC server method so it also execute on the server.
but my questions is, should you always have this template for all rpc calls ?
regardless of whatever situation
Because of the return it will only be executed on the server and not the client.
but because the actor or whatever is replicated, it will reflect on the client side, hence we should use this template for all rpc calls ?
It is a standard template use by UE programmors, you don't have to use it but I think it's good practice.
you say
you don't have to use it
what is the alternative ?
and is it better ?
and better in what sense
do you have some examples of the "something else" ?
also, lets say you know you're server, would you still use this template for rpcs ?
If you are 100% certain the code is running only on server side then you don't need to, as the server do not need to RPCs to replicate.
*server side
are there some kind of overhead/cons with calling rpc on server side ?
Beside that you are making an extra call and that your logic is not properly handled (and might be confusing as the project grows) no I don't think so. The server will just execute the function.
cool cool i think that clears up some of my doubts, thank you
You can refer to the documentation here (section: RPC invoked from the server)
https://docs.unrealengine.com/4.26/en-US/InteractiveExperiences/Networking/Actors/RPCs/
Designating function replication across the network
i think its not informative enough
I undertand. However it shows that when you are the server instance executing a server UFunction, regardless of the Actor ownership it always runs on the server.
Are you familiar with GetNetMode()
I feel that we should avoid using them ?
I mean if you actually just want to check for GetNetMode() then its fine
But i dont think its good or useful/adequate enough when used to check whether you are server or not
The better way is to use HasAuthority() to check whether you are server/client ?
And to check whether you're yourself then IsLocallyControlled()
What do you think ?
I am experiencing a weird behavior so It's a very intersting question to me.
I actually have my clients spawning a projectile showing as:
- Having Authority
- Local Role: ROLE_Authority
- Remote Role: ROLE_SimulatedProxy
- Locally controlled: yes
- Owned locally: yes
And the projectile appears only on client side, the server doesn't spawn it. (even after the hasAuthority check)
So I am trying to figure out what I did wrong in this project, but normally the hasAuthority is enough to know if you are on server or client side.
I'm not 100% sure but wouldn't client-side only actors have authority?
Yeah they will
They would. You want GetNetRole
Where are you spawning the actor from?
I am spawning the actor (a projectile) from a weapon.
The weapon is owned by the character.
I also set the ownership of the projectile to the weapon but right after spawning the projectile.
But are you doing all this server side or client side?
What machine is calling the spawn actor node
I'm using the same template as Jekas
void DoSomething()
{
if (!HasAuthority())
{
DoSomething_Server();
}
// Do the something
}
void DoSomething_Server()
{
DoSomething();
}
It's run on client and supposed to call the Server RPC but because of the Authority being always true the client never call the RPC.
The client should not be authority over the gun or character
That's what I don't understand. I've used this "template" before and I never ran accross this issue.
Double check that the gun is being spawned by server lol
You might have a local only gun
I think you might just have found out.
The weapon is spawn during the beginPlay of the Character.
I would guess it should exist on the server side too.
Gated behind Authority right?
It wasn't ๐
So you'd have 2 guns I'm pretty sure
It's a collaborative project, I have to adjust several things. I have random crashes as the weapon doesn't exist locally anymore, but I think we are on good track.
BeginPlay in the Character is too early
You can't properly specify an owner
OnPossessed is a better point to Spawn the Weapons as you then have a Controller you can use for the Owner Pin
OnPossessed runs only on the Server too, so easier to manage
It's alright, you can even do it before in the PostInitializeComponents. I did that in another project.
I just need to replicate the variable of the weapon I think now and we should be good.
Run the game with some simulated latency/packet loss. That's a good way to start finding the cracks in your logic.
Of which there will likely be many if that's never been done before
I wasn't aware of this possibility, would you have a link about how to simualte latency?
PostInit / BeginPlay etc. is essentially way too early to start using other replicated actors - you can't garauntee they'll be valid at that point. That's what OnRep callbacks are for.
Just go into the advanced play settings in the editor, and check the "enable network emulation" boxes
In the PostInit and BeginPlay I only spawn the weapon. Still too early?
Server can spawn it there if you'd like it too, but there's no guarantee the client will have it in BeginPlay/PostInit
(In another actor, that is)
Makes sense. Thanks.
Can someone help figure out why this is only teleporting the first player?
Its in the GameMode and sets the clients positions via the server
Can you debug/breakpoint your player array and display the elements in it?
I'm about to go to bed, I can stay 10/15min but then I will have to go.
Yeah, it prints player names when a player connects and gets both
Ahh cheers
We're using VR so we can't debug via UE4 itself ๐
Going to do a Get All Actors + Foreach on the server so it covers them all and hopefully it force moves the camera
From what I see your logic is good.
Yeah, it just won't move the 2nd VR clients camera
Maybe it's not running on the server side and runs locally.
Im assuming they're not in the array so I've just hard coded it like I said just before, hopefully this fixes it. If it doesn't I'd be surprised
Cheers for your help ๐
you need to ask server to tell players to teleport
That is the server telling players to teleport
as well
Host tells server to tell all to teleport to specific location
for some reason Cli 2 doesn't
Telleport all clients is set as a RPC server ?
Not from Authority
It was from another Cli
I'll try that
The change I just made moves the 2nd player but only a tiny bit
It moves them forward and they force move back to their previous position
oh... I think I know what it is ๐
I force set the client camera position 
Thank you everyone, I'm going to go lie face down on the concrete for an hour and question my life choices
It didn't work ๐
I have no idea whats happening anymore lol
I got a problem of handling animation for multiplayer. Right hand side of this video is showing server looking at client movement and the animation works well. However, left hand side of the video showing when the client looking at server movement, the transform of head and hands seems to be reset to a certain position when server is walking but back to normal when the server stay still.
I have applied some IK logic to the animation BP, and I replicated the camera and motion controller transform. Does anyone have any idea what's wrong?
IK in anim graph
HI, i have a Problem wehre the CLIENT via Listenserver sees the AI moving but falling in to the Ground heres a video.. they are clipping up and down
they might not be in the same movement mode
walking vs nav walking
on client/server
other, scarier version is that your Base (reference to the component deer is standing on) is not net addressable
in which case it would not be clipping through floor and back, but teleporting to 0,0,0 instead
for everyone else
Can someone help me
those map deformations aren't replicated, and it won't look right until they are
Hi @low helm replicating map deformation is a thing? Sorry i am still a beginner
@low helm oh yes, but i use no Voxels its just the ue4 landscape
Oh well you can't deform UE4 landscape at runtime so you're fine
collision always uses the highest LOD, the morphing verts are visual only
I made a equipment component which swaps succesfully, I used a delegate to callback to the character itself but in MP it seems to do RepNotify before being bound (binds on OnRep_PlayerState and BeginPlay to be safe). Somehow it Reps the component variables before playerstate and thus not being able to call the correct function. Is there another function I can use to bind delegates before OnRep of components?
hi all, I would like to have a VR client spawning in with a VR listen server, but what I get is that only the listen server will be visible while the client is not even spawning.. I know that probably the issue is with the get player controller, but I don't know how can I reference the player controller otherwise.
@pine bobcat You need to replicate whatever your driving variables are
For VR that'd be the head and hands transforms at a minimum or something derived from them.
GameMode supplies you with the Players in PostLogin. Or even better in the overridable function called GetDefaultPawnForController.
Can someone help point me in the right direction for level streaming in multiplayer?
Blueprint Runtime Error: "Accessed None trying to read property CallFunc_GetPlayerController_ReturnValue". Blueprint: GameMode_Darts Function: Execute Ubergraph Game Mode Darts Graph: EventGraph Node: Possess
I am also getting this error, which is I guess due to my incorrect use of get player controller. where would I use the GetDefaultPawnForController? Sorry I am a still new to blueprinting and Unreal in general.
May I ask why you do multiplayer if you are new to this?
Multiplayer is the second step of learing coding in UE4, not the first
Either way, it's an override in the functions tab of your GameMode blueprint
You can select override when you hover the function tab
GetPlayerController is 100% wrong
Because even if it wouldn't return nullptr, it would return the Server's Controller all the time
So you would never possess the other players with the correct controllers
I am looking into multiplayer because of a project that we are working and I am aware that this is not the first step learning it, I just thought there might be an easy fix for it. Thank you for your help.
Hey hey, I'm learning multiplayer so forgive me if I ask anything stupid ! Is there a difference between using a 'is local controller' bool check vs using a custom event that runs on client only ?
I think this question is asked without context. So better state the situation as to why you need to do such a check and what you want to achieve.
It's not replicated like most things, you'd just have to do it on each client independently.
Does anyone know if a LobbyBeacon(Host) implementation can work on a dedicated server. As in the dedi server is able to communicate with players before they join the map.
If not please stop me, because that's what I'm about to do
@lost dune Best way would probably be something like a repnotify on the Character for when EquippedItems changes, takes each item and sets MasterPoseComponent for them.
Thanks a lot for the idea , i test that as soon as possible
It's usually a good idea for reference to flow in One Direction so that's why I'm suggesting having the character take the initiative to tell the armor piece to set its Master pose component rather than the armor piece having a reference to the character
If you have several OnRep properties that call the same thing when repping down, it's completely safe to just make 1 OnRep function and have multiple OnRep properties call it right?
UPROPERTY(Transient, ReplicatedUsing = OnRep_Health)
float CurrentMaxHealth;
UPROPERTY(Transient, ReplicatedUsing = OnRep_Health)
float CurrentHealth;
UFUNCTION()
void OnRep_Health();
As opposed to having unique OnRep functions that each call duplicate code
that depends on the overload
yes
Is it fine?
should be, yes
Great thanks
And I assume if you do pass in the last value it'll just take whatever the last one repped
Which is bad of course
But for a case like this should make things a bit neater
Good to know it's not tied to a specific variable or even variable type
i would still have all separate OnReps call the same function to handle them
Yeah in case I need to do unique logic per property it would be wiser down the line
makes it easier when you find yourself debugging things
True also
I won't be going crazy with it but there are a few places where it's a nice cleanup
Hey everyone, im trying to figure out how to make a matchmaking system.
Ive looked around and all it shows me is the basics of online multiplayer and nothing on how to set up teams and such.
How would I go about making this after making the initial multiplayer settings (lobbies and such)
I have a setup where players interact with mechanisms in world (buttons, levers), which communicates via messaging. The blueprint for the mechanism updates the instigator character rotation and location to line up to play an animation. I'm sending the updates through the server so they're replicated across all clients, which is lerped through a timeline.
After the timeline ends, the character snaps back to its original position. I presume what's happening is there's conflict between the player controller and the updated rotation/location. Is there a method I should be using to properly inform the player controller of the update, bearing in mind that his is happening in the mechanism blueprint placed in the world?
Teams would be extra data that your game logic refers to. You could have a widget or some logic that selects a team for a player, then have an array for each team that you populate and can use for reference via your game logic.
I did a quick youtube search and saw this video that covers team selection for multiplayer. Hope it helps. https://www.youtube.com/watch?v=aW6XSshcYwE
Is there any reason a VR Camera wouldn't teleport when a server forces set actor transform?
Resolved the issue. I have the server multicast to get each client to run the animations. Then I do a Get Instigator Controller and Set Control Rotation on just the controlling player so that their input rotation updates to match the animation output. This could be the wrong way to go for many reasons I guess, but it works at least for this prototype.
I have replicated the values and I checked that the values in server and client is the same
How can i trigger an event from a client to the server ? ex : I want a client to push a button in the UI and then the server would run the node " get all actors of class > player controller " then for each player controller i would like to change a variable
I thought the " run on server " event would work but i believe i dont quite understand the concept
Run on Server works on OWNED actors
in your case, probably just Pawn and PlayerController
so route through your pawn or PC
In your case prolly the PlayerController. UI is local only
So you should go like
UI -> PlayerController -> Run on Server -> ??? -> Profit
So all i have to do is to change the logic to the player controller class ?
ya
and i call that event from the ui ?
Awesome, i will try it now
On button clicked > get player controller > Event X
Although, what are you trying to do? Modifying everyone's PlayerController smells weird
Yes, Event X being a Run on Server event
i have a lobby where players can choose between team 1 and team 2
i just want the UI to be the same for all players
That should live on PlayerState
so if i switch between team 1 and team 2 , all players will be updated
The State of the Player (what team they're on) should live in PlayerState
or at least GameState (Team Red has Players A,B,C, and Team Blue has players X, Y, Z)
Everyone would locally use that info to populate their UI
@edgy valveCheat sheet
Thank you man, now it is very clear ! ๐
You can probably just do a run on server in PlayerState, not 100% sure but I think so
GameState would be a better option innit ?
I will try some experiments and i come back to you haha
I'd prefer PlayerState then you can aggregate them to get team rosters etc
But I'd do either/or, not both. Have 1 source of truth for which players are on which team
RunOnServer doesn't work in GameState
Please read up on Ownership (:
We usually make a new AInfo Actor (similar to APlayerState, which also inherits from that) called ATeamState. (A for Actor in C++).
And then have that hold all the info about Teams. GameMode spawns those and saves them in an array.
GameState also gets the set (from GameMode) in a Replicated Array (can be done "more improved", but this works for the start best).
TeamState Actor should also replicate and marked as Always Relevant.
Then you can have PlayerState arrays in that which replicate.
That way your Players can access the Replicated Team array and then the Replicated PlayerState array.
With a bit of OnRep and EventDispatcher/Delegate magic, you can make sure that the Players get informed when the Team changes.
(and you can use the TeamStates for even more logic, like TeamName, Color, checking who's the top player in the team etc, neatly packed into one actor)
@edgy valve @dark edge
I have no experience with networking so I might sound a bit ignorant. If I package a dedicated server executable while having my OnlineSubsystem be set to steam (also have AdvancedSessions installed) and I run it on a pc, will the server show up in 'Find Sessions' (also would like to know if I would need to forward ports for it)?
hello, anyone here have a problem with the join session node fire on success but the client does not load into the lobby level?
Hello everyone.I have an drone which has replication enabled and i spawned it on server.But movement is not being replicated across server.I am controlling the drone by possessing it on server.But when i possess the player the drone is at starting position only.Thank you.
I also enabled component replication as well.
Non-ACharacter pawns have no movement replication support at all and need it built from the ground up
This course has an entire section dedicated to a multiplayer vehicle : https://www.gamedev.tv/p/unrealmultiplayer/?product_id=1500305&coupon_code=JOINUS
I'm having an issue where my OnRep functions are not being called. Also on the client-side the component has no Owner. Anyone knows if im making a stupid mistake? (Component is replicated)
Components can't be arbitrarily replicated, their outer has to be a replicated actor.
And the component itself needs to be replicated - you're replicating the pointer only
The outer as in the character actor onto which it is attached correct?
Yep, when you create the component you need to use NewObject<UMyComponent>(SomeActor)
@bitter oriole Is it simple server call and then rpc call for replication or is it more complicated
The NewObject doesn't really change anything for me under the hood. It currently seems to work the same as CreateDefaultSubobject (according to logs). I think its more of a timing issue on the client side. Idk if the OnReps will be called once initialized but I guess I need to do some more logging. Weird thing is everything was working fine yesterday untill I added two variables
@bronze summit breakpoint AActor::OnSubobjectCreatedFromReplication
and see what's going on
Will try that. Its also apparently common for that specific component that sometimes the detail panel in UE goes blank and I have to rename the variable. But thats more of a hotreload issue I believe
yeah, never do that
it also doesn't take kindly to renaming the component in c++
or changing its class via FObjectInitializer
note that the above function won't happen for components on the CDO
just created and replicated at runtime
It is quite a lot more complicated
Aha the function is not being called or atleast not hitting a breakpoint
Hey guys, how does one connect multiplayer using LAN ?
that would indicate no component created at runtime replicated
open <ip> in console, or sessions with the default NULL subsystem
This is how I added it to the class Is there some kind of crucial flag/step Im missing? As the InventoryComponent I handle exactly the same which does call OnRep's succesfully
If you are creating a component like that, more work is required
in constructor, you use createdefaultsubobject
that component is not net addressable
Yeah but both NewObject or createdefaultsubobj have equal result in this case they both wont hit the breakpoint
because its not a default subobject
default subobject components are not created from replication
so they don't need to hit that breakpoint
they are instead spawned with the actor, and have NetGUID assigned to them
yes, memory address would be of little use sent over network, NetGUIDs are sent instead
So do replicated components push an initial OnRep when they are created? So lets say I change a variable that is replicated on server, after that the component is created on client and thus onrep called because it already has changed on the server?
Because that might actually be the issue on my end
"sessions with the default NULL subsystem" .. can you elaborate ?
The OnRep will be called anytime a new value for it is received by the client, and/or when the object pointer resolves to something else.
If it wasn't created at runtime, then the OnRep will not fire - but a default subobject pointer shouldn't be replicated anyway
Using the engine's sessions system.
Guess i did not ask the right question, what i try to know is how to connect a multiplayer game using LAN !
because i want to test my game with my wife !
Well yeah, that's what you asked
I answered that the easiest method is the session system, using the default ("NULL") built-in online subsystem, that only does LAN
Look up Advanced sessions plugin, put up four Blueprint nodes, enjoy instant LAN matchmaking
The second method I suggested was the "open <ip>" console command which works just as well, except manually, using the IP address
Thanks, will try that
My set master pose still does not work in multiplayer , i can't continue to work
help please
It doesn't have any multiplayer functionality
You have to handle different clients setting it up yourself
i make a multicast from the server which calls the set master pose
so the clients execute it locally$
i don't know why it fails
the skeletal meshes are replicated components
is it about it?
Skeletal meshes don't have any network feature, so you have to carefully replicate everything you do on them on every device
i was wrong , they are not replicated , ther's just a variable repnotify
That's replicated
@chrome bay regarding that BeginPlay triggering after OnRep events thing from a few days ago, if you have 2 RepNotify variables being set in sequence, will they reliably replicate down in order?
Nope
It appears they do when testing with 10% packet loss and 200 ping
Hmm ok
Thanks
I'm setting on as part of a deferred spawn and the other after the spawn completes
So not sure if that affects it
They'll very likely do it most of the time, but there's no gurantee, if the first one is lost in the network it won't be resent
Ok got it thanks
This is all for an edge case where a projectile explodes too quickly after being fired so the tint isn't set yet as the original repnotify variable that inits the projectile hasn't reached the client yet
So the client gets the exploded variable before the init variable and explodes with default colors and FX
yeah variable replication is not ordered
So I guess the solution is to check if the tint is uninited on the client and call the same logic twice
Thanks
If you need properties to replicate atomically, put them in a struct together
And make the struct atomic
In this case it's an edge case where a projectile explodes too quickly after being fired (if firing into a wall close to you)
Causing the explode repnotify to rep down before the init repnotify var potentially
It happened all the time when I was initing the projectile with BeginPlay as the on reps always happen before
yeah that can be a tricky case to handle
But now since changing I never notice it
But as said
It could very well happen
Just curious what this means? Serialized as a single unit, does this mean it ensures the entire thing gets repped each time rather than only the changed properties within the struct?
Is this the correct way to mark it?
USTRUCT(Atomic)
struct FProjectile
{
GENERATED_BODY()
UPROPERTY()
AActor* A;
UPROPERTY()
AActor* B;
FProjectile()
{
A = nullptr;
B = nullptr;
}
};
I'm fairly sure structs replicate atomically anyway, so if you change two properties in a single network frame, you should receive both changes together and never individually
But ofc if you change a property, then network sends out updates, then change another property, then you would get multiple on-reps in different states
But failing that ofc you could also guarantee it by creating a custom NetSerialize(), but you lose the per-property replication ofc.
Ok good to know, in my case in other examples I'm setting both at the same time, so should be fine without marking Atomic?
As they are both set in the same frame
I think so, I think I saw some mention of it on UDN a while ago
And I'm also fairly sure I have some things riding on that too ๐
Might be no harm to mark it then I guess? ๐
Or is there a downside to marking with Atomic?
Not sure actually
It all seems to work fine without it but of course I haven't seen what it's like with 12 players in real world conditions!
Emulation can only do so much
Some interesting stuff from UDN:
When an actor is replicated all of its changed values will be sent as an atomic update. This means that we guarantee if you receive the update, you will receive all the properties that have actually changed in that update. This includes subobject properties as well.
What you can do in order to treat a struct as atomic is to force it to use a custom serializer, see FVector or FMovement for an example of how we do this.
But I guess, the first comment sort of overrules the second - if the entire actor is replicated atomically, then it wouldn't matter for structs individually :/
Shame there's no easy way to test this
Yeah.. I don't 100% trust this even from them ๐
Good morning guys. Look, I watched the third video of a tutorial about multiplayer games using listen servers in UE4. At this point, we have created the first class with attributes that will be replicated over the network. But what I don't understand is: In the first video, he didn't code anything, just set the project to 2 players and to run as a listen server and set their viewport sizes and BAM, they're sync and can see each other. I did the same but, i have 3 players, 1 server 2 clients, but they're not sync at all. What is the reason behind this? Apparently, they are automatically sync after his first task, no code involved at all. (https://www.youtube.com/watch?v=JCjSyzXv9CQ&list=PLD1wDiU3QkLKvSFrE6P72FFkgsJAv9-el&index=2), but they aren't in my project, sometimes one of them see another one, but the other don't see him, etc. Also, in the first class he have create , he used bReplicatedMovement to sync actors between peers, but it seems that is deprecated, so will bStaticMeshReplicatedMovement do the job, because isn't working neither?
Create the project through the Epic Launcher, Make the test level, and setup the simulated clients to test our work.
Btw he used the third person template, I used the twin stick template. Apparently, the Third Person template goes fine, but something in the Twin Stick is messing around with the synchronization.
@grizzled stirrup I had the same problem a few weeks ago in The Ascent.
I can't 100% recall how I fixed it
But I think it had to do with simply giving the Actor some time before destroying it
It's a "common" mistake to instantly destroy the actor
Sometimes it makes sense to just deactivate it (hide, etc.) and destroy it 3 seconds later
Iirc I used a struct with information about it being exploded, which I use to explode it locally if it's not too long ago
There are some solutions
Guys, how can I replicated a Pawn position over the network? I couldn't find an example
set bReplicatesMovement
then set its location on the server
if you need to do it smoothly, you need some interpolation system, for example the CMC, interpolates the character mesh but teleports the capsule
Thanks for your reply! I'm using the twin stick template, and I tried to change the code to do movement using another way. It happens that the code has problems on other parts so i decided to stick with the template code for the pawn, and the code moves the ship using RootComponent.MoveComponent(). Based on that, do you think that I have to do is first to store the FVector used by this method, mark it with ReplicatedUsing= in the UPROPERTY, create a RepOn_, and implement the GetLifetimeReplicationProps(), and using and authority guard inside the Tick() where the RootComponent.MoveComponent() is called, using hasauthority?
{
// Find movement direction
const float ForwardValue = GetInputAxisValue(MoveForwardBinding);
const float RightValue = GetInputAxisValue(MoveRightBinding);
// Clamp max size so that (X=1, Y=1) doesn't cause faster movement in diagonal directions
const FVector MoveDirection = FVector(ForwardValue, RightValue, 0.f).GetClampedToMaxSize(1.0f);
// Calculate movement
const FVector Movement = MoveDirection * MoveSpeed * DeltaSeconds;
// If non-zero size, move this actor
if (Movement.SizeSquared() > 0.0f)
{
const FRotator NewRotation = Movement.Rotation();
FHitResult Hit(1.f);
RootComponent->MoveComponent(Movement, NewRotation, true, &Hit);
if (Hit.IsValidBlockingHit())
{
const FVector Normal2D = Hit.Normal.GetSafeNormal2D();
const FVector Deflection = FVector::VectorPlaneProject(Movement, Normal2D) * (1.f - Hit.Time);
RootComponent->MoveComponent(Deflection, NewRotation, true);
}
}
}```
I'm asking because I never did it =S
Or must I only replicated the FVector property that i must create and replicated together with a FRotator property , replciate them, and only change the names inside tick, based on the information that the server runs the tick method ehre ?
Pretty complex topic, it's really not the worst idea to read a bit through the CharacterMovementComponent
Thanks for your reply! 'm inexperienced, but a task was asked to me
Also, isn't not a Character, since I'm using the Twin Stick template, its a Pawn
Well, does your actual Mesh looks like a human character?
Because there is no need to use a pawn then
Could you give and example about how to set the location on the server?
Its a ship, is not even rigged, its just a mesh without skeleton
I need to solve this today XD and there is no example in the internet
The deadline is today
That aside, your Tick function is missing the Super::Tick call