UE5 - 制作《塞尔达传说》中林克的技能 - 14 - 技能面板

发布于:2025-06-26 ⋅ 阅读:(17) ⋅ 点赞:(0)

让我们继续《塞尔达传说》中林克技能的制作!!!
UE版本:5.6.0
VS版本:2022
本章节的核心目标:技能面板
先让我们看一下完成后的效果:

第14章效果

本章节项目链接:
通过网盘分享的文件:14_技能面板
链接: https://pan.baidu.com/s/1BcNuIlxd2elJZd70RfJgug 提取码: rd7w
–来自百度网盘超级会员v3的分享


已经完成的功能:

动作 按键 是否完成
移动 W、S、A、D 完成
疲劳 完成
冲刺 Left Shift 完成
滑行与跳跃 Space 完成
下落 完成

预计制作的技能

技能(符文) 按键 是否完成
RBB(方向遥控炸弹) 未设定 未开始
RBS(圆形遥控炸弹) 未设定 未开始
Mag(磁铁) 未设定 未开始
Stasis(时间静止) 未设定 未开始
Ice(冻结) 未设定 未开始

UI交互

UI面板 按键 是否完成
打开(关闭)技能面板 Tab 进行中

本章节的项目文件:

技能的图标:

在这里插入图片描述

说明:每种技能共有4个图标,用来表示4个不同的状态。
Disable_Hover_Pressed:表示的是鼠标在未选中的图标上悬停和按下的效果。
Disable_Normal:表示的是未选中的图标(正常状态下的显示)。
Enable_Hover_Pressed:表示的是鼠标在选中的图标上悬停和按下的效果。
Enable_Normal:表示的是选中的图标显示的效果。


0.导入素材

  将文件夹内的图片全部拖拽进UE中。
在这里插入图片描述
  为了防止模糊,我们将这些图片的压缩方式设置为UserInterface2D
具体操作为:全选图片=》右键【资产操作】=》【编辑属性矩阵中的选择】
在这里插入图片描述
选择【压缩】=》压缩设置【UserInterface2D】
在这里插入图片描述


1.ZSCharBase.h中新建符文的枚举类

UENUM(BlueprintType)
enum class ERunes : uint8
{
	R_EMAX UMETA(DisplayName = "EMAX"),
	R_RBB UMETA(DisplayName = "方形遥控炸弹"),
	R_RBS UMETA(DisplayName = "圆形遥控炸弹"),
	R_Mag UMETA(DisplayName = "磁铁"),
	R_Stasis UMETA(DisplayName = "时间静止"),
	R_Ice UMETA(DisplayName = "冻结")
};

UCLASS()
class ZELDARSKILLS_API AZSCharBase : public ACharacter
{
	GENERATED_BODY()
public:
	
};


2.制作 - 显示技能图标用的格子

  目的1: 方便添加和管理图标的显示。
  目的2: 用于选中技能事件的逻辑交互(我们得获知玩家点击到了哪一个技能,然后才能执行后续的逻辑)。

2.1 新建用户控件蓝图(命名为:UI_RuneSlot)

  命名为UI_RuneSlot,用于显示技能图标。
在这里插入图片描述
在这里插入图片描述

2.2 为UI_RuneSlot添加尺寸框

  尺寸框(Size Box)作用:控制子控件尺寸的核心布局容器。在这里我们用到了它的子布局:宽度重载和高度重置
  具体而言:添加尺寸框到UI_RuneSlot下后,勾选:宽度重载和高度重载,并将其值设置为250,而后选择屏幕上所需
在这里插入图片描述

2.3 为UI_RuneSlot添加勾选框

  勾选框(Check Box)作用:在本次项目而言,主要作用为与鼠标进行交互,能够根据鼠标当前的一个操作情况显示图片。它的尺寸大小由尺寸框控制
在这里插入图片描述
  重命名为CB,并勾选其为变量。后续在蓝图中有用。
在这里插入图片描述

