Expanding on what Kamik said: variables only take up bandwidth if they're replicated.
Just to note (since the way that was explained could seem like more replicated variables == higher RPC function cost), those replicated variables won't matter in the context of sending the actor pointer to the server via an RPC, but rather affect the bandwidth that actor is using for it's entire lifetime as a whole.
#multiplayer
1 messages · Page 50 of 1
Thx for fixing what I said ^
I should've been more clear about what I meant there.
where is best place in multiplayer game to store player team, score etc ? in his pawn not I suggest or?
because when I set his team and so on in map of menu and lobby and then join session my player state will get reset so I lost all informations
and I am now using game instance for this
it persist throught all game
player state
wait didn't read everything
I would store it in the player state and then use some way to share information between levels. It can be a game instance susbsystem or using the options string to load the level
okay thanks
Hello, I'm trying to replicate an array of uobjects, but whenever I add any, only its owner and the server receives the actual object, meanwhile other clients get a nullptr. The objects are added on server side. For example, if the array is empty, and I try to add 5 objects, the server and the owner will have these 5 valid objects, while other clients will have 5 nullptr inside the array. The array is marked with Transient and Replicated properties, and inside GetLifetimeReplicatedProps I just use DOREPLIFETIME on it. What may be the issue?
Have you made a custom UObject class that supports replication? They don't support it natively so if you haven't, that's why they're null on clients.
Jambax has a nice write up on adding replication support to UObjects here.
https://jambax.co.uk/replicating-uobjects/
It's good to note that is the old way, there is a newer much simpler way
Ohh? 
I'm actually storing actors, sorry that I wrote uobjects 😅
What actors? could be that the actors don't replicate to simulated proxies
Just AActor
I presume that's new/specific to 5.1?
Are your actors actually marked as replicated?
Yes, they are. I do bReplicates = true on the constructor without changing it in the BPs
Then I would make sure that it replicates in the first place, because you could be thinking that it's replicating to the owner while in fact you are adding them yourself
Other than that I'm out of guesses
I'm not adding them myself. What I do is whenever I press a key a function is called which calls another function that is marked as Server, Reliable and WithValidation, which actually adds the object
Do you have any code samples of your header (the replicated property), how you're adding to the array and your GetLifetimeReplicatedProps?
By "code samples of your header" you mean this UPROPERTY(Transient, Replicated) TArray<class ATestObject*> TestObjects;?
Yes, that's the one
That part looks fine
That's the answer to the second question
void AddTestObject(const FInputActionValue& Value);
UFUNCTION(Server, Reliable, WithValidation)
void Server_AddTestObject();
initially AddTestObject is called, and then server version is called instead
And the GetLifetimeReplicatedProps has DOREPLIFETIME(AMyCharacter, TestObjects);
Could you post screenshots/snippets of/the code for AddTestObject and Server_AddTestObject
So far everything looks like it should work
Sure
If I don't do Owner = this, only the server gets a valid object
This is the TestObject constructor, you can see that it's replicating
Hmm, so the owner and the server see that these objects are 100% valid (you can access properties, etc), but not other remote clients?
I'm not sure that they're 100% valid, but I can see that they aren't null
I just made a simple debug function that runs on the caller, that's the way I debug it 😛
I'd recommend, on the owning client, just check the TestObjects array and see if they're all valid, log/on screen message their location or something every so often
On my listen-server I have 2 clients. I add the objects on my first client. The second client sees the array with some invalid objects (first screenshot). The first client and the server sees them valid (second and third screenshots respectively)
kk, will do
Oh, well, in order to see the output log I went to open it, and saw a bunch of warning about the absence of root component on my TestObject. After adding one, I tried to check the validness, and everything is valid now
But the thing is that this is happening on another project as well, where the actual objects that I'm trying to add do have a root component
I actually ran into that myself recently, I also had to add/set a root component, quite an obscure issue that I've never seen mentioned anywhere really.
As for your other project, there could be something else going on
First of all I will try to check the output log in that project as well 😛
There are no warning, but it has the same issue
I will compare everything array replication related, and then tell what's going on 😄
It's checked in IsNetRelevantFor, and if no root component exists then the actor isn't relevant
It's mentioned in the docs https://docs.unrealengine.com/en-US/InteractiveExperiences/Networking/Actors/Relevancy/
Thanks for the explanation to that, In the 6 years I've been in Unreal, I'd never needed to create an actor without a root component (had to do so recently for my inventory component wrapper actor), so it was something I'd missed/hadn't needed to "go looking for".
I really need to get involved with a project that's not one of my own again, my knowledge growth kinda stagnated to a "need to know basis" when I left my last one in like 2019 
I can relate
I still have the problem 😦
My base project is the UE shooter game, what I need to do is to give a weapon to a character inventory. Whenever I use a pickup, a function called GivePickupTo is called on each machine. I execute the actual thing only on server; what I do is that I create the actor, set the owner and add it to the replicated array. However, the actor that I create isn't valid on each client, but, as I said before, only on the client and on the server.
The array is marked with Replicated and Transient properties. Inside GetLifetimeReplicatedProps it's used inside DOREPLIFETIME macro, hence should be replicated on each client. Both the character and the weapon are replicated (bReplicates is set to true).
What may be the issue?
Edit: Marking the weapon as Always Relevant fixes the issue, however I still don't know why they may be irrelevant in this case (even after reading the relevancy docs).
Hey everyone! Having trouble with a local player subsystem when playing a multiplayer game and wondering if anyone has some insight. We launch the game as standalone, then after making a party and lobby, we send the players to the gameplay level with one being the listen server and the rest clients. The host seems to get his local player subsystem fine, but the clients either don't or they get destroyed. Any ideas?
Sounds like a great idea to debug IsNetRelevantFor and figure out what's failing
LocalPlayerSubsystem exists locally, so depends on where you are retrieving it from it could be null on clients
I tried to put a breakpoint on both Pawn's and PC's overrides, but they aren't triggered at all, and there is no override for that function on AShooterCharacter and ACharacter
(AShooterCharacter inherits from ACharacter)
First thing you don't want IsNetRelevantFor version of neither Pawn no PC
They are replicating fine
What you want though is the one for the actor which you have issue with
Which means you should look at the generic version of AActor
Doesn't the weapon actor make use of the owner's one? Look at the second screenshot, at the end there is this line - bUseOwnerRelevancy = true
Doesn't it mean that it should call that function on the owner - AShooterCharacter?
But if I'm using it from my player controller that should always be local right, even on a client?
Correct, it does (didn't look at the code before)
Then figure out why the function is not triggering
Because it should™️
Right, but there is a high chance you are calling it from an event that runs server-side and that you use GetPlayerController(0)
I could keep guessing considering the lack of info you shared
I mean, it doesn't trigger at all, even when I fire the game 😦
Not just for that particular case
I do run debug game editor
I know, which is weird
Any other breakpoint works fine
In which is not a #multiplayer issue anymore
True 😄
If you lack the debugging capabilities then you're doomed
I would tackle this part before anything else
kk, thanks for the help though 😄
Yeah it is using GetPlayerController0 but the client should have ownership of the actor it's on since he posseses the pawn. I'll send some blueprints in a sec.
Well I guessed one thing right
My next guess is that the event you use is Possessed
Wizard woke up and chose violence.
My guessing skills has turned wild
Also hello 👋
Also correct lol
so let me show you real quick
Can I get the medal of guessing real quick?
thx
What you want to do instead is client RPC on Possessed and do your stuff inside the RPC
So I am trying to click an actor that is on the pawn i possess and broadcast that click to my pawn using a local subsystem
That is if you use BP-only™️
My controller subs to the broadcast OnPossess:
So does that OnPossess not happen on a client?
Wait
Aren't you IN the controller?
This is the Controller BP
yes
Not Pawn one
Take that medal away from them
Then it's just self
I've never seen that node (from ID) let me look into it real quick
But sounds like a split-screen node
i was under the impression that getcontrollerID0 was always your own
That's relative to where you call it
then other IDs would be others on the server
And redundant if you are in the controller bp
Locally that is true
If we ignore split screen shit
Man you guys are awesome. I thought I was taking crazy pills over here.
Yeah those are free of charge when doing multiplayer
LMAO
Cedric ate all of ours though.
In the making
Seems like I missed the ID version
Also what's funny is I was literally writing the part of Possessed lol
This is what was failing. I can click my cards on the server and attack with them, but the clients can't. I will try this change in a build and update you on what happens.
If not using BP's I still don't see why you would ever want to use a RPC in onpossess though. Client side always gets a callback from one thing or another.
Thank youuuuu.
APawn::Restart ❤️
Yeah that will be addressed
And hopefully a kind soul will PR an exposed event to BP
While we watch it get... 
I mean
Not using GerPlayerCharacter etc is also a bad advice
I think it's better to explain how to properly use it
Otherwise we get a Tick situation
Where people just read it's bad and try to never use it
Correct, that's why they are my own tips at the end of the day, and I also say don't use them unless you know what you do
My screenshot is clearly cropped
There is no need for that rpc
What is it?
OnControllerChanged or so
😱
Check the overrides
Although I did do it in my spaceship game 😛
I think we lost Wizard
🥲
This is the closest I could find but without any real usages
/** gets triggered shortly after a pawn's controller is set. Most of the time
* it signals that the Controller has changed but in edge cases (like during
* replication) it might end up broadcasting the same pawn-controller pair
* more than once */
UPROPERTY(BlueprintAssignable, DisplayName=OnPawnControllerChanged)
FOnPawnControllerChanged OnPawnControllerChangedDelegates;
From GameInstance yuck
Let me look at the chain of possession
/** Event called after a pawn's controller has changed, on the server and owning client. This will happen at the same time as the delegate on GameInstance */
UFUNCTION(BlueprintImplementableEvent)
void ReceiveControllerChanged(AController* OldController, AController* NewController);
Sheesh
Also I hate this. A game with no real hacks possible in the main modes still getting 'cheated' on 🥲
Wow that blew my mind. Since when it's a thing?
I would feel bad if it has been there all this time
4.27 didn't have it iirc
Well then that's a sign of relief for me 😌
I've been playing it recently, feels cool
The game is nice yes xD
But the fact that AI now shows up in online matches who are better than the average player is not so fun lol.
But not in ranked or?
Yeah I was faced by a very good AI yesterday tbh 🥲
No, in ranked too now.
Yes. The fact that a game that's cheat proof is likely going to need an anti-cheat sucks.
Where they faced you against AI if you lost and just gave them names of random players with their skins etc to hide it
Just to keep you happy
Psyonix must have jumped on the ChatGPT wagon
The story (likely) behind it is that one of the community machine learning bots is being used in ranked matches by a third party.
Because that bot can outplay regular players until a certain high rank. Which is not cool whatsoever.
Oh I didn't get the memo that it wasn't official bots
They are not official yeah.
That's exactly why it sucks if you ask me. No game is in theory safe from it even if you were to have a game (like Rocket League) that from a technical perspective has no hacks 😦
Although I doubt it will be common for some time as machine learning is complex, but the idea of it being used like this sucks.
will this be available somewhere as a vid or doc?
The latter
Check latest message in pins
Or even better, click my face and you'll figure out how to get notified when that happens
I am making a first person multiplayer melee slasher. you can turn your upper body independent of your lower body to an extent both in pitch and yaw and that is animated via a two-dimensional aim offset (using the kubold longsword animations from the market). Everything looks great single player, but the animation offset doesn't replicate so the swings look a little wonky multiplayer as other players don't see your head turning. Currently the way the body is facing is the player controller direction and then there is a camera that can rotate independently that is used for the aim offset. The player controller naturally replicates so all the movement and body orientation looks good. For the camera direction that drives the aim offset, is there a standard way to replicate that using the CMC or a best practice for setting it up myself?
You usually set the ControlRotation
And then drive the anim via GetBaseAimRotation
Which uses a replicated pitch value for simulated clients
I'm guessing the same would apply for a third person melee slasher
That's what I ultimately am trying to build. I'm using lyra as a sandbox to test melee animation / systems.
I'm trying to figure out the best high level approach to make the attacks fluid. Is it possible to use control rig to control the hips and feet (that supports multiplayer) to turn in the direction of the target? This is useful if the target is slightly left or right of the player and I want the player's character to soft lock on to them while swinging
Or is that typically just done with math and animation blending with premade poses?
So, I have this in my PC, what I'm trying to achieve is to bind my GA to my input settings, but OnRep_PlayerState & SetupInputComponent checks the ASC and fails on every try, is it because the ASC variable should be replicated? I'm testing this on Play As Client btw
I made it so that when you swing it rotates the upper body to match the direction of the lower body whilst playing the swing animation and it looks fairly nice, basically starting a swing calls a “rotate body to head” function that uses interp
But then the character would always have to be facing the target right?
If the animation plays a forward attack animation, and the character is slightly to the right, then I can use root motion pull to align it, but then it doesn't look natural
Yeah it does require that you turn your body to your head as you swing. I was playing around with Mordhau and mortal online and that is roughly what they do
No, it's a reference to the PS ASC
I don't have the ASC set as a replicated UPROPERTY in my project
but in the PS constructor I set it's replication
AbilitySystemComponent = CreateDefaultSubobject<URaevinAbilitySystemComponent>(TEXT("AbilitySystemComponent"));
if (AbilitySystemComponent)
{
AbilitySystemComponent->SetIsReplicated(true);
}
You probably also want to set the replication mode to mixed
And what's the difference on doing it in the constructor or using UPROPERTY macro?
I was just pointing out that I didn't have it set as a replicated UPROPERTY, because you asked if that was the problem
this fixed it, now I have 4 player combat working in the game! You are a life saver, we had so much frustration here.
I assume you are creating the object right?
Now is time to credit
I think I did all you mentioned before
Wait, aren't you supposed to call Super?
lol ill send you some swag when we get this puppy out
I think not
I would try it. I've encountered odd behavior when accidently forgetting to call Super on some of the built in classes
Ahsolutely you are or it takes the default constructor without the objectinitializer
As the famous saying goes "Those who think do not know"
Hi! quick question about stat modifiers.
How would you go about storing stat modifiers on a multiplayer setup, something like Path of Exile, Torchight, Diablo, etc? (Additive, Multiplier, etc) and updating them as they come?.
*Just add them all into one float and recalculate when modified.
*On each change, recalculate everything and start from 0, grabbing all stat modifiers from all sources again and doing the calculation after.
*Save each modifier with One ID and when equipment is removed, go and search all the modifiers by ID and remove them
Etc
I think the best performance option is to just add them as they come into one float and do the calculation for the stat affected, but that would require that when item/buff/anything is removed, you need to be sure that the opposite stat modifier value got removed too.
Not sure if that is reliable enough
So I changed it cause the ObjectInitializer was an old implementation, but still does not work, don't know why
The server should be modifying them, not the client. All you need to send is the data to display that a stat modifier is active to the player. Or instead of data just do a reliable RPC request to add and remove them.
I can get the reference from the PC, or it's getting it too late
I'm okey with this part, what i'm having troubles is working out how to store the damage modifiers in a way that doesn't lead to recalculating everything when you get one buff on/off.
And that is reliable on knowing that the modifiers in place are the correct ones and there's no trash from buffs or other sources that are outdated
What do you mean by store them? Can't you have a variable for each one?
yeah, let's say that i have
Power Attack
Base
Additive
Multiplier
When you equip a new item that has +25 base
How do you account for that?
PowerAttack.Base + 25
and when unequipping the item you do
PowerAttack.Base - 25
Or you do an array of "Power.Base"
that has Float / ID
and check by ID before removing
I'm asking more of the general structure of how to store them and update them
Oh can buffs stack? Like multiple damage multipliers?
Is stacking a desired feature?
depending on the type of modifier, yeah.
Currently I have one variable with this for each stat
so when I update something, I start from all on 0.
Gather all the modifiers from different sources (equipment, buffs, etc).
Sum them up depending on the modifier type and fill that variable on the picture above
and after that do the basic calculation
but I don't think it's scalable at all and i'm not sure how to do it in a reliable way that allows for "Just add/remove this one modifier, don't start from 0"
Make 2 functions and a variable total. The first is used to add to the modifier list, and will calculate the total and store it in the total variable for that modifier type. The second function is used to get the total from the total variable.
So what you are doing is calculating the buff only when it's edited.
If you need to remove buffs, then make a function to edit the list that then calculated the new total and stores it in the total cache variable.
Does anyone know why the Movement mode on the CharacterMovementComponent is different between server and client ?
on server its set to Navmesh Walking
on client its set to Walking
trying to debug why the character stutters going up and down hills but only on the client
So you do?
Buff On: Stat modifier +15
Buff Off: Stat modifier -15
Without checking sources or anything? it sounds to me like that will evolve into a lot of bugs really quickly
No, I'm saying make wrapper functions that cache the result.
So what happens is everything is calculated when editing, removing, or adding, but when reading it uses the cache value so nothing is calculated.
You completely missed the point of my message
you are supposed to use the objectinitializer constructor, and call the super
or you break parent classes in the hierarchy
If that doesn't make any sense I strongly recommend brushing up on C++ basics before continuing to try and program a game in C++ using Unreal Engine
I think that's what I have right now
I'm not using GAS, but i'll check that one out, didn't knew about it
If you are caching your stats then I don't know what else you could do.
Small but important keyword: most* 😄
Is GAS the usual way to go with this? I would need to do a total revamp of the skill system to account for gas, not sure if that would save troubles in the long term or bring more
GAS has a steep learning curve, like everything. If you already have a system in place that would require a serious time investment to revamp, it's most likely not advised
It's perfectly possible to build a game without using GAS
I would stick with whatever you have, and upskill during non-development time on GAS, before using it in an actual project, or be on a team that has learned the lessons the hard way and you get the easy DO's and DONT's list alongside with the C++ implementation and BP usage to look at
Yeah, I'm looking at GAS and it seems a big investment for the rework, I'm seeing on how to modify my system
is adding a reference to the source of the modifier a viable strategy?
public class Item
{
public void Equip(Character c)
{
// Create the modifiers and set the Source to "this"
// Note that we don't need to store the modifiers in variables anymore
c.Strength.AddModifier(new StatModifier(10, StatModType.Flat, this));
c.Strength.AddModifier(new StatModifier(0.1, StatModType.Percent, this));
}public void Unequip(Character c) { // Remove all modifiers applied by "this" Item c.Strength.RemoveAllModifiersFromSource(this); }}
not sure how much memory a reference costs
Well assuming you're storing a reference, aka a pointer, the size of a pointer, so on 64bit ... 64bit
sizeof( x )
Or google 😄
Hey, Root motion in 5.1 is broken in multplayer when allowing rotation. Any hints or ideas will be much appreciated.
Reported this bug about a month ago, it is a new behaviour in 5.1. I’ve been able to reproduce it in a blank scene.
Steps to reproduce:
-Make a character with an AI controller and focus the AI on a moving player. Make sure that you let the character rotate towards the desired rotation in the character BP.
-Add some logic in the character AI to play a montage with root motion as shown in the video. Or use GAS. Replicated.
-In the movement component set allow physics rotation while root motion to true.
-Create an actor with a SM as a floor for the characters. Rotate the actor to something different than 0, i.e Z=90.
-Play as a client.
Result:
The AI won’t consider the Ground actor rotation, won’t update the root motion rotation, and will end up teleporting to the authoritative correct location.
Expected:
The AI character will update the rotation and consequent position and won’t teleport when ended since the client and server will be the same.
Notes:
I’ve seen many changes in the movement component diff of 5.1 related to root motion, so might be related. It is a deal breaker if you are using root motion on multiplayer at this moment.
I'm also having some similar problems with root motion
I reported it and documented, sadly is not yet pull as a bug.
But it is def a new behaviour in 5.1
And sadly, no work arounds
5.1 root motion has some issues
there's a non-related issue I fixed of notifies not firing the 2% or so of the time
So I am trying to replicate my animation offset and it sort of works but it seems to only update occasionally (I think when an GAS ability is used, maybe occasionally otherwise?). My animation blueprint update animation event has this, and then I used those two variables for the animation offset and they are both set to replicated. Any idea what I am doing wrong? I am a noob so it may be (almost certainly is) something stupid.
Sadly I don't see related reports. Afraid is not getting enough attention.
https://issues.unrealengine.com/issue/search?q=root+motion&resolution=unresolved&component=&sort=created
GetAimBase returns a different value for local-players and clients
GetControlRotation requires access to the Controller which simulated proxies won't have a valid reference for
not sure if they are even reported
I did twice 😦
I see, what is proper way to do it?
Will see, the movement component in 5.1 has some key diffs in regards of root motion, but looks like a rabbit hole
The easiest way would be to create duplicate of these values, update them on tick, and set them marked as "replicated" with condition-SkipOwner
any one have idea how i can fix this desync ? it happens on 6-7 objects when client loads attached object
i cant send rpc from client to server on actor to force the sync because actor do not have the owner and it will never will have... because of dedicated server
i'm done with training to fix it for past 1-2 days and the same issue at the end
- info
object is already attached when client joins
works fine if client is already in game
attached object count is around 80 but i tested it with ~190 at the end 6-7 objects have location and rotation out of sync with server
I do hope you looked at my code review. I'm assuming there's similar problems in different parts of the code that may result in out of syncs
Namely when your execution stops that you didn't account for
@native vector here:
https://discordapp.com/channels/187217643009212416/221799385611239424/1061023282515685466
I would start with cleaning up the logic that's handling your objects
And if you stick with default UE networking and replicated actors ... desyncs are not a thing
desyncs are not a thing
so what is this ?
#multiplayer message
- editor is a server server
- PIE window is a client
less objects, server view
client
I tried doing this and it almost works but its really weird, on other players screen the character looks like he is twitching occasionally like the replicated value is filled with garbage randomly and then corrected to the proper value, I throttled it so it is on took but only if its been more than .25s since last update (or even 1 second) and it still happens.
Is the twitch occuring on SimulatedProxies?
If the character is a SimulatedProxy you probably don 't want to update the variable (Because what's happening is that its getting updated locally, and than the server is going to override it on an update, and these two values are going to fight with one another)
err You don't want to update the variable locally, but you DO want to update it to whatever the server is sending to the simulated proxy
Both entities are roughly the third person template default character, I need to read on what simulated proxies are but what you are describing sounds like what is happening
(IE only update the "MyAimBaseRotationCopy" on locally controlled players and the server, and have the server replicate this value to the non-owning proxies)
SimulatedProxies == anyone that's another client. (IE I am player "A" and I see player "B", "C", etc, from playerA's perspective all other players in the lobby are "SimulatedProxies")
but from player 'B' perspective player 'A' is a simulated proxy (So 'who' is a simulated proxy is dependent on 'perspective')
So I do something like if has authority when I am setting the replicated variable?
If you can give me about 10-20 minutes, I'll post how I go about having replicated aim offsets.
Yeah so in Tick (assuming we're in the Character class)
if (IsLocallyControlled() || GetLocalRole() == ROLE_Authority)
{
//update my vars
}
That would be awesome, thank you
BP only, yes?
I am trying to do it in BP but I am a developer, just new to unreal, I can read/write C++ just fine, but trying to use BP mainly
that worked
That's exactly how it works in my game too 🤣
thank you so much lol, have been stumbling through things but occasionally random dumb road blocks can take me hours and a quick helpful answer is sooo appreciated 🙂
Don't need me to grab my solution anymore?
I'm kinda curious on your approach, I know there are a handful ways how to do it
I'd definitely still be curious if its not too much effort, always really good to see multiple ways to solve a problem
Welcome! I think everyone has been through that haha
@rose pollen @gilded vapor This is what I do, it's purely used to replicate the clients local ControlRotation for remote clients, there's a client-side variable for local access.
// Character header.
protected:
/** Locally stored aim location. */
UPROPERTY(Transient)
FRotator AimRotationLocal;
/** Used for aim location on remote clients. */
UPROPERTY(Transient, Replicated)
FRotator AimRotationRemote;
protected:
/** Used to update replicated aim location. */
UFUNCTION(Server, Unreliable, WithValidation, Category = "Aiming")
void ServerUpdateDesiredAim(FRotator AimRotation);
void ServerUpdateDesiredAim_Implementation(FRotator AimRotation);
bool ServerUpdateDesiredAim_Validate(FRotator AimRotation);
public:
/** Gets the current location of the camera aim (with respect for if this is a remote or local pawn). */
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Aiming")
FRotator GetAimOffsets() const;
// Character cpp.
void AMyCharacter::Tick(float DeltaSeconds)
{
if (IsLocallyControlled())
{
// Update replicated control rotation for remote clients.
AimRotationLocal = GetControlRotation();
ServerUpdateDesiredAim(AimRotationLocal);
}
}
void AMyCharacter::ServerUpdateDesiredAim_Implementation(FRotator AimRotation)
{
AimRotationRemote = AimRotation;
}
bool AMyCharacter::ServerUpdateDesiredAim_Validate(FRotator AimRotation)
{
return true;
}
FRotator AMyCharacter::GetAimOffsets() const
{
return (IsLocallyControlled()) ? AimRotationLocal : AimRotationRemote;
}
void AMyCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
// Lifetime conditional variables.
DOREPLIFETIME_CONDITION(AMyCharacter, AimRotationRemote, COND_SkipOwner);
}
IIRC it doesn't replicate pitch*** yaw
yeah its possible I did something else wrong, but just using GetBaseAimRotation didn't work for me, I did try that first
Pitch is already replicated by the engine
That's what GetBaseAimRotation returns for simulated clients
Check Pawn.cpp for the impl of GEtBaseAimRotation, you can see it doesn't
that is what i was feeding into the animation offset originally and it didn't work
Post the implementation please. I'm not in reach of the code atm
There is def no need to replicate it by hand
Could you please recommend me some site or material where to find this C++ basics? 💔
Well you are technically giving it the same value twice
FRotator APawn::GetBaseAimRotation() const
{
// If we have a controller, by default we aim at the player's 'eyes' direction
// that is by default Controller.Rotation for AI, and camera (crosshair) rotation for human players.
FVector POVLoc;
FRotator POVRot;
if( Controller != nullptr && !InFreeCam() )
{
Controller->GetPlayerViewPoint(POVLoc, POVRot);
return POVRot;
}
// If we have no controller, we simply use our rotation
POVRot = GetActorRotation();
// If our Pitch is 0, then use a replicated view pitch
if( FMath::IsNearlyZero(POVRot.Pitch) )
{
if (BlendedReplayViewPitch != 0.0f)
{
// If we are in a replay and have a blended value for playback, use that
POVRot.Pitch = BlendedReplayViewPitch;
}
else
{
// Else use the RemoteViewPitch
POVRot.Pitch = RemoteViewPitch;
POVRot.Pitch = POVRot.Pitch * 360.0f / 255.0f;
}
}
return POVRot;
}
End of that function returns the replicated view pitch
....
// If we have no controller, we simply use our rotation
POVRot = GetActorRotation();
SimulatedProxies don't have access to the Controller
Which gets further modified
I am using exact same thing now, but just storing in repilcated variables as CarryDazzle suggested and it works
All I can say is that this function works for getting the replicated pitch
I never had to replicate it by hand
Simulated clients return the replicated pitch value as the function shows.
Hmm, I just tried using GetBaseAimRotation and in my case, pitch is fine but yaw is not
I never said anything about yaw though. I mainly stated that pitch is already handled
BaseAimRotation returns the Yaw of the Actor
But iirc most people rotate the legs of the characters only if the angle since last forced rotation and current is too big
The actual actor usually represents control yaw anyway
in my case it doesn't but agree that is the norm
Pretty sure there is a fully working aim offset in the content examples of ue
But maybe they dropped the ball ( wouldn't be the first time ) and didn't check it for replication
I'm like 100% sure that yaw is not properly replicated
This is likely why I went with a custom implementation, since I use the camera yaw and pitch, this is using GetBaseAimRotation(), the yaw only seems to work on the owning client, I also do a few extra things with my projects' implementation of the server RPC like sending first person and freelook states
I mispoke when I said pitch
Yaw is not, that's correct
is there a good total beginners guide to setting up a dedicated server and setting up clients to connect to it that any of you guys recommend?
Haven't used any guides in ages so no clue about any up to date once
But it also hasn't really changed
If you're just making an indie you can just go the ListenServer route (IE p2p, which is IMO a good bit easier to set up)
Download source engine. Follow steps in the readme to compile it and package the server.
Or just select play as client in pie to test in pie.
Or start standalone with -server as an option via bat file I guess, also only for testing.
Epic have a nice writeup here, haven't personally used it, but it seems to cover everything at a quick glance
https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/Networking/HowTo/DedicatedServers/
I guess that's fine. I would still have thought that the Yaw of the Actor is equal to the head here and the rest of the body follows some saved rotation. But it doesn't hurt to get yaw replicated I guess
Most of these setups also have some pretty involved root Motion setup that I never really digged into
Well doesn't have to but I usually encountered the head and upper body rotation in those
My setup is for third person idle (the camera can just freely rotate around the character without affecting the characters direction), I don't do anything with root motion, just some additive animations to rotate the upper body/head to relative +/- 90 based on the camera rotation.
Yeah that's fine. Was mostly a misunderstanding about yaw vs pitch
If CPP is available it might also be a good idea to check if one can override the involved function to only replicate yaw additionally and not a full FRotator
But then again I don't think it matters in most games
This is probably just some legacy design where they originally assumed everyone was just making first-person games
Hence no need to replicate yaw
Bandwidth is not that big of an issue nowadays
Yeah it's a UT engine after all
I likely ran into GetBaseAimRotation when I was initially implementing this some 4 years ago, but only god knows what mess I tussled with back then 😅
I think before current implementation, I did just have 2 replicated floats, but I recall in one of the projects I was working on we also needed camera roll for something to do with aiming in a vehicle that's on slope, I don't remember anymore, so I guess I just refactored to replicate the whole rotation
When playing on Listen Server mode, does the server also works as a client?
"Yes"
So if i have this code, why isn't the server logging SetupInputComponent & OnRep_PlayerState?
```c
your code here
```
// Fill out your copyright notice in the Description page of Project Settings.
#include "GAS_PlayerController.h"
#include "GAS_PlayerState.h"
void AGAS_PlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
FString MyRole = UEnum::GetValueAsString(GetLocalRole());
UE_LOG(LogTemp, Warning, TEXT("Setup Input: %s"), *FString(MyRole));
if(AbilitySystemComponent)
{
UE_LOG(LogTemp, Warning, TEXT("Binded Setup Input"));
AbilitySystemComponent->BindAbilityActivationToInputComponent(InputComponent, FGameplayAbilityInputBinds(FString("ConfirmTarget"), FString("CancelTarget"), FString("EAbilityInputID"), static_cast<int32>(EAbilityInputID::Confirm), static_cast<int32>(EAbilityInputID::Cancel)));
}
}
void AGAS_PlayerController::OnRep_PlayerState()
{
Super::OnRep_PlayerState();
UE_LOG(LogTemp, Warning, TEXT("Rep player state"));
if (AbilitySystemComponent)
{
UE_LOG(LogTemp, Warning, TEXT("Binded Rep player state") );
AbilitySystemComponent->BindAbilityActivationToInputComponent(InputComponent, FGameplayAbilityInputBinds(FString("ConfirmTarget"), FString("CancelTarget"), FString("EAbilityInputID"), static_cast<int32>(EAbilityInputID::Confirm), static_cast<int32>(EAbilityInputID::Cancel)));
}
}
void AGAS_PlayerController::OnPossess(APawn* InPawn)
{
Super::OnPossess(InPawn);
UE_LOG(LogTemp, Warning, TEXT("Posses"));
if(AGAS_PlayerState* GasPS = GetPlayerState<AGAS_PlayerState>())
{
UE_LOG(LogTemp, Warning, TEXT("ASC setted"));
AbilitySystemComponent = GasPS->AbilitySystemComponent;
}
}
Sorry, didn't know that
The c wasn't a typo!
OnReps aren't fired automatically by default in c++ if you're on a server/listen server.
So if you're on a listen server, you need to fire them manually.
mode
Listen Server, Client + server
Client, Client + "dedicated server"
Oh I forgot that
So I'll have to call OnRep_PlayerState after my OnPosses was fired?
if (GetWorld()->GetNetMode() < ENetMode::NM_Client) { OnRep_PlayerState(); }
Also the SetupInputComponent is not firing serverside
Now that I'm not sure about.
void AGAS_PlayerController::OnPossess(APawn* InPawn)
{
Super::OnPossess(InPawn);
UE_LOG(LogTemp, Warning, TEXT("Posses"));
if(AGAS_PlayerState* GasPS = GetPlayerState<AGAS_PlayerState>())
{
UE_LOG(LogTemp, Warning, TEXT("ASC setted"));
AbilitySystemComponent = GasPS->AbilitySystemComponent;
}
if (GetWorld()->GetNetMode() < NM_Client) { OnRep_PlayerState();}
}
So this should work?
For the playerstate part, sure.
Ok, that something, thanks ❤️
Np
Is there any automagic replicated ControlRotation?
Hi, im using Advanced Sessions and im trying to set up a party system to invite steam friends, I've got the friends list displaying fine, but when I invite someone its failing every time and I'm not sure why.. any idea what im doing wrong?
Nevermind fixed it lol i never had a session created 😅
Hi! last question about stat modifiers, I promise (?)
Does anyone see an obvious flaw and problem with doing a "push" setup for stat modifiers?
For example:
Each stat has 3 values stored.
Flat (Float)
Additive (Float)
Multiplicative (Float)
(Total Effective value (flat * (1+Additive)* (1+Multiplicative))
When you Equip one item, you check the modifiers it has and see what stats they affect, and grab the stat and push those values into its modifiers values.
When you UnEquip that item, you do the reverse.
This setup seems easy, you can update stats modifiers only when that particular stat is affected and it's really nice on performance.
Any Flaw or Problem I am missing?
Why this is in #multiplayer ?
You could swap messages with the last peep in #blueprint
it's a multiplayer setup, so maybe there's a reliability issue or something like that
Honestly it sounds to me like you're writing your own mini GAS system
And that's the nature of prototyping, you fix things on the go
Someone suggested to check GAS before and it's similar, but the rework necessary is not worth.
Then you could learn about what #gameplay-ability-system does and reiterate
Only cherry pick what you need (even if you could only learn from)
hmm that's actually a good idea, I checked it before but an overall view. Thanks
The GAS Compendium (CTRL + F to navigate) will help you along the way in case you missed it
This one?
https://github.com/tranek/GASDocumentation
Thanks for the info ♥
Having an issue where a client calling the server using blueprint replication isn't passing through all the variable data,
When Client_SpawnItem gives a valid non null item object to the server spawnitem... when Server_spawnitemfromactor is called it appears null any ideas?
I've been ItemObject is not addressable, is there a standard way of passing object or information through to the client server from the client?
The fact that it's alive on the client doesn't mean it's alive on the client.
Why not spawn it on the server and handle it in there?
Server_SpawnItemFromActor which is on Executes On Server, isn't that spawning it on the server?
Objects do not replicate by default. The lowest class that supports replication without any additional C++ work is Actor, so if your "Item Object" isn't a child of actor, and you haven't set up your items to properly replicate, then it may not be getting passed through the network at all.
If you are using actor as the base class for your items, then perhaps you may be spawning the item client side first? If so, then the server doesn't have the details about that item and you can't pass through the reference of the item to the server as the server doesn't have a copy of the item.
Also just to point out, it's very odd to have something set up this way. You usually do not want your clients being able to tell the server to spawn items of a particular class directly as this then allows the clients to dictate what gets spawned and when as a client could call the RPC at any time.
This makes a lot of sense now, Item Object is just a basic blueprint which inherits from Object so it wouldn't have any of the replication
Yeah I assumed this would be the case, I was going to add in checks later but it would probably be better for the client to request to drop an item in a particular spot and the server will look at it's records and stuff and choose the item
Thanks for your help
Anyone working with a persistent world model and if so at what point are you serializing / saving things? I was tempted to make another service that only digested messages / persisted to database and just toss out a message hook onRep? then if I ever needed a backup I would have the last replicated state of things to bring it back online from? Good/Bad? something already exist?
Thought I had this down pat but, apparently this doesn't create specific inventory for clients if I add a gun, it adds it for everyone, maybe I needed an authority node or something so it's specific to that controller, this is the player controller btw.
My idea was the player picks up a weapon, then chats to the server, then the server tells it's controller to add weapon, unless I don't need to do that and I can just go about not replicating anything
If I understand correctly... What you want to do is.
- client asks server to pick up weapon
- server checks conditions for said client to pick up gun
- server adds the weapon to the clients inventory, or whatever you're using
- server sends relevant information to client. Example: Equipped weapon
server should not really be telling the client to add a weapon, server should be telling the clients what weapons they have. If that makes sense
Yeah I see, I got my head around a bunch of replication, now the inventory is a bit of a curve ball
When dealing with multiplayer inventories... Basically server does everything, server keeps track of everything, server adds and deleted everything, clients only receive updates to the inventory when they need it, or when they ask for it
I wonder if then, I could get away with storing it on the game mode, and make a struct array of a struct that has the player controller + inventory and just compare the controller
You want to put the inventories of the players in the gamemode?
well, I was thinking then the players could talk to the server, then the server could check what inventory has asked and then do actions for that?
nah fam
There's no need to use the game mode for something specific to a player.
Make an inventory component and put it on the controller. All your inventory logic should be there
You can put it on the character but I prefer the controller as it is persistent there
That's what the struct is
I've got a struct with player data on the PC, the inventory is only like a simple pickup thing, because it's an FPS with nothing fancy
Pretty much this, it's pretty good and works for the most part
It's just getting me head around the adding item to inventory thing
stats are for controlling cooldowns and what not that are feed from the blueprint.
Client stand on weapon -> client tell server it want to add the weapon -> server add the weapon
I'm a bit confused what you're stuck on
are you trying to get it to show up in game as equipped?
yeah that's how I thought I had it setup
I already have it showing in game as equipped
your image looks more like the client is adding the weapon rather then the server
FAddGunToInventory looks like it should be the server doing that
it's just all the inventorys are linked, I have it setup that player picks up wep -> Talks to server to say they picked it up, then it talks to the client saying "Ok fam, added"
right
I thought if the server does it, it's doing it to it's own inventory
They shouldn't be linked o.O
yeah I'm a magician of smooth brains
player picks up wep -> Talks to server to say they picked it up, then it talks to the client saying "Ok fam, added"
That's not what this is doing, this is the client telling the server to tell the client to add the weapon
The server needs to add the gun to the players inventory
The CE_ROS_PickupWeapon is where you're actually supposed spawn/to add the weapon, on the server
Right so I thought something like this
-_-
Sorry to be frustrating my brains very smooth, it is without dimples.
you just added an extra step to the same exact thing my mans :p
No, you don't need to do any authority check, it will always be authority (the server is always authority), so you just call FAddGunToInventory directly after CE_ROS_PickupWeapon
CE_ROS_PickupWeapon -> FAddGunToInventry -> Nothing, you're done, if your weapon/inventory is properly setup/replicated, the client will just "know" it now has a gun
Oh
Multiplayer is hard

I advise you take a read into the Server -> Client model documentation for Unreal and probably read through eXi's Networking Compendium to get a better understanding on how to make the things do the things 🙂
https://cedric-neukirchen.net/Downloads/Compendium/UE4_Network_Compendium_by_Cedric_eXi_Neukirchen.pdf
It is when your brain is smooth, and yes I had a look through that, the penny hasn't dropped for inventory for me yet, I got most things working find though
Currently the server is hogging the inventory, I did replicate the inventory now
What do you mean by "The server is hogging the inventory"? 😅
So when the client picked up an item it went into the servers inventory
I feel I'm missing a small bit of code to tell if it's the server or clients inventory
I picked up an item with server and 1 client and it all went to the servers inventory
which makes sense that's what that bit of code is doing
What BP is all this in? https://cdn.discordapp.com/attachments/221799385611239424/1061526258858590268/image.png
PC
Is this in your "pickup"
I realize I should have this in pickup and authority maybe
How're you doing your "triggering" of the pickup code? I.E where is CE_ROS_PickupWeapon being called from and how?
Checking for authority on a server event? 😄
what do you mean you wont teach me?
GetPlayerController 0 is your problem, that's always returning the servers controller, you want to get the controller from the "OtherActor" you're casting to your character class
Oh
Right
As BP Player Char -> GetController -> Cast to PC_C_LevelBase -> call CE_ROS_PickupWeapon
Ahh yeah right right, I see
then that calls the appropriate PC for the updates and what not
Correct
You are checking authority on a server event
In the case where the remte branch is executed, you already got a problem, and it's not solved by the next server event it's calling
Because that chain of nodes does not do what you think they do
It's better to just make sure the the original RPC is called from a client-owning connection, remove complexity and source of bugs
We've already covered and fixed that 😛
I think 
Great work then! 😄
Ya we're past that
now I got more bugs, but they're different bugs so maybe it's ok
I have some functions that are supposed to only run on the server (and they do, I haven't managed to break stuff yet).
These functions are not UFUNCTION(Server) - they are just regular functions which only fire on the server.
I don't do Authority checks inside them, again because I know they are only supposed to be fired on the server.
However after some time I'm starting to get lost whether some function is supposed to get called only on the server, and most of the time I have to track back when and where it is being called. This gets frustrating really quickly because it eats way more time than it should.
Initially I considered adding Server_ prefix to these methods, but I'm not so sure now, because its already reserved for server RPCs.
Other thing I'm considering is wrapping entire function body with authority check, so its clear that this is only supposed to run on the server, like this
void AMyActor::SomeFunc()
{
if (!HasAuthority())
{
return;
}
...
}
I have a feeling that my design is fundamentally flawed, I'd appreciate any tips on this particular issue as well as any sample / repository that handles this kind of stuff gracefully
you can't really make that any more simple
another company i worked at had 3 different copies of each code file for the client, server and shared, it was a nightmare
How do you make those functions run only on server? Any checks are welcome and make it explicit. Maybe you are a solo dev, but for yourself in the future or others it will be very important to signal that those functions sould only run on the server
exactly this ^ if you hide it away its not explicit anymore and its not clear that its only supposed to run on the server
going down the route of making amyactor_server and amyactor_client is not good, somefunc_server and somefunc_actor is kinda pointless because if you don't need to call the same function before you call the function you'll still have to check somewhere where you are calling it from
So adding Authority checks to clearly indicate that a function is supposed to only run on the server is good I guess.
I was kind of wavering because I always am for some reason, even with simple stuff that might seem straightforward.
I guess I wanted to make sure if there is a better solution to these kind of naming-structuring type of issues, but I'm very content knowing that authority check suffices
there's no way to make it more straightforward , only way more complicated, which means overengineered if you can get the same functionality with something you can write in 5 seconds
I do LocalServer LocalClient for specific local funcs
A good rule of thumb is to not expect the caller of your function to know it's theoretical limitations.
You shouldn't need to check for server before calling if it's not supposed to run on clients
So the conditions should be handled inside of it
With said Has auth check or even with the netmode
(cause a client side spawend non replicated actor has auth too)
Hello I have very complicated question.
I am using game mode to spawn my players after on post login on map, they are choosing from start points on map I have 4 there and after joining my session I spawn normally but I dont see other players in game we are in same session I see it on log of server but we are not replicated should I call here on this on post login spawn call multicast for clients too? I thought its not needed, when I was spawning players without on post login just on startpoints it was working fine thank you for tips here I have my blueprint of game mode spawn.
- Also another question every player has stored his team in game instance I am getting here before spawn game instance and getting players team but it seems I am spawning randomly does it mean this game instance is not of player but of server and its mistake? thanks
i have a replicated player controller with a function that i want to be called only serverside:
if (HasAuthority)
fun()
if i want to run a function from clientside to serverside, do i need to do: if(!HasAuthority)?
Designating function replication across the network
-
What are you spawning for the Players? A Character or a Pawn?
-
If you get the Game instance in the GameMode you are always on the server and that's the server's Gameinstance
Also please clean up your graph when posting pictures
already looked at it, it does not answer my question
It does though?
If you want to call a function serverside from the client
you need to use RPCs on a client-owned actor
Read it again
I never knew. Does that mean if I spawn an actor on client, that actor is only on this client and has authority?
Replicated actors that are spawned on clients only exist on that client
They always need to be spawned on the server to properly replicate to others
And yes if an actor is local only and you call a function on it with has authority it will be true
Cause the client has authority over its own local actors
99.9% of a time you won't run into a problem with has authority
That sounds like spawning actors only on clients is a bad idea. Are there cases where you would want to do that?
Cause usually you use it on an actor you know is replicated etc
Yes
But it has to be pointed out that Authority does not mean server
Sometimes you want to have things only on the local client that don't affect gamestate
The easiest example here is UI
Or a predicted projectile fwiw
Otherwise some FPS games have local per client weapon instances
Or projectile, VFX, etc...
anything that doesn't impact the state of the game that could be influenced by other players
I can't say I ever used Has authority on actors I know are local
But if you want to code an actor that 100% of a time doesn't run said code on clients, then Has Authority is theoretically wrong
pawn but when I was spawning it by default on player start it was ok if you remember we tried It before many times now I am spawning them by game mode ( my pawns) and I don't see each other , also sometimes happens that I will spawn more like 1 pawn i don't know why they flu straight and I posses just mine
Hi!
Do you know which are the BRY & reubs youtube tutorials about multiplayer? I've read that they are great.
Thanks
if i build my server using the UE5 5.1 source build (required to build a dedicated server) from github can I use the download and install UE5.1 to build the clients or will they not be able to interact?
can anybody tell me why I can use destroy event only on listen client, but other clients cant trigger it?
Does anyone knows where can I get a multiplayer turn based combat project? It can be either free or paid (Please free if possible)
Why are you trying to destroy it only on clients? That feels off. Normally you just destroy actors on server, or just never replicate them.
destroy client is for multicast
destroy server is for server
Right, but why?
Why not just have a replicated actor and just call Destroy on the server?
If I want to multicast an RPC, how can I check whether the client that got the call is owner of the actor that the RPC is calling on?
I dont really know, every tutorial I watch was doing it to syncronizhe multiplayer. Im trying to make an actor destroyed when a player interact with it
If you destroy an actor, on the server, that is replicated, then the server will notify every client about the fact that the actor has been just destroyed, and every client will repeat it
That's what Authaer is saying
I tried to doing with only server but sadly it still dont work, It was working before I changed something with interact
But its only work on host now
Are you sure that your actor that you're trying to delete is replicated, and the destroy function is called on the server?
Yeah, its called on the server, actor is replicated. But it only despawn when Host interact it(it despawn on other clients too), but other clients cant interact it to despawn
And the actor is not destroyed even on the client either, right?
Yes,*, when host interacts, it works perfectly
When client do it, nothing happens
Well, that's because a ServerOnly function can be called only by the owner of the actor that the function resides in, this is the reason why the client yields no result by interacting with it
What you need to do instead is making a ServerOnly function on your actor, and make it call the interact function so that the destroy will be called on the server
I was using an interact system before, but now Im just using "enable input" when you are overlap collision box and you press interact key
It was working with the another interact systeö, so i think i need to change
I just said you the reason and kind of a solution, you need to understand the actual problem instead of switching things
Sorry I was trying to write something different and I mean trying your solution, but my keyboard cutted off
I needed to restart it, Im trying to your solution right now
I just tried using print command to check if its only destroy, but even print dont work when past this line for clients, so Is it about something different.
Game Mode doesn't exist on clients, so you can't get and cast to it on clients.
Than what can I do?
Much like you wouldn't have a client destroy a replicated actor, you have the server update the game mode.
Hey,
could anyone help me with a thread about online joining a server?
Currently I create a listen server and use a "find sessions" node to list them and then join via "join session". It seems to work fine via Lan. But I doubt it would work over the internet.
I'm wondering it the way I am starting to design this gameplay ability is terrible. I am designing it to detect the distance between the player and the target, then if within a certain range, play the in-place variant of the melee swing animation; it outside the range, play the root motion variant
Even though this is in a gameplay ability it's not really ASC specific
I'm thinking that with lag, the server could think the player is close enough but the client thinks they are still too far away and then there is rubber banding / undesired behavior
Has anyone else encountered this and if so, what approach did you take - high level of course, no need to write out the code or anything.
We usually move the player with RootMotionSources to target locations
And don't use any actual Root Motion
Interesting
Just have to make sure you either don't have a delay between Activate Ability and the Root Motion Source or you expose the Flush Server Moves call and execute that before
Otherwise you get corrections
Don't you need a curve to make sure that the capsule doesn't move too early?
I'm not familiar with RootMotionSources, so maybe that removes the need for a custom curve
I'm using root motion and I have no issues - well... you need to modify the cmc for that
Usually the main recommendation is to decouple logic from visuals
but sometimes it is not possible
so far the only inconvenience I found with root motion montages is the fact that queued anim notifies are sometimes skipped from autonomous proxies server side
thats because notify evaluation is only done on MoveAutonomous when playing montages without root motion
which is really an oversight
I do have to note that I did not have to modify the CMC for Root Motion. So if there is something to modify you'll have to point that out :x
You dont need to modify the cmc for rm to work in montages
you need it to ensure total reliability on queued notifies
@thin stratus
I didn't know that the CMC actually had an impact on animation notifies
oh it does! 😄
Since I am using animation notifies to control when to start performing traces, I will have to look into that
I just knew that they are not 100% reliable and took a mental note to track down why that is and what the work around would be
I think you just provided a short cut to that research when the time comes 🙂
We actually stopped driving gameplay from them
The few timed things we have are sections which we query and use a delay for
Yeah I was trying to think of how to avoid them but am just using this current approach to get moving
Little workaround but at least no issues
Thats what I recommend ☝️
and one of them was to use a custom curve to insert into Constant Root Motion Force
Getting away from my original question about distance syncing between client / server, I was thinking I could just always play the in-place, but then use Apply Root Motion Constant Force, modifying the strength based upon the calculated distance between the player and the target and max distance possible to travel
but then I ran into an issue where I couldn't figure out how to use the custom curve I created inside of the animation montage
It wants to be fed a custom curve, but then that doesn't account for play rate or anything like that
It's just simply a curve at that point, that has nothing to do with the currently playing animation as far as that method is concerned
yes you'd need to bake a curve
and you'd have foot sliding
cause of your variability
I'm starting to see why there are so many multiplayer shooter game examples out there
(relatively speaking)
many triple A games suffer this
As soon as you start trying to make a good combat system that is fluid, there is so much headache that goes into it versus doing a trace from the gun's barrel to what the player is aiming at
well shooters have their own complexities but by no means they match the complexities you'd have to deal with in a melee game with hit reactions
specially if you want to introduce pvp
Right, I didn't mean to make it sound like I thought shooters were easy to make
but just for a solo developer, getting a melee system working that doesn't look like a two year old made it is hard
I agree with you
As a Host, if I'm storing say 10 maps to go to back to back - Is it correct for me to save this in my local Game Instance? I don't see a reason to replicate that 100%, and I just want persistence for Host.
That's how I have it working currently at least.
yes that's fine RØ
@thin stratus do you have anything I could google to look into RootMotionSources? I haven't had to delve deep into the magic that is root motion, so that term doesn't ring a bell to me, but I'd like to learn more about it.
Oh, I'm playing around in lyra lol
so take a look there haha
So that is convenient!
^^
Ok, I'll look at the dash ability, ty.
This is interesting
So it looks like the ability runs mostly on the client
then it sends the directional values to the server and they both play the montage and apply the root motion constant force
but where is RootMotionSources being used here? Is the "Source" in RootMotionSources just a type of data to feed into the root motion system, so ApplyRootMotionConstantForce, inserting the world direction, strength, and duration - would those be a "source"?
there is a gameplay task in there
Hey,
when I use seemless travel to go from a lobby to the actual map, where the match will be played, can I use the same game mode on both the lobby level and the map level? And if so, does the information on the game mode get reset when travelling?
@pallid mesaAr eyou talking about the ApplyRootMotionConstantForce node? The only two tasks I see are PlayMontageAndWait and ApplyRM
Ok, yeah I am already using that node in my gameplay ability if I don't play a root motion animation. I just locked on to when eXi mentioned "RootMotionSources" and I didn't know what that meant
so ApplyRMConstantForce is one of those then, got it.
Yeah I went outside the scope of multiplayer as time went on. I'll think about this some more and play around with things before asking more questions. Thanks for all of the help everyone.
nono haha its okay, have in mind that the other channel is about GAS including multiplayer
Right 🙂
You can, and yes info will be reset. Look into the latest pinned message for a tour on persistence.
@fathom aspen oh nooooo...
I was hoping for the information to stay :/
I made a lobby where players get assigned to a slot in a team, depending on how many people are in either team and saved those slots inside an Array in that specific order. That way I could swithc teams and informations, by switching around the elements in those arrays. But the array with the player slots (including their order) will then be lost, right? That way, I can't make each player spawn where I wanted to ...
You can if you looked at that compendium that took months to write
alright
Again info will be lost if stored on GameMode. There is several ways to fix this issue
I opened it and will read it
But I don't find it fun to write that compendium again here
I thought that my setup would be fundamentally wrong
nah it's ok I completely understand and respect that
No. What you did is fine. You only need to take care of persisting that info. That article takes care of that
Sorry I searched it for too much but I couldnt find a key-number of items collecting to open a door system, for multiplayer. Every one of them showing it for single player and its broken on multiplayer, is anybody know any video-guide for it?
thanks a lot for the help!
If you're asking for a guide to do any system for multiplayer then you lack the understanding of multiplayer
I would start by checking the pinned messages
There's an article that goes over stateful replication, check it out
Actually I got a bit of idea about how multiplayer works as I did some destroy-door syncronizations etc. But making a working collecting system was harder than I think, for multiplayer.
“Any system” is a bit over the top lol. There are definitely things that need some explaining. But this in specific is indeed in my opinion not too difficult if you have gone through the basic stuff 🙂
If we’re talking find a key or several of them just give them an ID for example and keep track of what IDs belong to which door. Then check if someone picked them all up if they want to enter the door.
Also you can always ask any specific questions here if you get stuck on a specific implementation 😄
But I’m not aware of such a tutorial.
You must be Youtubeless to not be aware of such one
I often have the issue with YouTube tutorials that they explain nothing, just show what they did and that is it.. Sometimes nice to have but in general pretty worthless as that means I can’t solve it my self the next time if it’s slightly different 😅
So no, not often looking on YT for tutorials lol. But with some exceptions.
I also tried multicast this spawning but I dont see each other also kekw
The gamemode is not replicated to clients / doesn’t exist there. So you can’t multicast on it.
whats bad wizard ? 😄
I'll just go sneeze and pretend nothing has happened
but how then solve my problems that I am spawning pawns and they dont see each other in game?
Besides player controllers do not exist for other clients, only the owner gets the controller replicated to it.
when I disable this spawnning after on post login and I just use random spawn on player starts on map they see each other
but when I try do this in game mode and choose spawn for them
they dont see
If you’re marking a pawn as being replicated and have it be relevant for other clients and it actually spawns on the server then it should at bare minimum show up for other clients. GameMode can spawn the pawns, that’s fine but it can’t it self directly call networked methods.
what then can cause that they are not showing for others?
Either not properly set to replicate or they are not relevant, so for example too far away from each other or completely invisible is one as well I think.
Make sure you have the pawn marked as replicated and perhaps try “always relevant” to see if that makes a difference.
Or that they are joining different servers (which was what I guessed basically a few weeks ago and you confirmed it)
What's weird though is that more or less you're still asking the same question since then
If they are not on the same server then not much will happen yes 😅
no its not different server at all 😄 I have session which I am finding by button play and joining there
Literally if you open any of the UE example template projects and you set your own Pawn class in the GameMode settings then it just works out of the box
its definitely not same as we talked months ago
What's cool is that the default Unreal GameFramework handles all this for you as I said
check now I disabled on post login spawn and I am using just default spawn on player starts
So you're lucky
Correct, because that's the default spawn behavior
What you're doing is wrong basically
Which confirms what I said
but how then set for them for example 2 points where they can spawn and if one will be team blue he will spawn on point 1 and if one will be red he will spawn on point 2 how ? I thought I have to make it after on post login
If you're overriding the default behavior then you should have a very basic understanding of multiplayer, which by looking at what you sent you seem to lack
dumb question, but I am doing something wrong. I have a GAS ability that needs to be triggered with an enum value that the user inputs in a multiplayer game. How do i get that enum value from the client as part of the TryActivateAbility so that the server can validate it and then replicate it to all clients? Using blueprints for the ability but a C++ answer would help too
sorry ...
If you want to spawn your pawns in a specific PlayerStarts you could override for example ChoosePlayerStart
i thought on post login is good because it can notice me everytime when someone join
sorry...
PostLogin would work too but you would be more error prone considering your multiplayer skils
okay may I have one more question? most propably dumb but...:D
When I put player in team in my lobby and I then save it to their player state after they join session it is deleted so I saved their team in game instance but how I can get their team in game mode? because in game mode I cant get their game instance as its running on server
so how I can get to this information? where to store it?
ofc it need to be safe so it cant be stored in game instance i think
but its my solution for now
Joining Sessions is hard travel (that is not a disconnection), so yes PlayerStates won't persist
Opting for the GameInstance is okay
but cant they hack it then? I mean it is stored in client side so he can change it maybe
I already answered that in one of the forums, so let me provide you with that answer and then further explain to you a better approach
thank you very much bro
i appreciate that u are wasting your time with me here 😄
You are basically having this issue: https://forums.unrealengine.com/t/pass-lobby-data-to-game-map/724953
Read that answer and come back
The answer I gave there was before I knew about an event that is called Receive Controller Changed which fires on client without the need of firing that needless RPC I suggested in the forum post
if I understand it I will cal custom event which will be executes on client or multicast? and I will get from it game instance and my variable
hmmm okay
Though if you was to use that event you need a way to tell that you're retrieving the data from the GameInstance only once (as the Pawn can get unpossessed and possessed back serval times during a session)
Or that you can the GameInstance in sync anytime you change any of the infos so you're good on that part
and there is no another way of passsing data ? I mean something different as game instance
There is a plenty
Have you checked the monolithic compendium in the pinned messages
anyways i dont think storing anything in multiplayer game is safe and good solution in multiplayer game, isn´t it?
The latest pinned message to be specific
Not really. Otherwise how do you persist these info between levels for example.
But there is a side to what you said
IDK just was listening from every side do not use player side to store anything because its problem
thats why asking
For example storing info on the client GameInstance like you did (which is normal), would need a verification before those info are applied to the player on spawn
For example checking against an external database
Is there a specific way to do 'For Each Loops' when doing multiplayer? Im getting weird results no matter where the code is. (Server replicated, Multicast, and even Owning Client)
There isn't. Flow control nodes are clearly multiplayer agnostic
lol greatttt. Been struggling trying to get stuff to work that NEVER will. Custom loops it is I guess
Thanks for the reply 🙂
I mean you could be doing something multiplayer illegal, but I can't tell with the bit of info you provided
But if you know what you're doing then alright
Esentially, I had 2 door BPs in the scene, each had a public variable named DoorA?. I did a for each loop to get both instances, and checked which was Door A and not, and set the doors accordingly.
But only 1 of the doors would work. It runs the for each loop, but only assigns a single instance,
But if I delete 1, and re add it, the opposite one works. So the codes all right, its just the for each loop thats giving issues. This is the 2nd issue weve ran into with the node
Are the doors placed in the level? or they are dynamically spawned?
Placed in the level
Yeah then they must exist on the server and clients as early as possible, but again no idea what's going on without seeing the full context
Ive changed that specific code, so I cant screenshot, but my next task requires setting 10 sprites on 10 instanced BPs, and the for each would be SUPER helpful, but its seeming like that loop is NOT good for multiplayer lmao
Hey, I'm using Advanced Steam Sessions in Ue4.27, I'm using AppId 480, and It won't find any sessions, how do I fix this? (sending screenshots)
Hey all. I'm new to unreal and trying to get my head wrapped around multiplayer.
Is there any case where GetLocalRole() would be ROLE_Authority on a client? I'm really confused why this is the case on my client. I was under the impression that only servers have authority over replicated actors. The actor in question is the main 3rd person character actor.
Code in question:
The debug text is appearing on the client, meaning the client has role authority over the character for some reason?
void AMMOBRCharacter::SetCurrentHealth(float healthValue)
{
if (GetLocalRole() == ROLE_Authority)
{
CurrentHealth = FMath::Clamp(healthValue, 0.f, MaxHealth);
OnHealthUpdate();
}
}
float AMMOBRCharacter::TakeDamage(float DamageTaken, struct FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
{
float damageApplied = CurrentHealth - DamageTaken;
SetCurrentHealth(damageApplied);
return damageApplied;
}
void AMMOBRCharacter::OnHealthUpdate()
{
//Server-specific functionality
if (GetLocalRole() == ROLE_Authority)
{
// Why is role authority here on the client? This debug text is appearing on the client for some reason.
FString healthMessage = FString::Printf(TEXT("%s now has %f health remaining."), *GetFName().ToString(), CurrentHealth);
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, healthMessage);
}
Is there any case where
GetLocalRole()would beROLE_Authorityon a client?
Yes. If the client spawns the actor.
Gotcha. I just have the starter 3rd person controller. Is the player "spawning" it? I was under the impression this server is and the client is the proxy?
Running in one process can also complicate this debug message.
Ohhh so you're saying it's possible that GetRoleLocale() == ROLE_Authority is not actually evaluating to true on the client but that debug message is being rendered on all unreal engine instances? :o
I was hoping that by setting it to client mode I could get a totally isolated client
hey guys/gals, quick question.
Is there any way to distinguish players in a multiplayer game? basically get a player ID? I'm sending events with shots fired, and I want to identify who owns the shot.
Even though I get a player controller with different names in different players, they both return 0 from GetPlayerControllerID ( which makes sense from a few things I read )
So, is there any engine-provided way to distinguish them_
Aha, I think this might be the case! That explains it, I was really confused https://forums.unrealengine.com/t/why-does-calling-gengine-addonscreendebugmessage-in-a-client-marked-ufunction-get-called-on-all-devices/284819
Their PlayerState should hold a UniqueNetID. You could use that for an ID. Normally you might just pass a PlayerState or Pawn around as an instigator. Just depends on the system.
AGAS_PlayerController::AGAS_PlayerController()
{
IsInputBound = false;
}
void AGAS_PlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
UE_LOG(LogTemp, Warning, TEXT("%s: Setup Input"), *FString(UEnum::GetValueAsString(GetLocalRole())));
AbilitySystemComponent = GetPlayerState<AGAS_PlayerState>()->AbilitySystemComponent;
if(AbilitySystemComponent && !IsInputBound && InputComponent)
{
UE_LOG(LogTemp, Warning, TEXT("Binded Setup Input"));
AbilitySystemComponent->BindAbilityActivationToInputComponent(InputComponent, FGameplayAbilityInputBinds(FString("ConfirmTarget"), FString("CancelTarget"), FString("EAbilityInputID"), static_cast<int32>(EAbilityInputID::Confirm), static_cast<int32>(EAbilityInputID::Cancel)));
IsInputBound = true;
}
}
void AGAS_PlayerController::OnRep_PlayerState()
{
Super::OnRep_PlayerState();
UE_LOG(LogTemp, Warning, TEXT("%s: Rep player state"), *FString(UEnum::GetValueAsString(GetLocalRole())));
AbilitySystemComponent = GetPlayerState<AGAS_PlayerState>()->AbilitySystemComponent;
if (AbilitySystemComponent && !IsInputBound && InputComponent)
{
UE_LOG(LogTemp, Warning, TEXT("Binded Rep player state") );
AbilitySystemComponent->BindAbilityActivationToInputComponent(InputComponent, FGameplayAbilityInputBinds(FString("ConfirmTarget"), FString("CancelTarget"), FString("EAbilityInputID"), static_cast<int32>(EAbilityInputID::Confirm), static_cast<int32>(EAbilityInputID::Cancel)));
IsInputBound = true;
}
}
void AGAS_PlayerController::OnPossess(APawn* InPawn)
{
Super::OnPossess(InPawn);
UE_LOG(LogTemp, Warning, TEXT("Posses"));
if(AGAS_PlayerState* GasPS = GetPlayerState<AGAS_PlayerState>())
{
UE_LOG(LogTemp, Warning, TEXT("ASC setted"));
AbilitySystemComponent = GasPS->AbilitySystemComponent;
}
if (GetLocalRole() < NM_Client) { OnRep_PlayerState();}
}
So this is my PC
If i want to access the ASC reference from client
Will the client get the reference if I'm setting it OnPossess?
If the OtherActor is your Character, then you could just cast it to your character class and call IsLocallyControlled on it with a branch
Instead of doing this, why don't you just override the OnRep and Init for PlayerState and just set the reference in the playerstate from there? Doesn't really make sense to set it over and over and over from possession.
That's a good question
is there a BP node that I can use that checks if I'm in a muliplayer game?
GetNetMode, check if it's Standalone. Anything else implies it's multiplayer usually.
Hey again everyone. Im having trouble where I'm using HISMs for the meshes of actors in my game. My problem is that for some reason clients are only getting part of the meshes loaded, so they have an incomplete level. The actors add instances of their mesh on begin play, so I thought that would fire when the client loads their instance of an actor but clearly that isn't reliable for whatever reason. Please help
It occurs to me that it could be because of my HISM manager actor not getting replicated first, is there a way to make sure the client is having things replicated in the right order?
I'm trying to test CMC with a bad network connection, and sometimes this message appears. Can some explain what it actually means? Is it something about the movement information relevancy (in terms of time), like a movement couldn't be replicated in time, thus dropped when it's too late?
Is there any other more elegant way to check GetWorld()->GetNetMode() < NM_Client
Could be HasAuthority()?
How bad is said connection?
There is a limit at which things will just flat out stop working
250-500 ping and 30% packet loss
Way too high
In the real world if somebody has a connection that bad, the game will be largely unplayable anyway
Yeah, I know, but the question is why is the movement dropped. Just for the curiosity 😄
Too much packet loss + latency, so the packets aren't arriving in time so they are being rejected
kk, thank you
A really bad connection is around 200+ ping and 5% packet loss - but even that should only be short-term really, and should recover shortly after
If somebody is playing on that connection constantly, give up 😄
Nah, it's just an exercise that required me to test with such connection 😄
how is the CMC checking if packets arrive on time? I made a very rough manual check for my setup but I am quite sure it can be handled way better
The moves are sent with a relative timestamp, the timestamp is periodically reset and accumulates with move delta time etc.
I see, great. Any class/method I can look for the implementation? Is it directly in the CMC?
ok nice then I'll have a look
I can imagine
Basically I want to check if the updates are arriving within a threshold between each other, knowing that the server sends at a fixed rate of 100ms
the main usage was to know client-side if the server update arrived late (imagine a packet that got very delayed)
CMC's is really more about making sure clients aren't speed-hacking etc
mmm I see, I don't need that in this case
It accumulates move delta time over real time, and keeps track of the discrepancy to modify how delta from the client is applied
I see, that is probably way more complex than I need
does the server always has the same code/build as the client? is this different for P2P games (2 players where the client is the server) and a BR for example
I think it is usually the same except for dedicated servers, which might left stuff out (specially things that only exist for aesthetically purposes)
Why does the print says "Server" even if a GameState is present on the server and the client ? Isn't it supposed to print twice like once on the client and once on the server ?
Please ping me if any answer 🙂
It is most likely because you are running the logic from AGameMode - GMlassic in your case and game modes are server only
Will the value be synced with the client ?
if the values are being replicated then yes - eventually things will be synced
If you mean to sync the timer variable just make sure its replicated and it should work just fine, your clients will receive updated version of it from the server
Hi. I can't multicast my own made variables values, but velocity and such that are engine works.. How come I can't get the values to multicast? It should just be an input parameter value.
This is what I've done, and it for some reason won't print the value on the other clients nor the server.
Any help is greatly appreciated. I've been trying to make this work for several days now.
It's a movement compoent, and MoveForward(float AxisValue) is being called from the axis mapping of W and S, so it should change 1 and -1, but it only shows on the client/server that is locally controlled.
Thank you.
//Variable:
UPROPERTY(BlueprintReadOnly, Category="Default")
float MoveForwardAxisValue = 0.f;
//Set axis value:
void UMyMovementComponent::MoveForward(float AxisValue)
{
// Only do calculations if controlled by local player
if(CharacterOwner->IsLocallyControlled())
{
MoveForwardAxisValue = AxisValue;
}
}
//On tick:
if(GetOwner()->HasAuthority())
{
// is server
if(GetOwner()->IsNetMode(NM_ListenServer) || GetOwner()->IsNetMode(NM_DedicatedServer))
{
UpdateMulticast_Implementation(MoveForwardAxisValue);
}
}
else
{
// is client
UpdateServer_Implementation(MoveForwardAxisValue);
}
//Server:
void UMyMovementComponent::UpdateServer_Implementation(float InValue)
{
UpdateMulticast_Implementation(InValue);
}
//Multicast:
void UMyMovementComponent::UpdateMulticast_Implementation(float InValue)
{
FString StringToPrint = FString::SanitizeFloat(InValue)
UKismetSystemLibrary::PrintString(GetWorld(), StringToPrint, true, true, FLinearColor(0.0, 0.66, 1.0), 2.f, NAME_None);
}
It works fine with blueprints like this. Really not sure why this isn't working in c++ but works perfectly in blueprint.
@trim plume Everything aside, do NOT use Reliable RPCs on Tick.
Additionally: The Movement Component of the Engine is in fact NOT replicated at all. The Velocity is calculated on all ends.
The only replication that is done are RPCs to send what the Player did this Move, as well as corrections from the Server if the Client did something wrong.
So if you just plug an RPC into a MovementComponent, there is a high change that the Components isn't even marked as replicated.
Should ACharacter::LaunchCharacter work in a multiplayer game? If I simply trigger the function on a client, the server doesn't get the information about it apparently, but after investigating some CMC code it looks like it does use some launch related stuff, but it doesn't work regardless
And yeah, the LaunchCharacter function uses CMC::Launch inside, so it makes me think that it should work in a multiplayer game
I think the actual call is not replicated
What are you using this for?
A Launch Pad the player steps on?
I want to make a wall jump
Ah
I know that the call isn't replicated, I thought that it would be saved in the move list or something like that
Multiplayer and additional Movement is usually quite involved tbh.
Cause you'd need to handle this directly in the CMC if possible.
Yeah, I know, I just thought since the Launch method exists on the CMC itself, all the logic was already implemented
But apparently it does something else with the launch data replication wise
Yeah but you still need to call it on Server and Client in the same timestamp
How would I call it with the same timestamp though?
The Client sends a package each frame (terms and conditions apply) in which it has a flag for "Player wants to Jump"
And if it can jump, it will
But that is an upwards jump at best
You have some functions you can override to allow jumping in other situations
In the Character itself
But it might be that you just have to handle the "custom jump" in the CMC
Yeah, I already have found some place to put my jump to, the only actual network related problem is that the launch isn't replicated
Would I need to add a few field to SavedMove? Something like bWantsToWallJump?
I don't think you need additional fields
Cause it would still be just the Spacebar press I guess
You could override a few functions
bool UCharacterMovementComponent::DoJump(bool bReplayingMoves)
{
if ( CharacterOwner && CharacterOwner->CanJump() )
{
// Don't jump if we can't move up/down.
if (!bConstrainToPlane || FMath::Abs(PlaneConstraintNormal.Z) != 1.f)
{
Velocity.Z = FMath::Max<FVector::FReal>(Velocity.Z, JumpZVelocity);
SetMovementMode(MOVE_Falling);
return true;
}
}
return false;
}
This handles the actual Jump for example
Let's ignore that you still need to define a condition to when it's allowed to jump
Sure
But if you know it's a wall jump, you can here do something else
Instead of Velocity Z you can do Velocity = WallNormal * bla
Is DoJump called on every machine though?
DoJump is called on OwningClient and Server
As long as both are sharing the same state
Which for a normal jump is just "I want to jump and I haven't jumped already and I'm not in the air"
etc.
So the server will replicate the additional jump to other machines, right?
Except the owning client
SimulatedClients never really jump
They just get their Velocity
So you still see them do the movement
But they don't know what a jump is
And that would be it, right? 😄
Well you still need to allow the jump
void ACharacter::CheckJumpInput(float DeltaTime)
{
JumpCurrentCountPreJump = JumpCurrentCount;
if (CharacterMovement)
{
if (bPressedJump)
{
// If this is the first jump and we're already falling,
// then increment the JumpCount to compensate.
const bool bFirstJump = JumpCurrentCount == 0;
if (bFirstJump && CharacterMovement->IsFalling())
{
JumpCurrentCount++;
}
const bool bDidJump = CanJump() && CharacterMovement->DoJump(bClientUpdating);
if (bDidJump)
{
// Transition from not (actively) jumping to jumping.
if (!bWasJumping)
{
JumpCurrentCount++;
JumpForceTimeRemaining = GetJumpMaxHoldTime();
OnJumped();
}
}
bWasJumping = bDidJump;
}
}
}
This is the code that calls "DoJump"
In the Character
"CanJump" is important here
bool ACharacter::CanJumpInternal_Implementation() const
{
return !bIsCrouched && JumpIsAllowedInternal();
}
bool ACharacter::JumpIsAllowedInternal() const
{
// Ensure that the CharacterMovement state is valid
bool bJumpIsAllowed = CharacterMovement->CanAttemptJump();
if (bJumpIsAllowed)
{
// Ensure JumpHoldTime and JumpCount are valid.
if (!bWasJumping || GetJumpMaxHoldTime() <= 0.0f)
{
if (JumpCurrentCount == 0 && CharacterMovement->IsFalling())
{
bJumpIsAllowed = JumpCurrentCount + 1 < JumpMaxCount;
}
else
{
bJumpIsAllowed = JumpCurrentCount < JumpMaxCount;
}
}
else
{
// Only consider JumpKeyHoldTime as long as:
// A) The jump limit hasn't been met OR
// B) The jump limit has been met AND we were already jumping
const bool bJumpKeyHeld = (bPressedJump && JumpKeyHoldTime < GetJumpMaxHoldTime());
bJumpIsAllowed = bJumpKeyHeld &&
((JumpCurrentCount < JumpMaxCount) || (bWasJumping && JumpCurrentCount == JumpMaxCount));
}
}
return bJumpIsAllowed;
}
You would need to add your own condition to this
To check if the Character can do the Walljump
You can assume that the code is called for Server and owning Client
And that both are ROUGHLY in the same location when it's called
ROUGHLY being a very tiny number, if that causes a desync it would cause a tiny correction, but that's with all movement, sooo yeah
Thank you very much, you pointed out much information to work with 😄
No worries (:
Thank you for replying, exi.
I tried Unreliable as well, but didn't work either.
I just now set up a new blank project with an actor component, and it works fine in there too.. Does it mean that a character movement component can't multicast values from variables I make myself? I find it hard to believe that it's not possible, since it works anywhere else I do it, even blueprint it works.
I'm about to lose my mind here, I've been banging my head into the wall for a few days now.. This is so frustrating.. 🙈
There must be a way to multicast from the character movement component, so I don't have to do it in blueprint.
I tried Unreliable as well, but didn't work either.
Again, this is not about it being a fix. You should NOT use Reliable with Tick.
How come? 🤔
Because Reliable is meant for important, once in while, events. You are sending those EVERY FRAME. That's on average 60 times per second.
At that point it doesn't matter if one of those doesn't reach its destination.
On top of that you are filling the reliable buffer and this might cause other replication in your project to be dropped instead.
Ah I see. Thanks for the explanation. I'll look into that. Thank you ☺️
But I still need to figure out how to multicast values in the movement component as I can in an actor component.. I really don't understand why it's not possible, because I do the exact same thing.
Is that Component marked as Replicated?
I tried both checked and unchecked, if that's what you mean?
The Component has to be marked as Replicating
Otherwise it won't be able to process the RPC
and the Component has to be on an Actor that is owned by the Client
E.g. the Character/Pawn
What even is that Component you are making there? a custom UMovementComponent or even UCharacterMovementComponent?
Yes. I tried all that. And it should work, because if I parse Velocity.Size() as input parameter, then it works..
UCharacterMovementComponent
Is there a limitation to the character movement component that multicast isn't possible?
I'm shooting in the dark here, but I'm really out of ideas..
Well
Character Movement Component in general isn't meant to replicate
Epic performs the replication inside the Character if needed
@trim plume
I have bad lags when connecting to a dedicated server (even on the same computer) already tried the parameters in the DefaultEngine.ini but still happens, anyone knows?
Make sure you don't have any network emulation settings accidentally turned on, you can find them by clicking on the little dropdown next to the play button in the editor and then inside of advanced settings.
guys what is better to use when I want tell every spawning player/pawn where to spawn on map? find player start or choose player start in game mode?
which function would you use
What's the difference?
I treid override ChoosePlayerStart function like this I have 4x player start on map every has PlayerStartTag 1 2 3 4 and I am choosing from them (now only random but next I need choose depends in which team they are) but after joining game like this I get spawned more like 1 player, but when I run it as Play As client and choose 2 players I get sometimes this it will spawn more like 2 it will spawn 4 2 I can posses and 2 not
I hope its clear ah 😄
propably nothing but look what happens me
@real ridgeChoose Player Start is ONLY meant to choose the start actor, that's it
it doesn't do the spawning and possessing
and FindPlayerStart calls ChoosePlayerStart
Okay so I should not include posses there ? anyways why then its spawning more like 2
so I just need choose player start and return it
and dont do spawn anything
thats why its happening?
so delete spawn + posses?
Because you spawn a pawn while you're in FindPlayerStart, then after that the gamemode spawns another one as normal
btw every time you talk to me its like I am talking to jesus your profile picture reminds me him lol
XDDDDD
yes thank you
I am dumb
it makes sense
i am spawning and unreal is spawning too
so 2 are there
Yes just have your override return what it wants and nothing more
don't do extra stuff there
Okay thank you! I thought is needed to use spawn but it seems unreal is smart enough
GameMode basically does Choose Class, find start, etc etc, then it spawns the pawn and possesses it
you can override the individual parts like this
shiet but it seems replication is totally wrong
yes automatically thanks
I was not sure its automatic
can I ask one more question? I am saving team of player in his game instance how I can get in in game mode and then choose his player start up to this team?
any ideas
because in game mode I can access only to game instance of server
also I am not sure if its safe have team in game instance of client
but player state is not presistent when I am joining session
You can use CopyProperties in your player state and send the team variable to your new player state
Like this, but with team instead
hmmmm
I dont get it but will try
https://cedric-neukirchen.net/Downloads/Compendium/UE4_Network_Compendium_by_Cedric_eXi_Neukirchen.pdf - go to page 26-28 its explained better there
although it may only work if you're using seamless travel
The way mine works is in the pre lobby level is where players select their characters, then once the game is started all players are seamlessly travelled over to the actual map which is where my new player state is created, the CopyProperties event is fired before/during seamless travel which then sends the selected character variable from my pre lobby player state to my actual games player state, which i then use in the game mode to spawn each player with their selected character
Do you need a standalone machine to process all of these dispatches
Looking at making a small in-house game for work, it would be 5 tablets. Do I need a seperate machine to be the server?
One tablet can be Listen Server
assuming there's no Android/iOS weirdness around listen servers
i dont have it because my lobby is offline in game and I am making it via websockets and varest so in lobby u are not joined server just my own database
just after hitting play in lobby u are joining game/session on server
can any one help me with AnimNotifys, my weapon has a function that plays a unEquip montage and that tells animBP to tell Character that Equip or UnEquip is finished but most of the time it just snaps to idle on clients and does not Notify but animation plays fine on server?
can anyone suggest a tutorial to set up an online-subsystem? Its my first time trying something like this.
so I have a project that works properly when launched from the editor. I am trying to get familiar with the process of packaging / deploying it so that i can test it with a friend or two. I have set up a client and server build target, built them, cooked the content and everything seems to run locally on my machien just fine, the server accepts connections and i can see that in the log, the client starts up, and i can see debug output in the client etc. However, the client doesn't seem to display any of the world data. I can see my reticule and if i take actions i can see corresponding UI elements appear and logging display in the top right but my world is just a black screen like so (the little circle in the middle is a ui widget for the users cursor). If I play from the editor in client/server net mode with multiple players they all spawn in and can see each other, see the world, etc. In the screenshot, server output is on top and game client is below.
turns out i am an idiot, i didn't set the default server map in the project settings, working now
I have an issue where an item class (or, specifically the mesh of the item) is not shown to other clients than the owner and I am unsure what needs to be done to make it work.
The item only has a mesh, and it inherits from a "ThirdPersonEquipable" class, which inherits from an "EquipableMaster" class, which inherits from an "ItemMaster" class, which inherits from AActor.
The mesh itself exists on the item class. I can confirm that the item gets spawned by the server using UFUNCTION(Server, Reliable, BlueprintCallable) and is attached to the owner in a function using UFUNCTION(NetMulticast, Reliable).
I assume something needs to be set to "Replicates" somehow but I can't figure out what or how. Any good ideas?
EDIT: It might be worth noting that this is in c++.
hello, after a seemless travel I spawned the characters and tried to possess them with the player controllers. My issue right now is, that the client only possesses the pawn, when I put a delay node in front of the code. It seems, that the clients controller isnt ready to possess the character, by the time he is asked to, or am i missinterpreting this?
Can anybody tell me why I havent this in my defaultengine.ini, Im trying to make voice chat and this guy changing this setting, but I havent it. I also added online subsystem steam plugin
Because its a config file and every program using UE doesn't necessarily need to have voice chat enabled. So that and many other options aren't there by default, but feel free to add whatever configuration your project needs.
If i dont have that delay, the client doesnt possess a character for some reason
hi i cant seem to get the multiplayer to work outside the editor--thats the bp code im using steam advance sessions plugin-- when i test multiplayer on 2 different pcs it doesnt work but works in the editor
also followed the online doc about multiplayer added this in the default engine.ini file
i add this lines but editor still crashing what is the problem ??
Did you mean to do this?
You'd be trying to destroy what I think is your game mode which doesn't make much sense.
Hi, I just got surprised by the error "GameState null". The client requested the GameState before is has been replicated.
What is the proper way of dealing with this? I.e. in the client code, some actor does its setup, but in 'BeginPlay' there is no guarantee that the stuff is there.
(Or does 'BeginPlay' imply that the initial replication has finished, and there should be a GameState, too?)
I can wait for stuff to get ready within the tick function of an actor (doing nothing, until ...), but the disadvantage is that a proper error gets hidden this way. E.g. if a cast to 'MyCustomGameState' fails or alike.
@sinful tree it was originally connected to the controlled pawn. thanks for pointing that out.
Begin Play is when that particular actor begins play on that particular instance (whether it be server or on any particular client). Begin Play of any actor will fire when that actor is spawned, including if it was spawned as a replicated actor.
To rectify if you're checking on begin play of that actor, is to still use your current logic and if it succeeds, set a boolean indicating that the process that needed the gamestate has been completed.
If it fails, then you rely on begin play of the gamestate.
I am implementing a flag logic at the moment. For a given actor, whatever replicated actor or property is needed for its setup, has to tell the actor that it's ready. The 'BeginPlay' of the actor sets the "ready internal" flag. Whenever a flag is set, the actor checks:
if all flags are set, do the setup.
I was hoping that this logic isn't necessary, because it's quite a bit of code.
If initial replication doesn't follow a defined order, it seems necessary, though.
here, network initialization doesn't follow any pattern.
For C_0, PostNetInit happens in between the replication of OrbitState and Body.
For C_1, PostNetInit happens in the end.
The GameState isn't ready for C_0, C_1, C_2, but for C_3 it is
Similar with BeginPlay, which sometimes happens before, and sometimes after PostNetInit
Pretty messy
I am reffering to these logs
This is a thing for any multiplayer application, isn't it? Pretty strange that everyone has to reinvent the wheel to deal with this
Anyone know of any good articles/videos explaining the LocalPlayer and UniqueNetIDs / player names and how to handle those?
Hi I have an issue that I believe is caused by my actors replicating in the wrong order. I have a manager class that clients need for spawning ISMs in the level. The manager is referenced at the begin play of the actors, which I now understand is unreliable, since they are not necessarily replicated in order. My problem is I have no idea how to do the logic for initializing these actors, if I can't rely on load order. What am I supposed to do?
the same as me: (see right above); I don't know if you are using C++ or BluePrint
each actor that is required need to register somewhere when ready (could be the game instance or in the actor that requires all the actors). To that end, there is a register function that takes a enum flag as argument. Whenever the register function is called, it has to save the new flag and check if all flags have been set. ... in which case it's ready to do stuff that relies on those actor being present.
In your case that would mean: call all actors to finish their initialization
I am using blueprint.
What does your register function look like?
void AOrbit::SetReadyFlags(EOrbitReady ReadyFlags)
{
OrbitReady |= ReadyFlags;
if(OrbitReady == EOrbitReady::All)
{
UE_LOG(LogMyGame, Display, TEXT("%s: Orbit ready"), *GetFullName())
Initialize();
}
else
{
UE_LOG
( LogMyGame
, Display
, TEXT("%s: Internal %s, Body %s, Gamestate %s")
, *GetFullName()
, !(OrbitReady & EOrbitReady::InternalReady ) ? TEXT("waiting") : TEXT("ready")
, !(OrbitReady & EOrbitReady::BodyReady ) ? TEXT("waiting") : TEXT("ready")
, !(OrbitReady & EOrbitReady::GameStateReady ) ? TEXT("waiting") : TEXT("ready")
)
}
}
UENUM()
enum class EOrbitReady : uint8
{
None = 0,
InternalReady = 1 << 0,
BodyReady = 1 << 1,
GameStateReady = 1 << 2,
All = InternalReady | BodyReady | GameStateReady
};
ENUM_CLASS_FLAGS(EOrbitReady)
The actor 'AOrbit' relies on three things before it can call "Initialize()":
- Having finished its own BeginPlay: 'InternalReady'
- A pointer to an actor called 'Body' must have replicated: 'BodyReady'
- The gamestate must have finished its 'BeginPlay' on the client: 'GameStateReady'
sadly I don't understand C++ syntax so I don't know what the EOrbitReady enum class means
When are you calling SetReadyFlags?
yeah, that's a quite technical thing. it's the c++ way of storing a (potentially) high number of true/false values efficiently
My sticking point is mainly order of operations and ensuring I can call something like an initialize function at the right time
but my level has hundreds of actors that need this treatment, so I want to avoid cycling through every single one of them if I can
I call 'SetReadyFlags':
- in the begin play of the orbit actor:
SetReadyFlags(EOrbitReady::InternalReady) - in the
OnRep_Bodyfunction that gets called when the body actor pointer gets replicated:SetReadyFlags(EOrbitReady::BodyReady) - and in the gamestate begin player: still working this one out
cycling through a bunch of actors isn't necessarily performance heavy.
so you are doing a rep notify on an actor variable to figure out when something has loaded?
but yes, you want the actors to communicate to some central place that they are ready and then check the same place, whether or not all other actors are ready, too
yes
yes
wait that actually works? so if the server's beginplay sets every actor's pointer variable every actor will know once that central actor has replicated?
So if I am understanding right, the server can basically set a variable in my actors for each actor that needs to be loaded before them? Then on RepNotify I check my boxes and once all are checked I can initialize?
I am suggesting something different. My code happens 100% on the client
how are you doing that? Wouldnt the clients have nothing to point to?
on the client, you can just use 'BeginPlay' to be sure that a given actor is present
but where would I store that information?
like every pupil in class says "present", every required actor tells his name (or some index, or in my case: a specific flag) to the game instance or to some other actor, who requires them
why not the game instance?
What is your manager actually, Sumrex?
I just realize that this might be a flaw in my program: the "teacher" must definitely be there first ... otherwise it doesn't work
thats what I was confused about
the game instance is safe though