RPC Calls to Unowned Actors Not Working (C++ networking)
Been tearing my hair out over this one for some time, and still not sure what the best approach is. As such, any help would be extremely appreciated.
I'll quickly outline my situation and approach so far: I have a top-down multiplayer RPG game. When a player presses a button, they'll swing a sword, and this should be seen on the server and on all connected clients. When the sword connects with another actor, that actor will play a "hurt/recoil" animation, to show they have taken damage.
So far, swinging a sword is seen on all clients currently connected, plus the server, regardless of whether the client is swinging or the server is. So that's working as expected. I encountered problems when trying to play the "recoil" animation, because that's me asking another actor, that I don't own, to do something.
A quick current structure of how this works:
Character class has an AnimationHelper class, which has various functions to process animations etc. This is used to play the swing animation, and formerly the recoil animation. A quick demonstration of the code header:
PlayAnimation looks like this:
I had tried to follow this pattern to do the "recoil" functions as well. Unfortunately, trying to call the function via character->AnimationHelper->PlayHitReaction was disallowed, because the requester was not the owner of that actor.
After some research, it seems a character cannot call another actors functions if they do not own them. What I did read is that this may be possible if we go via the PlayerController. So, I created a new class, AnimationRequester, and created a member of this type on the PlayerController class. This is instantiated at BeginPlay.
It looks like this:
And request play looks like this:
Extremely similar to the other PlayAnimation function. The implementation is a little different.
This obviously doesn't work. The animation will play for the person who swung the weapon and caused the damage, but does not show on any other instance (no matter if it was the client or the server who did the action).
If I put a breakpoint on the functionality, it only appears to be called once - when I expected once per connection.
So a quick rundown again: when an enemy is hit by a sword, the RequestPlayHitReaction function is called, and I expect the animation etc. to play across all connected instances of the game. The function is on an object derived from UObject held as a member within my PlayerController class.
So my questions are: is this a dreadful approach? Is there a simpler way? Am I missing something obvious as to why the animation isn't playing for all? And: what is the best means of calling functions on unowned actors when RPC functions are involved?
Thanks a lot - really frustrating stuff to figure out. Any and all help greatly appreciated.
asked Mar 17 '18 at 07:14 PM in C++ Programming
it seems to me that you cannot use RPC in the class that inherits from UObject, based on this: click
I'm not tested this, but here have some concept.
In Weapon class I have event OnHit that is called when weapon hit something. OnHit is called only from server.
CalculateDamage() is executed only on the server side and only on the Warrior instance that receives damage. Next server changing replicated property HP and tell all to call proper animation.
As you can see I using only AWarrior and AWeapon. On the server side, I perform important actions, such as calculating the damage, etc. Clients only say what they want to do, but the server does it.
I treat the server as some "Game Master", which controls events, characters, performs calculations. Clients can do only what the server will allow.
if each client will calculate the damage on their own, then:
ClientA has exactly the same weapon as ClientB (and stats so, they do the same damage), but ClientA cheats (or badly calculates damage) and deals more damage than it should. If the server performs damage calculations, ClientA and ClientB will do the same damage even if there is some miscalculation.
Read this: Gameplay framework review (especially the beginning)
The server has all PlayerController, but each client has only his own PlayerController.
APawn and APlayerStat
The server and clients have all APawn and APlayerStat.
I hope it will be useful :D.
answered Mar 18 '18 at 12:16 AM
Follow this question
Once you sign in you will be able to subscribe for any updates here