2.3.1(测试)为勾选框添加一张任意图片

  目的:根据这张技能图标显示情况,获取到图片在勾选框应该显示的大小。如下图所示,明显图片填入后偏大(因为这个图片是512x512的)。
在这里插入图片描述
  将图片的大小(Image Size)设置为250和250,就刚好合适(记下这个值,后面我们在蓝图中用得到)。
在这里插入图片描述

2.3.2(可选)禁用键盘选中技能图标

  如果你不希望玩家通过键盘来选择符文,你可以取消勾选框内的该属性。
在这里插入图片描述

2.3.3(可选)调整勾选框内显示的图片

  不调整的话,勾选框内显示的图片与你导入的图片相比会偏暗。这是由勾选框的前景颜色所引起的,取消继承,并将前景颜色改为全白既可以解决这个问题。
在这里插入图片描述

2.4 自定义添加图片功能(UI_RuneSlot蓝图)

2.4.1(蓝图)触发事件和设置的目标属性

  是编辑器内部的功能:Event Pre Construct 触发。设置的目标属性是勾选框的样式:Make Check Box Style
在这里插入图片描述

2.4.2(蓝图)设置Unchcked Image

  Unchecked Image的值通过Make Slate Brush赋值。这个笔刷绘制用的“颜料”,就是我们的素材。接下来为我们的笔刷准备“颜料”
在这里插入图片描述
  (1)Make Slate Brush的Image_Size设置为:(250,250)
在这里插入图片描述
  (2)新建变量(Texture 2D【纹理2D】),并命名为:IMG_D_N:用于接收名字带有Disabled_Normal的图片。Make Slate Brush的Image设置为:IMG_D_N
在这里插入图片描述

2.4.3(蓝图)设置Unchecked Hovered Image和Unchecked Pressed Image

  与2.4.2的操作完全一致。
在这里插入图片描述

2.4.4(蓝图)设置剩下的情况

在这里插入图片描述

2.4.5(蓝图)变量细节设置

  为了让这些变量可以由我们手动进行赋值(添加图片),因此我们要勾选可编辑实例和生成时公开
在这里插入图片描述

2.4.6(蓝图,可选)Foreground Color 设置

在这里插入图片描述

2.4.7(完成)功能完成示意图

在这里插入图片描述

2.5 选中符文的逻辑交互(UI_RuneSlot蓝图)

2.5.1(蓝图)添加事件-勾选状态变化时

  当玩家点击UI_RuneSlot后触发的事件。
在这里插入图片描述
在这里插入图片描述

2.5.2(蓝图)新建事件分发器

  事件分发器的作用:用于管理和调度事件的传递与响应。它允许广播事件,其他对象可根据需要订阅这些事件,从而实现对象间的消息传递。
  新建一个事件分发器,命名为OnClicked,我们让它传递如下两个参数:
  (1)新建变量(文本)Name:用于传递点击的符文名字
  (2)新建变量(ERunes)RuneType:用于传递点击的符文类型
  PS:记得勾选 (1)可编辑实例和(2)生成时公开
在这里插入图片描述

2.5.3(蓝图)新建函数获取设置格子选中状态

  目的:方便设置当前格子的选中状态
  (1)新建一个函数:命名为CheckStatus
  (2)内部逻辑:设置勾选框的Checked即可
在这里插入图片描述

2.5.4(完成)功能完成示意图

  编译执行后,回到UI_RuneSlot设计器界面,显示如下内容,为该部分功能完成。
在这里插入图片描述


3.制作 - 技能面板

  目的1:显示所有的技能(UI_RuneSlot)
  目的2:管理技能选中逻辑

3.1 新建C++脚本(命名为:ZSRuneSelections)

在这里插入图片描述
在这里插入图片描述

3.2 创建基于ZSRuneSelections的蓝图类

  右键ZSRuneSelections,选择创建基于ZSRuneSelections的蓝图类,并命名为UI_RuneSelections,放到UI文件夹下。
在这里插入图片描述

3.3 搭建技能面板

