You need a localplayer override in project settings. This is due to the client posession of a non replicated controller without a cameramanager for a brief second and has been mentioned in UDN on how to properly address. Set the camera manager on your localplayer class to construct as set fade to solid black and once it hits posession after repped fade back in
I am having an issue when a player joins my game there is a quick flash of a camera sitting at what looks like 0,0,0. The Server player doesn’t not have the issue, I am guessing because the server is actually loading the world. However when a client joins the servers session, they get a quick flicker of a camera sitting at (0,0,0), before I manually spawn them to their correct PlayerStart. I manually spawn them in my GameMode right after OnPostLogin.
TL;DR
Override ChoosePlayerStart
and SpawnDefaultPawnFor
functions in GameModeBase might solve this issue.(UE5.03)
Steps
ChoosePlayerStart
can locate the pawn’s init StartSpot for you.SpawnDefaultPawnFor
can adjust the pawn with the StartSpot info you provided.
Story
After finding myself has the same issue of camera fickering,I first tried to override ChoosePlayerStart
function. But that just make my pawn spawn at the right place with no rotation info at all.Then with some trial and error iterating,a NPE happened to me,and I got a call stack below:
Then I found that after PostLogin(here I’ve once tried to SetViewTarget of the PlayerController,which turned out to be in vain…), GameMode tried to spawn a default pawn for the login-ed player controller after PostLogin, but without rotation info of the StartPot! But lucky enough, SpawnDefaultPawnFor
is also overridable.
At last, I overrode the 2 functions and the pawn spawned with a correct transform at the first place without flickering.
But…
If I directly open the map without JoinSession(In PIE), the flicker appears…
(In my case, I have a openning stage and an animation when the game starts,so there’s nothing to worry though.)
@TimBayer Hi!
As far as I know, it happens because Player Controller spawns Camera Manager before possess character. The Camera Manager starts the camera view as soon as it is created, and then waits for the character’s camera to replicate transform.
So you can override Player Controller’s SpawnPlayerCameraManager function and do camera fade for example, or what ever you want to hide this quick period of time.
Here is example:
I would spawn a widget “begin play” of the player controller. after posses a pawn, pawn or you can remove that widget
Personally I use custom Loading pawn (GM default pawn class). Bare bones pawn class, no movement, input/IMC. It has a loading screen widget.
This class determines when the clients level has loaded sufficiently, then calls an event on the controller to have the GM swap out for the character.
Works well. I get a loading screen, my pawn isn’t falling through the map, and the GM’s default new player logic/handling isn’t modified.
Here is the best way to fix it, based on @Uno1982’s solution.
- Create class (UMyLocalPlayer) with parent ULocalPlayer
- Put this in the header
public:
UPROPERTY()
bool bBlack = true;
virtual bool CalcSceneViewInitOptions(
struct FSceneViewInitOptions& ViewInitOptions,
FViewport* Viewport,
class FViewElementDrawer* ViewDrawer,
int32 StereoViewIndex) override;
- Fill implementation
bool UMyLocalPlayer::CalcSceneViewInitOptions(FSceneViewInitOptions& ViewInitOptions, FViewport* Viewport, FViewElementDrawer* ViewDrawer, int32 StereoViewIndex)
{
bool bReturn = Super::CalcSceneViewInitOptions(ViewInitOptions, Viewport, ViewDrawer, StereoViewIndex);
if (bBlack && PlayerController && PlayerController->PlayerCameraManager && PlayerController->PlayerCameraManager->bEnableFading)
{
bBlack = false;
}
if (bBlack) {
ViewInitOptions.OverlayColor = FLinearColor::Black;
ViewInitOptions.OverlayColor.A = 1.0f;
}
return bReturn;
}
- Create UUserWidget, override NativeConstruct, call StartCameraFade
protected:
UPROPERTY()
bool bFirstLoad = true;
virtual void NativeConstruct() override;
void UHUDWidget::NativeConstruct()
{
Super::NativeConstruct();
if (bFirstLoad) {
APlayerCameraManager* PlayerCameraManager = GetOwningPlayerCameraManager();
if (PlayerCameraManager) {
PlayerCameraManager->StartCameraFade(1.0f, 0.0f, 5.0f, FLinearColor::Black, true, true);
bFirstLoad = false;
}
}
}
- Load the widget on beginplay of player pawn
In the implementation code, you can see that the condition will disable the black screen if fading is enabled, so you can call a fade in the user widget NativeConstruct (I found that if you call the fade in earlier (e.g playercontroller onpossess), there is still a slight flash. If you don’t want a fade, you can change the conditions above, or set bBlack whenever you want (i.e set bBlack in NativeConstruct).
I found an easy solution to this problem!
My game is not an online game, but still, I was having the same issue because my character only spawns AFTER the dungeon is generated (procedural game).
The thing is that, during a small time windows, we are having a SpectatorPawn spawned.
So I created a BP_SpectatorPawn, I added a CameraComponent to it, and inside the camera, I changed: PostProcess → Color Gradient → Gain → Set to 0
Then, set in your GameMode, that spectator as your SpectatorPawn
This way, during that small frame, our camera will be fully black, until the real character spawns, with it’s own camera, that won’t have this BLACK postprocess setting on it.
I hope this helps someone!
This won’t work during replication
however I’ve posted a fix that will in a few repos already. You need to go to your project settings and create your own “localPlayer” class that derives from the base class and set the camera manager and set fade amount to black then after handle starting new player call a set fade on the camera manager to fade you back in from black. During replication the “localPlayer” class is the proxy used for the camera manager so any calls on your playercontroller won’t be respected for this single frame “which is why you get the quick 0,0,0 flash”
Comparing mordentral:Master…uno1982:VRCameraManagerFix · mordentral/VRExpansionPlugin
here is a PR I opened for VRE to handle a while back that should give you context to understand how to impliment