Download

Targetting a specific player in Multiplayer

I am wondering how to target a specific player after they’ve spawned on the server. I’ve tried to manually create my own player indexing system, but to no avail. I did some digging but the only thing I found that made some sense was getting all PlayerControllers (all players in game at that time) in the GameState blueprint making an array out of the results. Then in the MyCharacter blueprint I cast to GameState and get that Array, get its length, add 1 to it and set that as unique ID for the player, and this works. But now how do I target a player based on that unique ID, what node do I use instead of Get Player Character or Get Player Controller?

Basically my question is how does one handling player indexing / player targetting in a multiplayer game when the standard player index is not viable anymore?

Thanks in advance.

What if you create an array with an instance to each character? That way you can figure out which character you are targeting by getting the position through the instance.

I do not know what is the best method but the way I did it (some time ago around v4.4) was to add every player controller that logged in an array in the GameMode blueprint.

You can catch the player login via the Event Post Login.

Then you can do a for each loop in that array, get the Player State and then get the Player Id from it.

What do you mean with ‘Create an instance to that player’, how would I do that?

Cool, sounds like something worth giving a shot, but how would I for example then get player controller or player character from that player ID? How would I use that playerID I get from the array instead of Get Player Controller or Get Player Character which both require an Index to work?

What I’m trying to accomplish, for example, is getting some data from a database, and based on that data spawn different items into sockets on the character. Or something really easy change the characters material based on what color the player chose during character creation, but to do so I need to be able to target 1 specific actor, and this can’t be done with Get Player Character or Get Player Controller unless you manage to make an index system somehow. I really wish a dev would shed some light on this.

Thanks both for replying, the AnswerHub has let me down lately so Im really grateful for atleast getting replies.:slight_smile:

ForEachLoopWithBreak → get player state → get player id… if player id = xxx then get player pawn from that player controller and break.

Is that what you mean?

It sounds like thats exactly what I’m looking for but my only question would then be how do I initially store or get the xxx value?

Right now I have this:
Player logs in > store Username in GameInstance > player gets teleported to CharacterSelection menu.
In Character Selection menu > get all characters of Username (cast to gameInstance>get Username) with a JSON query > display all his/her characters.
Then when a character is selected > store Character’s name in GameInstance > teleport player to the online world > and spawn a MyCharacter for him after which he possesses it.

On event begin play for that MyCharacter I then > get CharacterName from GameInstance to get data about that specific character
(In my example a material, 001 for blue, 002 for red, this I hope to expand to more indepth character customization like morph target values and such, but used materials for this example)
I then want to apply this material to players character, but here’s my problem: How do I apply it to his MyCharacter only (his instance of MyCharacter if you will) since the Set Material requires a Get Player Character node (which has an Index)

With what value (xxx) would I compare the player ID from the ForEachLoopWithBreak to check if true or false and thus getting the right player controller?

Hope you get what I mean :slight_smile:

A more simple explanation would be: I want to be able to do logic for each player specifically. Set the hairstyle of his/her character based on his/her preference that is stored in a database.
On event begin play I try to apply those preferences, but I need to target his/her playerController/playerCharacter specifically where as the GetPlayerCharacter/GetPlayerController nodes require an index to be given to them first.

Your method of making an array out of PlayerControllers > ForEachLoopWithBreak > get Player State > get PlayerID, and then comparing that with a PlayerID that is already set (?) and if true, break the loop so I have a PlayerController targetted, thus being able to apply Player’s preferences/customization, sounds good, but the (?) part is what I don’t get.

From what I can gather I compare it with Player ID that is already set, but where and when was it set?:confused:

I’m trying to make myself clear, but I’m not a native english speaker so I apologize if I’m somewhat vague.

This is a video of my game which demonstrates another problem, variable replication (in this case his/her username). But it’s somewhat similar to this problem.

