Accessed to none trying to read property My Player Reference on the other player

I have a replication issue. The variable GhostLife shows at the Widget: LifeWidget in Player 1, but not in Player 2. GhostLife variable is located in Player1 (Ghost). When I play, the variable is shown as a text (100) correctly, but Player2 doesn’t detect the variable.

Ingame:
http://prntscr.com/jvnvsv

Error:
http://prntscr.com/jvnwkp

Event construct:
http://prntscr.com/jvnx3c

GetText:
http://prntscr.com/jvnxby

Variable settings:
http://prntscr.com/jvnxh6

Also Player2 and Player1 have replication settings to on.

Player2 spawns at runtime.
Player1 is on the level when the level is opened. (Player1 is who im trying to reference and it haves the variable GhostLife)

In your widget’s get text function it refers to MyCharacter.
MyCharacter is always set based on playercontroller 0. This is fine on individual devices but on the server this will tell it to use the same player for all.

So i suggest on widget constructor you instead reference OwningPlayer instead of PlayerController 0

http://prntscr.com/jvpmt6

How I can reference OwningPlayer instead of PlayerController 0? Tried by different ways, but anything work. You mean something different than what I’ve do in the image, but I don’t known what.

That is almost correct. GetOwningPlayer gets a playercontroller. Get the Controlled pawn from the controller and cast to your character class and that should work.

http://prntscr.com/jvryp9

Still doesn’t working. I don’t known how to do it, I didn’t understood correctly.

no errors but still doesnt work?

Nope, there still the same error. https://image.prntscr.com/image/vzzu5l-cS3mve8Cfo7AegA.png

If you use get owning player on the player 2 you will always get the pawn of the second player.
You should use a game state to get a reference to a specific player. Also the variable on your character might not be always updated to the client (Read on the network dormancy if you want to understand why). My suggestion would be to move your ghost health on a player state or maybe even on the game state.

Ok, thanks. But… What I should put in ‘Object’ on Cast to Player State?

Gamestate gas Player Array
has Player States which can be cast to your Player State class.

Remember you can only cast to classes that have a common ancestor AFAIK.

Alternatively you can Get Player Controller 1 (instead of zero) and from the get PlayerState and cast that to your Playerstate child class to access the variables you made up.

Same error :frowning:
http://prntscr.com/jy7tgc

http://prntscr.com/jy7u3k

Is this over network or is it local (same device) multiplayer?

You may need to wait until the PlayerState itself calls BeginPlay, and set the var from there. Many things can start executing before a PlayerState starts to exist for any given Player.

Network multiplayer.

How I can do that? Im pretty new to UE4, sorry, i’m really confused right now.

that might be your problem.

On the Server, Player Controllers exist for all connected players.
But on the remote Clients, the only player Controllers they can access (AFAIK) are the ones owned by the device the client is running their copy of the game on.

so you will be better off using Player states since they can be replicated from the server to all the connected clients. So you just get your game state node and the PlayerArray off of that and you can loop through all the playerstates in that array until you find the one whose PlayerID matches the one you want to display the info for.

Make sure you set your Playerstate child class blueprints’ variables to be Replicated so the clients can see the changed the server makes to them. These variables can be for things like health, ammo, lives, name, etc.

Be advised that trying to do networked multiplayer makes everything 5 times more complex, so i would not try it until you learn the basics of Unreal’s gameplay framework first and understand how Game Mode, Game state, game instance, player, player controller, player state, and Pawn all fit together.

Doesn’t work on the client and server. The error is the same: Accesed to none trying to read the reference.
http://prntscr.com/jyc7yf

Yeah lol, during the making of my first project (This), my unique issues were with networking, I could have finished my game a long ago, because every network issue for me takes weeks to resolve. I should have started with a single player game.

Thanks. But I’m stuck, I don’t know what nodes to put (Yeah, im very noob, I understood you but I don’t know what put to detect if it is in the server, for example. I only did that I know how to do, like the loop with event)

Event construct:
http://prntscr.com/jyffy8

Begin play on Ghost (Player 1, wich haves the GhostLife):
http://prntscr.com/jyfgl5

I reviewed your original post and I see more clearly now.

It looks like your original approach would work except that your were trying to get the ghost player by accessing Player Controller 0 (which is always the first player on a given machine. So on your server, player controller 0 is the only player on that machine (the one you call player 1)
and on the client, player controller 0 is the only player on THAT machine (the one you call player 2)

so by using player controller 0 on the remote client you are getting the pawn for player 2 as your MyCharacter instead assigning Player 1 to it. So your display on Player 2’s computer will always show the ghost life value that Player 2 has, not Player 1.

To solve this, since you are (in the original post) storing ghost life as a replicated variable on Player 1’s pawn, you can probably just do the following:

On the pawn’s beginplay, detect if it is in the server world or the client world, and store that as a replicated variable.

In the widget constructor set a timer for every 1 or 2 seconds to trigger an event called RefreshGhost. In the event, loop through all the pawns until you find the one with that isServerPlayer variable set to true and assign that to MyCharacter. That way if the ghost pawn is ever destroyed and a new one created, the display will reassign to the new one instead of referencing the destroyed nonexistent one forever after. I use a timer because it slows things down to loop on a tick.
To improve performance you can forget the timer and instead add a reliable Multicast to the pawn’s OnPossess event which gets handled by the client and passes the Pawn’s playerstate’s PlayerId to the client which he can then loop over pawns and check playerstates until it finds the one with the matching ID and assign that to the myCharacter var. Then it doesnt have to keep checkingg. it just updates wenever a new pawn is created for the server player.

That should do it.