#memo

indiedev太郎

マルチプレイ時のプレイヤーポーンのスポーンのタイミング

GameModeのログイン処理、パーシスタントレベルのロードが終わると始まるっぽいけど、ストリーミングでマップをロードするタイプの設計だと、最悪床のロード前にプレイヤーがスポーンして奈落即ち死になる可能性がある
https://i.gyazo.com/9f60984498e04cfb81aa69b221654c7f.png

かといって、ロード終わった瞬間にプレイヤー周りの処理してしまうと、今度はログイン処理が終了していない可能性があって、最悪な感じになってきている
ここでクッソよく分かる生成タイミングの図を用意する
https://i.gyazo.com/c3b30cc1b176a8cb611ba9d1fd66c096.png

作りがちなPlayerControllerのBeginとかはよくなく、Levelでロードが完全に終わっており かつ PostLoginが実行されている(PlayerControllerがちゃんと生成されている) 状態でいろいろやっていくと嬉しい

なので
Levelでロードが完全に終わった瞬間、PostLoginが実行されていればPlayerPawnスポーン
あるいは
PostLoginを実行した時、Levelがロード済みならスポーン のどちらかでDoOnceしたら良さそう

Levelがロード済みかどうかは、GameStateの中に変数として保存しておく、もちろんレプリケーションはしない

以下ノード

LevelBP
https://i.gyazo.com/cfbc05468a917f125191315f9af60894.png
ListenサーバーではGetPlayerControllerの0が常にOwningなやつっぽいので、Authorityは見てない
ロード終わったタイミングでPlayerControllerがあるかどうかは確実ではないので、あればイベント送る感じにしておく

GameMode
https://i.gyazo.com/0ca54847b5d3649b9b90d0ac7e7bb8d9.png
OnPostLoginをオーバーライドすると、ログイン完了毎に呼び出される、サーバー合わせて3人が遊ぶなら3回呼ばれる、Nullの確認は一応したほうが良い気がする

PlayerController
https://i.gyazo.com/6d52a22b3e616df804237cca838e7e86.png
GameStateにあるレベルロード済みかどうかのboolはlocalな変数なので、CliantPostLoginはlocalに実行しないといけない
なのでこのイベントのレプリケーションはRunOnOwingCliantかつ絶対に届いてほしいのでReliableにチェック
詳細はここらへん
Unreal Engine | ブループリントのマルチプレイヤー機能

Pawnをスポーンさせる関数は多分サーバーで実行するならどこでも良いと思うので、あとは適当
ソースもめちゃくちゃ流し読みなので、この記事も適当