Imagine user 1 having a red character in the database and user 2 a blue one.
How do I target user 1, to apply his/her red material, and with the same logic target user 2 apply his/her blue material when they spawn in the world?
(early beginnings of character customization, but can be applied to alot of other scenarios such as clicking on other players and seeing their username as demonstrated in the video)

Okay, sounds like you are trying to do something a bit more complicated than I thought.

I believe that the playerID from the player state is not permanent (it basicaly auto-generates a unique number each time) so you probably cannot use that to store persistent character preferences, if that’s what you are trying to do.

What you probably need to do is setup steam and load player data based on the steam id.

I’m not really sure that you can get the actual steam id via blueprints though, you probably can only get the steam nickname (which can be changed at anytime… so not reliable)

**
Edit: **
I just saw your other post. Looks like you already have a login system setup so you don’t seem to need steam :stuck_out_tongue:

I don’t think you need the playerID at all, you could just store the username from the login in the player controller.

I tested that and the autogenerated playerID is permanent as long as you keep the session (or server) running.
I dont need the auto-generated PlayerID to persist for when a new session is made… the generated playerID would be bound to a new playerController, but thats no problem as long as it persist during the session
(which it seemingly does)

So in theory if I’d get PlayerID and get a playerController from it somehow, I can accomplish what I want.
I plan on having this server running 24/7 so really all I need is a way to get a PlayerController from that playerID so I can load in player preferences from a database and apply it per player. :rolleyes:

But perhaps I am overlooking something. In any case thanks for your help so far TK-Master. :o

Cool, but how would I cast to PlayerController though if that also requires me to connect a controller to the object input?

9ce20da3e700a02a735ea6239f20e5094a4451c2.png

Also does this MyPlayerController actor stay in memory when a new level is loaded?

You cannot run a server 24/7 forever though :stuck_out_tongue: sooner or later you will have to restart it or it will crash (probably :p).
Besides, even if the client re-logs a new id will be probably generated.

Here is the steps that I would take based on what I have seen of your setup.

Client starts, tries to login with username/password, if password is correct save the username into the player controller and load the character selection screen.
Once a character is selected, load the necessary data based on the username we stored in the player controller.

Sounds good, but once the player is spawned in the world how would I target the player then? Like with for example the Set Material node, what do I put in Target?
Thanks a bunch in any case :slight_smile:

Once the character is spawned (and possessed) you can easily read it’s controller’s variables (such as the username :p) in the character blueprint.

So then you can load all the data you need (in the character blueprint).

JoinWorld gets called when player selects a character:

Once player is in world, MyCharacter is spawned and possessed, then this fires:

I am unsure what to put in the Object input, self fails…:confused:

I’m assuming the JoinWorld part is in the player controller and you don’t have a problem with that part, correct?

In the character blueprint you need to use the **Get Controller **node, not self :stuck_out_tongue:

CharacterButton (the button you see me pressing after I’ve logged in with the username and level of character on it) fires JoinWorld in it’s own blueprint. (this is a UMG button onClicked event)
ca9410b6608764658ccdae83e3047d15c9d821a5.png
I am unsure what to put in the Object Input for the cast node…

Then it calls JoinWorld in MyGameInstance which does a console command:
8d82d814f12a8e5d96a71b52296deb3a7cadc452.png

Player is transferred to World which has this default pawn:
433c923237aa5afae7f14d676645c8e31f018cfb.png

This spawns a TopDownCharacter in the world which executes this:

To get a controller reference from a UMG widget you can use the Get Owning Player node.

That worked but now the Cast to MyPlayerController node in TopDownCharacter fails with GetController… :stuck_out_tongue:
MyPlayerController does get transferred over/saved in memory to the new level when I execute ‘Open MyIpAddress’ I hope?

When you open a level, a new controller is given (probably?) xD you have a never-ending stream of things to solve man :smiley:

You can use a game instance bp to store data between level loads but I will have to look into that…
…tomorrow that is, I have to go to sleep :stuck_out_tongue: