【UE4 C++】角色与道具、技能的互动(下)
前言
上一章已经把道具实现好了,现在就把界面做一下,让角色和道具之间具有联系,并且给角色一个加速的技能。
功能介绍:
我们点击运行之后,左上角会出现血条和体力条,右上角会出现金币数。
当我们角色按下左shift键的时候会消耗体力条,并且人会加速。
当体力条耗尽的时候体力条会处于恢复状态,在这个状态下无法使用加速按钮。
当拾取金币时金币数会增加,道具消失(为啥金币上有火???),碰到爆炸物的时候会扣血。
制作HUD UI
先将上边的这个界面做一下。
界面上有血条、体力条、金币数。
金币数UI实现
右击空白处新建小装置蓝图:
重命名为WB_Coin
,命名要遵守命名规范,WB为Widget Blueprint的简写,下划线后为我们所取的名字。
双击打开界面, 看到右上角,打开Panel:
将Canvas Panel删除
把Horizontal Box 拉到他的位置,Size Box拉到它的下面,点击Fill,填充整个区域;在Common中找到Image,拉到Size Box的下面,这里使用Size Box的好处在于它不会将图片进行拉伸,把图片弄的很难看
找到右边的细节面板,找到下面这个界面,将选择我们的图片。
如果之前没有图片资源,那么到网上下载好我们想要的图片之后,找到下图界面,点击 Import即可。
找到下图界面,将Text Box 拖到与 Size Box 同级的位置。
点击Fill,下面两个也可以按照我那样操作,可以让文本处于区域的中间位置。
他们之间的层级关系如下:
效果:
体力条、血条UI实现
这两个就更简单了:
按照这个层级关系摆放:
以血条为例:
Progress Bar 在Common里面。
Progress 点击 Fill
进度先设置为一个 20 % 20\% 20%
血条颜色我们设置为红色:
再新建一个体力条,和这个也是类似的。
总界面UI实现
层级关系如下:
先拉入两个水平盒子:
都点击填充, 第一个水平盒子设置为需要这样设置一下:
代表的是我们的那个血条、体力条等UI的总共区域。
再添加三个垂直盒子
都点击Fill, 第一个第二个第三个。
在第一个垂直盒子中放入两个水平盒子:
代表的是血条的位置和体力条的位置,他们之间是有间隙的,所以将间隙设置为10
然后放入我们的血条和体力条,在用户创建这个地方可以找到我们之前创建的。
都点击填充。
第三个位置放入我们硬币界面,点击Fill。
UI界面制作完成,接下来我们要让这个界面显示到屏幕中。
创建玩家控制器C++文件
右键新建C++类,创建一个继承PlayerController的类,我这里命名为:MainPlayerController
。
打开之后会看到什么功能函数也没有。
.h 文件
public: UPROPERTY(EditAnywhere, BlueprintReadWrite)TSubclassOf<UUserWidget> HUDAsset;UUserWidget* HUD;protected:virtual void BeginPlay() override;
HUDAsset
就是储存widget Blueprint的变量,就是我们刚刚创建的那些界面资源。
HUD
就是一个用户控件对象
重写BeginPlay()函数。
.cpp文件
- BeginPlay
添加头文件: #include "Blueprint/UserWidget.h"
如果蓝图中设置了HUDAsset
变量,那么就可以创建一个HUD 实例, 然后让它设置在我们的界面中能够看到我们的空间对象。
void AMainPlayerController::BeginPlay()
{if (HUDAsset) {HUD = CreateWidget<UUserWidget>(this, HUDAsset);}if (HUD) {HUD->AddToViewport();}
}
找到.Build.cs
文件,在PrivateDependencyModuleNames.AddRange
中添加"UMG"
模块,要不然编译器识别不了,无法通过编译。
然后以这个文件为父类创建蓝图,在蓝图细节面板中加入我们之前创建的界面:
打开主编辑界面,看到世界设置,在Game Mode 中选择我们新建的玩家控制器。
这样界面中就能显示啦!
接下来就要设置界面的动态变化了。
角色C++文件设置
.h文件
- 声明血量、最大血量、体力值、最大体力值、硬币数。
UPROPERTY(EditAnywhere, BlueprintReadWrite) float Health; // 当前血量UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)float MaxHealth; // 最大血量值UPROPERTY(EditAnywhere, BlueprintReadWrite)float Stamina; // 体力值UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)float MaxStamina; // 最大体力值UPROPERTY(EditAnywhere, BlueprintReadWrite)int32 Coins; // 硬币数
写int
的时候最好写int32
,如果写int
,电脑会根据配置来设置int
的占位情况,就有动态的变化了,不方便后期维护。
- 声明受到伤害之后的反应函数
void SufferDamage(float Damage);
(代表消极影响) - 声明死亡函数
void Die();
- 声明拾取金币函数(代表积极影响)
void Pickup(EPickupType Type, uint32 Count);
EPickupType
代表的是类型,需要在前面声明:
enum EPickupType {PT_Coin
};
当前只有一个类型看不出来优势,但是随着类型的越来越多,他的优势就体现出来了,这是一种项目思想,为后期维护做好准备。
- 声明角色当前状态
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)EStatus CurrentStatus;
EStatus
需要在前面声明一下:
UENUM(BlueprintType) // 可蓝图化
enum class EStatus : uint8 {ES_Normal UMETA(DisplayName = "Normal"),ES_Sprint UMETA(DisplayName = "Sprint")
};
这个声明就是让类型可蓝图化,在蓝图中显示类型的东西就标签后面显示的名字:“Normal”、“Sprint”
代表的是角色是处于平常状态,还是加速状态。
- 声明设置角色状态
void SetStatus(EStatus Status);
- 声明普通跑步速度
UPROPERTY(EditAnywhere, BlueprintReadOnly)float RunSpeed;
- 声明加速跑步速度
UPROPERTY(EditAnywhere, BlueprintReadOnly)float SprintSpeed;
- 声明加速开始、加速结束做出的反应函数
UFUNCTION()void BeginSprint();UFUNCTION()void EndSprint();
- 声明是否已经耗尽体力
UPROPERTY(EditAnywhere, BlueprintReadOnly)bool IsExhausted;
- 声明恢复体力的速度
UPROPERTY(EditAnywhere, BlueprintReadWrite)float StaminaDrainRate;
.cpp 文件
- BeginSprint()
开始冲刺的时候,只要他不是耗尽状态,那么我们就把他的状态设置为冲刺状态。
如果是耗尽状态,按Shift键是没有任何响应的。
if (!IsExhausted) {SetStatus(EStatus::ES_Sprint);
}
- EndSprint()
冲刺结束,将状态设置为平常状态。
SetStatus(EStatus::ES_Normal);
- Tick(float DeltaTime)
因为我们的体力是可以恢复的,而这个恢复状态是动态的,所以要每一帧都要更新它。
我们首先要将恢复体力的值计算出来。
如果是平常状态,那么我们的体力值就可以恢复,先将恢复的体力值计算出来,如果超过了最大体力值,就直接设置为最大值,并且要维护是否耗尽变量,让他保持非耗尽状态。如果没有超过最大体力值,计算出来的值就是当前的体力值。
如果是加速状态,那么我们的体力值就处于消耗的状态,先将消耗之后的体力值计算出来,如果小于零(已经消耗完了),就直接设置为0,并且要维护是否耗尽变量,让他保持耗尽状态, 加速状态改为非冲刺状态。如果没有小于零,计算出来的值就是当前的体力值。
float Delta = StaminaDrainRate * DeltaTime;
switch (CurrentStatus) {case EStatus::ES_Normal:
{float Tmp = Stamina + Delta;if (Tmp < MaxStamina) {Stamina = Tmp;}else {Stamina = MaxStamina;IsExhausted = false;}break;
}
case EStatus::ES_Sprint:
{float Tmp = Stamina - Delta;if (Tmp > 0) {Stamina = Tmp;}else {Stamina = 0;IsExhausted = true;SetStatus(EStatus::ES_Normal);}break;
}
}
- SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
设置键盘输入,我们加速是要按键的,所以将左shift与人物加速要绑定起来。
打开UE4编辑界面,点击Edit,点击项目设置,
点击Input,按照下图设置
添加下面的内容,将按键与角色冲刺绑定起来。
PlayerInputComponent->BindAction("Sprint", IE_Pressed, this, &ARole::BeginSprint);
PlayerInputComponent->BindAction("Sprint", IE_Released, this, &ARole::EndSprint);
- SufferDamage(float Damage)
先预计算一个生命值并将他约束在0 到 MaxHealth 之间。如果声明值小于等于零,调用死亡函数。
float Tmp = Health - Damage;
Tmp = FMath::Clamp(Tmp, 0.f, MaxHealth); // 约束到 0 - max 之间
Health = Tmp;
if (Health <= 0) {Die();
}
死亡函数暂时没有做什么功能。
void ARole::Die()
{}
- Pickup(EPickupType Type, uint32 Count)
拾取金币函数实现
根据拾取的类型增加金币数量。
switch (Type) {case PT_Coin:Coins += Count;break;
default:break;
}
- SetStatus(EStatus Status)
设置人物状态
普通状态就让他的奔跑速度为普通的奔跑速度,冲刺状态就设置速度为冲刺速度。
CurrentStatus = Status;
switch (CurrentStatus) {case EStatus::ES_Normal:GetCharacterMovement()->MaxWalkSpeed = RunSpeed; break;
case EStatus::ES_Sprint:GetCharacterMovement()->MaxWalkSpeed = SprintSpeed;break;
default:break;
}
爆炸类设置
.h文件
- 增加储存爆炸伤害的变量
UPROPERTY(EditAnywhere, BlueprintReadWrite)float Damage;
.cpp文件
构造函数 增加
Damage = 10;
OnOverlapBegin
增加,如果与爆炸物碰撞的是角色,那么就要调用角色的伤害函数。
Cast为类型转换,转换成功返回地址,失败返回空指针。
if (OtherActor) {ARole* role = Cast<ARole>(OtherActor);if (role) {role->SufferDamage(Damage);}
}
拾取类设置
.cpp文件
- OnOverlapBegin
重叠之后让角色的金币数+1,这里可以拓展,设置我们增加的金币数,后期可以增加食物加血之类的……
if (OtherActor) {ARole* role = Cast<ARole>(OtherActor);if (role) {role->Pickup(PT_Coin, 1);}
}
接下来就是将这些反应和我们的HUD结合起来了。
WB_Coin设置
点击我们显示硬币数的文本控件,
在细节面板中,找到内容,创建绑定:
蓝图这么画:
整体思路就是:创建一个角色变量RefRole, 开始的时候判断这个变量是否储存了值,如果没有,那么就通过获取玩家操控的pawn来类型转换为Role类并且赋值给RefRole变量,转换失败就按照默认的来。
转换成功之后,现在已经拿到了我们当前控制的角色,那么通过获取角色的硬币数传值给我们的文本。
WB_Health设置
点击在细节面板中绑定进度条的值
蓝图这么画:
思路和上面一样,注意一下进度计算就好了。
WB_Stamina设置
点击细节面板中绑定进度条的值
蓝图这么画:
然后我们最后再添加一个细节,就是恢复的时候是灰色的,还有体力的时候是黄色的。
在这个板块创建新绑定:
蓝图这么画:
前面一大推和之前一样,就是确保我们的角色获取到了,主要是后面这一段,通过判断体力值是否耗尽来选择我们要体现出来的颜色。
设置人物运动动画
先将我们之前设置的一维运动动画修改一下:
添加人物在什么速度应该是什么样的状态的动画:
动画蓝图添加如下:
完工!
【UE4 C++】角色与道具、技能的互动(下)相关推荐
- 深入好文:数字经济技能:基于角色的数字技能培养方法、行业趋势、未来及未来的关键角色、这些角色的学习路径
我们正处于新的工业革命之中,蒸汽推动了第一次工业革命,电力推动了第二次工业革命,数字计算推动了第三次工业革命.根据世界经济论坛的说法,"定义第四次工业革命 (Fourth Industria ...
- 蓝图解锁怎么用_[UE4蓝图][Materials]虚幻4中可互动的雪地材质完整实现(一)
不说废话,先上个演示图 最终成果(脚印,雪地可慢慢恢复,地形可控制) 主要原理(白话文): 假如你头上是块白色并且可以透视的平地,来了个非洲兄弟踩上面,你拿起单反对着上面拍了一张,照片如下 把脚印稍作 ...
- ue4 改变枢轴位置_[UE4蓝图][Materials]虚幻4中可互动的雪地材质完整实现(一)
不说废话,先上个演示图 最终成果(脚印,雪地可慢慢恢复,地形可控制) 主要原理(白话文): 假如你头上是块白色并且可以透视的平地,来了个非洲兄弟踩上面,你拿起单反对着上面拍了一张,照片如下 把脚印稍作 ...
- ue4 改变枢轴位置_[UE4蓝图][Materials]虚幻4中可互动的雪地材质完整实现(二)
上一篇: [UE4蓝图][Materials]虚幻4中可互动的雪地材质完整实现(一)zhuanlan.zhihu.com 10.新建一个MaterialParameterCollection(材质参 ...
- 实时互动下视频 QoE 端到端轻量化网络建模
在实时视频互动中,影响观众对视频体验的有较多且复杂的因素,包括:画质.流畅度以及与其耦合的观看设备等.传统客观算法会利用网络传输或编解码参数拟合接收端人的感知体验,或者使用图像质量结合其他相关参数拟合 ...
- [unreal4入门系列之十] UE4添加角色到场景中
现在我们已经有了一个场景并且运行了,我们需要添加一个角色到场景中.要这样做,我们必须从UE4的GameFramework类继承它. 一. 打开上次创建的关卡 如果你已经关闭了项目,并且保存了上次创建的 ...
- DevOps组织IO专业人员新角色分析与技能提升
最近在"Top 10 Trends Impacting Infrastructure & Operations for 2019"中Gartner指出,十大趋势之一是I&a ...
- 项目管理——产品开发各角色职能及技能要求
PDT经理(LPDT) 职责说明 定义项目研发过程,组建项目团队并明确职责,定义项目研发过程的度量指标: 主导制定并维护项目主计划,并协调各种资源实施PDT的管理工作: 统筹管理项目立项阶段到发布阶段 ...
- 【UE4】UAbilityTask_Repeat 潘森E技能
结构 Module GameplayAbilities Header /Engine/Plugins/Runtime/GameplayAbilities/Source/GameplayAbilitie ...
最新文章
- Lucene之删除索引(备忘)
- 三家逐鹿,私有化部署能帮神策数据杀出重围么?| 公司调研
- 沧州学计算机设计大赛,沧职两学子全国工业机器人技能大赛获奖
- python哪个文字转语音好用_【python3】Python十行代码搞定文字转语音
- BugkuCTF-MISC题cisco(writeup)
- 数学 —— 计算几何 —— 平面分割问题
- 遇上放养型导师,论文就业该咋办?
- autojs命令代码大全_各个主流品牌手机的命令代码大全,安卓工程模式的指令大全!...
- 北大计算机专业毕业论文,北京大学毕业论文格式范本
- 高等数学知识框架梳理
- bugku 旋转跳跃
- 成为独立游戏制作人需要注意的六件事
- 高斯公式(div:点乘)
- python图形模块_Python图像处理PIL各模块详细介绍(推荐)
- 【Ubuntu】Ubuntu18.04无法识别移动硬盘、U盘解决方法
- 让你一步步成为运维专家之各种运维脚本
- License Server
- matlab 求概率密度,MATLAB如何使用pdf函数计算指定分布的概率密度函数
- process lasso 优化原理
- c语言for循环笔记,【学习笔记】【C语言】循环结构-for
热门文章
- 信息融合概念和主要方法
- Android ionic resource style/Theme.AppCompat.Light.NoActionBar (aka x.x.x:style/Theme.AppCompa
- 银河麒麟Kylin_s10_sp2安装Oracle11g(FS)(亲测有效)
- 计算机启动F1正在准备自动修复,win10系统卡在正在准备自动修复如何解决
- 快速了解统计学之辛普森悖论
- 设计原则之【单一职责原则】
- HTML标签和标签的属性
- 64位matlab扩大内存的方法,Matlab增大内存方法外传及性能测试报告
- 密码学系列之一:密码学的前世今生
- PHP+HTML 实现blob链接视频播放