UE4 回放系统升级到UE5之后的代码报错问题解决

关键词: 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。它的头文件跟网上其他教程是一样的。

UE4 回放系统升级到UE5之后的代码报错问题解决_第1张图片UE4 回放系统升级到UE5之后的代码报错问题解决_第2张图片

完整代码

// 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);

};

祝你成功

你可能感兴趣的:(ue4,ue5)