关键词: UE4 回放系统 升级 UE5 报错 DemoNetDriver GetDemoCurrentTime GetDemoTotalTime
背景
照着网上教的UE4的回放系统,也叫重播系统,英文Replay。做完了,测试运行正常,可升级到UE5却报了一堆 WorldSetting 和 Pauser 错。
本文将介绍如何解决这些错误,此方式不止在UE5中可以运行,也让你的UE4可以运行。
报错现象
抱歉忘了截图 反正就是有关 WorldSetting 和 Pauser 的错误。
查找问题
WorldSetting 文件里的 Pauser 追溯源码,看到如下图,“在4.23之后 这个属性就被弃用了,请使用GetPauserPlayerState()或者SetPauserPlayerState()”
所以猜测,UE4的版本一直在坚持维护,到了UE5,干脆直接放弃了。
那么,咱们更新一下新代码就可以了。
解决方法
请重点确认下图中,画红框的这几个地方。因为这几个函数名字变了。在旧版本是变量,新版本变成有返回值的函数了。
除了下图红框的部分,别的地方都沿用网上的其他回放教程就行,不用改。
下图是PC_ReplayerSpectator.cpp文件 是我创建的旁观者控制器,继承自PlayerController。它的头文件跟网上其他教程是一样的。
完整代码
// Fill out your copyright notice in the Description page of Project Settings.
#include "PC_ReplayerSpectator.h"
#include "Engine/World.h"
#include "Engine/DemoNetDriver.h"
APC_ReplayerSpectator::APC_ReplayerSpectator(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
bShowMouseCursor = true;//显示鼠标
PrimaryActorTick.bTickEvenWhenPaused = true;
bShouldPerformFullTickWhenPaused = true;
}
bool APC_ReplayerSpectator::SetCurrentReplayPausedState(bool bDoPause)
{
//设置暂停状态
AWorldSettings* WorldSettings = GetWorldSettings();
//设置抗锯齿为FXAA 和 关闭运动模糊,否则在回放暂停中画面会有问题。
//命令行 抗锯齿
static const auto CVarAA = IConsoleManager::Get().FindConsoleVariable(TEXT("r.DefaultFeature.AntiAliasing"));
//命令行 运动模糊
static const auto CVarMB = IConsoleManager::Get().FindConsoleVariable(TEXT("r.DefaultFeature.MotionBlur"));
if (bDoPause)
{
PreviousAASetting = CVarAA->GetInt();
PreviousMBSetting = CVarMB->GetInt();
//关闭运动模糊,关闭抗锯齿TXAA切换成FXAA,因为变速播放,跳放会对帧速率产生变化
CVarAA->Set(1);
CVarMB->Set(0);
//设置 暂停状态 ,当SetPauserPlayerState不为NULL时,则暂停
WorldSettings->SetPauserPlayerState(PlayerState);
//整个函数返回true,输出暂停。
return true;
}
CVarAA->Set(PreviousAASetting);
CVarMB->Set(PreviousMBSetting);
//当SetPauserPlayerState 为NULL时,则不暂停
WorldSettings->SetPauserPlayerState(NULL);
//整个函数返回false,输出继续播放。
return false;
}
//获取当前影片的总时间
int32 APC_ReplayerSpectator::GetCurrentReplayTotalTimeInSeconds() const
{
if (GetWorld())
{
if (GetWorld()->GetDemoNetDriver())
{
return GetWorld()->GetDemoNetDriver()->GetDemoTotalTime();
}
}
return 0.f;
}
//获取当前时刻的时间
int32 APC_ReplayerSpectator::GetCurrentReplayCurrentTimeInSeconds() const
{
if (GetWorld())
{
if (GetWorld()->GetDemoNetDriver())
{
return GetWorld()->GetDemoNetDriver()->GetDemoCurrentTime();
}
}
return 0.f;
}
//设置跳转到的时刻
void APC_ReplayerSpectator::SetCurrentReplayTimeToSeconds(int32 Seconds)
{
if (GetWorld())
{
if (GetWorld()->GetDemoNetDriver())
{
GetWorld()->GetDemoNetDriver()->GotoTimeInSeconds(Seconds);
}
}
}
//设置播放速率
void APC_ReplayerSpectator::SetCurrentReplayPlayRate(float PlayRate)
{
if(GetWorld())
{
if (GetWorld()->GetDemoNetDriver())
{
GetWorld()->GetWorldSettings()->DemoPlayTimeDilation = PlayRate;
}
}
}
附件:
PC_ReplayerSpectator.h 头文件 你或许会有用
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "PC_ReplayerSpectator.generated.h"
/**
*
*/
UCLASS()
class AUCDISPLAY_API APC_ReplayerSpectator : public APlayerController
{
GENERATED_BODY()
public:
APC_ReplayerSpectator(const FObjectInitializer& ObjectInitializer);
protected:
int32 PreviousAASetting;
int32 PreviousMBSetting;
UFUNCTION(BlueprintCallable, Category = "CurrentReplay")
bool SetCurrentReplayPausedState(bool bDoPause);
UFUNCTION(BlueprintCallable, Category = "CurrentReplay")
int32 GetCurrentReplayTotalTimeInSeconds() const;
UFUNCTION(BlueprintCallable, Category = "CurrentReplay")
int32 GetCurrentReplayCurrentTimeInSeconds() const;
UFUNCTION(BlueprintCallable, Category = "CurrentReplay")
void SetCurrentReplayTimeToSeconds(int32 Seconds);
UFUNCTION(BlueprintCallable, Category = "CurrentReplay")
void SetCurrentReplayPlayRate(float PlayRate = 1.0f);
};
祝你成功