3.3.1(UI设计)添加画布面板

  (1)添加画布面板;
  (2)为画布面板,添加一个背景模糊(Background Blur),调整其参数:全覆盖,将偏移量置为0,模糊强度设置为1。【添加背景模糊的目的:让打开技能面板的时候,背景显示模糊。】
在这里插入图片描述

3.3.2(UI设计)添加水平框

  目的:管理技能。
  参数设置:
  (1)锚点:中心
  (2)位置X:0;位置Y:0;
  (3)对齐:(0.5,0.5)【说明:中心位置】;
  (4)尺寸X:1250【说明:有5个技能,每个技能长250,因此 为5x250=1250】。
  (5)尺寸Y:250【说明:高度就是250】
  (6)重命名:HB_RuneContainer,并勾选其为变量
在这里插入图片描述

3.4 添加格子到技能面板中

  拖拽5个UI_RuneSlot到水平框下。
在这里插入图片描述

3.5 设置UI_RuneSlot的参数

  以RBS为例
在这里插入图片描述

3.6 交互文本

  创建一个文本,该文本的作用是显示当前选中的技能名字。设置成如下图所示,并记得勾选其为变量
在这里插入图片描述


4. 代码 - 选择技能

4.1 技能面板与角色的交互

4.1.1 角色获知当前选中的技能

简单来说:ZSRuneSelections:告知ZSCharBase,当前选中的技能是谁。
具体而言:
ZSCharBase.h

	// 当前选中的符文
	UPROPERTY(EditAnywhere, Category = "Runes")
	ERunes ActiveRune{ ERunes::R_EMAX };

ZSRuneSelections.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "ZSCharBase.h"
#include "ZSRuneSelections.generated.h"

/**
 * 
 */
UCLASS()
class ZELDARSKILLS_API UZSRuneSelections : public UUserWidget
{
	GENERATED_BODY()

public:
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	AZSCharBase* playerRef;


	UFUNCTION(BlueprintCallable)
	// 设置:角色当前选中的技能
	void SelectedRuneType(ERunes RuneType); 
};

ZSRuneSelections.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "UI/ZSRuneSelections.h"

void UZSRuneSelections::SelectedRuneType(ERunes RuneType)
{
	// 玩家选择技能
	if (playerRef)
	{
		playerRef->ActiveRune = RuneType; // 更新玩家选中的技能
	}
}

4.2 UI_RuneSelections管理UI_RuneSlot

  我们希望通过UI_RuneSelections去管理所有的技能格子(UI_RuneSlot)。

4.2.1(蓝图)注册UI_RuneSlot的OnClicked事件的响应函数

  通过UI_RuneSelections注册UI_RuneSlot的OnClicked事件的响应函数。
在这里插入图片描述

  绑定的响应函数为(自定义的:SelectedRune),该函数的功能如下:
(1)告知角色当前选中的技能(SelectRuneType方法)
(2)UIRuneSlot根据自身是否被选中设置其选中状态Check Status)。
(3)UI_RuneSelectionsTXT_Hint显示的内容设置为当前选中的符文名字
在这里插入图片描述

  整体一览:
在这里插入图片描述


5.通过Tab键 - 玩家与技能面板交互

5.1 为UI_ZSLayout的画布面板创建控件切换器

5.1.1 UI_ZSLayout介绍

  UI_ZSLayout是本人文章UE5 - 制作《塞尔达传说》中林克的技能 - 9 - 耐力条制作(涉及蓝图)中,创建的。
  内部构造很简单,就一个耐力条,如下图
在这里插入图片描述
  涉及的蓝图逻辑与耐力条的值有关,如下图所示。
在这里插入图片描述
  蓝图中的Update Stamina函数的内容如下图:
在这里插入图片描述

5.1.2 创建控件切换器

  选中UI_ZSLayout的画布面板,右键,选择包裹->控件切换器
在这里插入图片描述
在这里插入图片描述

  重命名为WS,并勾选为变量
在这里插入图片描述

5.1.3 创建新的画布面板

  存放PB_ST的画布面板重命名为StatusPanel,将新建的画布面板重命名为RunesPanel
