108. UE5 GAS RPG 实现地图名称更新和加载关卡

在这一篇里,我们将实现对存档的删除功能,在删除时会有弹框确认。接着实现获取玩家的等级和地图名称和存档位置,我们可以通过存档进入游戏,玩家在游戏中可以在存档点存储存档。

实现删除存档

删除存档需要一个弹框确认,防止玩家误操作,所以,我们需要一个弹框的用户控件。

创建一个新的蓝图,基于我们之前自定义的用户空间基类。

然后添加对应的UI,外层添加覆层是为了保证动态创建添加到视口时,位置正确,尺寸框内的组件为组成弹框的内容。

里面比较注意的点一个是边框的设置,我们需要将其设置为边界,然后调整边缘。

我增加了一个背景模糊,保证玩家注意点只关注到弹框。

在覆层这里,我们将事件修改为可视,这样,鼠标事件将不会传递到后面的ui上,将不会参数误触的问题

下面为制作完成的效果。

接下来,我们为弹框取消按钮和确认按钮绑定点击事件。

在取消时,我们只需要清除自身即可

在确认时,我们通过一个事件分发器,外部可以绑定事件分发器的回调,来绑定触发确认后的回调

增加删除功能

我们在GameMode里增加一个删除存档的函数,用于删除已经存在的存档

cpp 复制代码
	/**
	 * 删除存档
	 * @param SlotName 需要删除存档对应的视图模型实例名称
	 * @param SlotIndex 存档索引
	 */
	static void DeleteSlotData(const FString& SlotName, int32 SlotIndex);

实现就是通过函数获取存档,存在就删除即可。

cpp 复制代码
void ARPGGameMode::DeleteSlotData(const FString& SlotName, const int32 SlotIndex)
{
	//检查是否有对应名称的存档
	if(UGameplayStatics::DoesSaveGameExist(SlotName, SlotIndex))
	{
		//删除已保存的存档
		UGameplayStatics::DeleteGameInSlot(SlotName, SlotIndex);
	}
}

接着,我们在加载界面的视图模型里增加一个删除存档事件,用于用户控件蓝图调用

cpp 复制代码
	/**
	 * 删除存档
	 * @param Slot 点击存档的位置,以索引来代表
	 */
	UFUNCTION(BlueprintCallable)
	void DeleteButtonPressed(int32 Slot);

在实现这里,通过调用GameMode里的事件删除,然后修改显示用户控件枚举,更新对应存档UI显示的用户控件。

cpp 复制代码
void UMVVM_LoadScreen::DeleteButtonPressed(const int32 Slot)
{
	//删除存档
	const ARPGGameMode* RPGGameMode = Cast<ARPGGameMode>(UGameplayStatics::GetGameMode(this));
	RPGGameMode->DeleteSlotData(LoadSlots[Slot]->GetSlotName(), Slot);

	//修改用户控件显示
	LoadSlots[Slot]->LoadSlotStatus = Vacant; //修改为创建存档
	LoadSlots[Slot]->InitializeSlot(); //修改存档显示
}

接着,我们在对应的存档用户控件里增加一个按钮,用于删除存档。

在蓝图初始化回调里,我们绑定删除按钮的点击事件,创建一个弹框来添加到视口,并监听事件分发器的事件,如果在弹框选择了确认,将触发删除事件,我们使用添加到加载界面的视图模型的删除函数删除即可。

实现地图名称更新

在创建新存档这里,我们需要实现读取到地图的名称,并且地图名称需要是可以自定义的。

首先,我们修改加载界面使用的GameMode的父类,让其基础战斗场景使用的蓝图类,这样,它也会继承类里设置的数据,我们只需要在父类上设置,子类上也会成为默认值。

接着,我们将一些不必要的类设置恢复到之前状态,战斗场景使用的,不必要在加载界面使用。

接着,我们在c++里在GameMode类里增加一些配置,用于配置初始进入的地图和地图名称,并增加一个映射,可以增加多个地图。

这里映射使用了TSoftObjectPtr,这个指针只保存路径,如果不使用,对应的资源不会加载到场景,可以在需要时再加载。

cpp 复制代码
	//初始地图名称
	UPROPERTY(EditDefaultsOnly)
	FString DefaultMapName;

	//游戏初始地图
	UPROPERTY(EditDefaultsOnly)
	TSoftObjectPtr<UWorld> DefaultMap;

	//地图名称和地图的映射
	UPROPERTY(EditDefaultsOnly)
	TMap<FString, TSoftObjectPtr<UWorld>> Maps;

然后覆写BeginPlay函数,在BeginPlay里将初始地图加入到映射

cpp 复制代码
protected:
	virtual void BeginPlay() override;
cpp 复制代码
void ARPGGameMode::BeginPlay()
{
	Super::BeginPlay();

	Maps.Add(DefaultMapName, DefaultMap);
}

然后增加一个函数,用于进入对应地图

cpp 复制代码
void TravelToMap(const UMVVM_LoadSlot* Slot);

我们通过UGameplayStatics::OpenLevelBySoftObjectPtr加载软引用的地图,它在未使用时不会加载,所以在打开时,会出现卡顿。

cpp 复制代码
void ARPGGameMode::TravelToMap(const UMVVM_LoadSlot* Slot)
{
	const FString SlotName = Slot->GetSlotName();
	const int32 SlotIndex = Slot->SlotIndex;
	
	//打开地图
	UGameplayStatics::OpenLevelBySoftObjectPtr(Slot, Maps.FindChecked(Slot->GetMapName()));
}

接着打开蓝图,我们设置初始的地图和名称。

接着,我们需要在用户控件上让其自动更新名称,在存档的视图模型上增加对地图名称的相关设置

接着在加载界面视图模型里在创建存档时设置,

在获取存档后,记得设置存档用户控件使用的视图模型的地图名称。

存档视图模型可以获取到数据,我们接着增加一个函数,用于进入游戏的事件调用,用于打开新关卡。

cpp 复制代码
void UMVVM_LoadScreen::EnterGameButtonPressed(const int32 Slot)
{
	ARPGGameMode* RPGGameMode = Cast<ARPGGameMode>(UGameplayStatics::GetGameMode(this));
	RPGGameMode->TravelToMap(LoadSlots[Slot]);
}

最后,我们在显示存档的用户控件里绑定地图名称的显示

并绑定加载进度的点击回调,调用进入关卡事件,并测试即可。

相关推荐
妙为16 小时前
ue5 仿鬼泣5魂类游戏角色和敌人没有碰撞
游戏·ue5·碰撞
努力的小钟21 小时前
Unreal Engine 高效数组复制用法详解
ue5·游戏引擎·虚幻
Zhichao_971 天前
【UE5 C++课程系列笔记】32——读Json文件并解析
c++·ue5
吴梓穆2 天前
UE5学习笔记 FPS游戏制作42 按钮添加回调函数
笔记·学习·ue5
沾血滴蔷薇2 天前
虚幻5入门
数码相机·ue5
吴梓穆2 天前
UE5学习笔记 FPS游戏制作39 制作一个带有背景的预制面板 使用overlay和nameSlot
笔记·学习·ue5
AgilityBaby2 天前
UE5把动画导出为视频格式
ue5·游戏引擎·unreal engine
远离UE43 天前
UE5 Simulation Stage
ue5
吴梓穆3 天前
UE5学习笔记 FPS游戏制作38 继承标准UI
笔记·学习·ue5
蛋卷卷-3 天前
【UE5】发现意外的文件尾解决方法
ue5