在这里插入图片描述

5.1.4 添加UI_RuneSelections

   将UI_RunesSelections拖拽到RunesPanel下面,调整大小,全覆盖,偏移值设置为0,并将其勾选为变量。
在这里插入图片描述

5.2 输入操作与交互逻辑

5.2.1 UE创建输入操作资产

  命名为:IA_ToogleUI
在这里插入图片描述
  设置其为暂停时触发
在这里插入图片描述
  老规矩,到IMC_ZS_Settings添加,并设置为tab
在这里插入图片描述

5.2.2 (cpp)交互逻辑

ZSCharBase.h

	// 声明 唤出技能面板动作
	UPROPERTY(EditAnywhere, Category = "Inputs")
	UInputAction* ToggleUIAction;
	
	// 指向UZSLayout类型的UObject实例,用于管理UI布局的生命周期
	// 该指针由UE5垃圾回收系统自动管理,无需手动释放
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI")
	TObjectPtr<UZSLayout> LayoutRef;
	
#pragma region ToggleUI
	UFUNCTION()
	// Tab - 按下 - 触发的函数
	void ToggleUI_Started(const FInputActionValue& val);
#pragma endregion


	UFUNCTION(BlueprintImplementableEvent)
	// 获取角色当前切换的【画布面板】编号
	// 如当前的Status Panel 编号为:0
	int32 GetWSIndexInfo();

	UFUNCTION(BlueprintImplementableEvent)
	// 设置角色当前切换的【画布面板】编号,用于与UI交互
	// 如我设置为 0:则关闭技能面板显示
	void SetWSIndex(int32 index);

ZSCharBase.cpp

void AZSCharBase::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	// UI
	EIComp->BindAction(ToggleUIAction, ETriggerEvent::Started, this, &AZSCharBase::ToggleUI_Started);

}


void AZSCharBase::ToggleUI_Started(const FInputActionValue& val)
{
	AZSPlayerController* PC = Cast<AZSPlayerController>(Controller);

	// 判断当前显示的面板是否为 技能面板
	if (GetWSIndexInfo() == 1)
	{
		// ----- 隐藏技能面板 ------
		// 关闭鼠标显示
		PC->bShowMouseCursor = false;

		// 将玩家控制器的输入模式设置为仅游戏模式
		PC->SetInputMode(FInputModeGameOnly());

		// 继续游戏
		PC->SetPause(false);

		// 隐藏技能面板 - 将控件切换器的索引设置为0(状态面板)
		SetWSIndex(0);
	}
	else
	{
		// ----- 显示技能面板 ------
		// 显示鼠标 - 我们要用来选技能
		PC->bShowMouseCursor = true;

		// 设置玩家控制器为游戏与UI混合输入模式,并聚焦到指定UI组件
		// 让玩家能够通过鼠标与UI元素进行交互
		FInputModeGameAndUI InputHandle;
		InputHandle.SetWidgetToFocus(LayoutRef->TakeWidget());
		PC->SetInputMode(InputHandle);

		// 暂停游戏
		PC->SetPause(true);

		// 显示技能面板 - 将控件切换器的索引设置为1
		SetWSIndex(1);

	}

}

5.2.3(蓝图)交互逻辑

  先添加IA_ToogleUIBP_Player中。
在这里插入图片描述

  实现GetWSIndexInfo
(1)获取到Layout Ref(也就是咱们的ZSLayoutUI)
(2)拿到其下的WS,返回激活的Index。
(3)若是LayoutRef的值无效,返回-1(即:什么都不会做)
在这里插入图片描述

  实现SetWSIndex
(1)获取到Layout Ref(也就是咱们的ZSLayoutUI)
(2)(2)拿到其下的WS,设置其Index(为传入的Index)。
在这里插入图片描述


第14部分完成啦!!
十分感谢大家的阅读、点赞、收藏!!
如果有不足之处,有疑问之处,有错误地方,欢迎大家在评论区讨论、批评、指正!!!


网站公告

今日签到

点亮在社区的每一天
去签到