金融情报局网_中国金融门户网站 让金融财经离的更近

TomLooman_ActionRoguelike_AssignmentThree

当前位置:金融情报局网_中国金融门户网站 让金融财经离的更近>股票 > 正文  2023-08-11 19:20:18 来源:哔哩哔哩

该专栏用于保存对TomLooman的ActionRoguelike项目的学习笔记,学习过程中的思考与记录不一定准确。

教程参考:/tomlooman/ActionRoguelike

基于的项目实现:/CarolBaggins2023/TomLooman_ActionRoguelike_Tutorial


(资料图片)

2023_08_07

Assignment 3(1):子弹飞行和爆炸音效,角色攻击特效,最大血量属性,伤害值UI,可交互血包,摄像头震动效果

先前我们制作了子弹飞行和爆炸的AudioCase,现在我们要使用它们。

我们在子弹基类中创建两个声音组件(UAudioComponent),并在编辑器中赋值。

其中子弹的飞行音效可以在子弹Spawn时就产生,所以我们想在子弹的BeginPlay中使用它,并且持续到子弹被销毁。因为飞行音效本身是循环的,所以我们可以用Activate激活声音。

爆炸音效在爆炸时产生,所以我们在Explode_Implementation中使用它,通过UGameplayStatics::PlaySoundAtLocation。其函数原型是static void PlaySoundAtLocation(const UObject* WorldContextObject, USoundBase* Sound, FVector Location, …),因为这里的参数要求是USoundBase类型,所以我们不能直接用UAudioComponent类型的成员变量,而是要获取UAudioComponent类中的Sound成员变量,

要实现角色攻击时的特效,我们先在SCharacter类中创建UParticleSystem类的成员变量。

之前在子弹类中我们也创建了粒子效果的成员变量,子弹的飞行效果成员变量是UParticleSystemComponent类,子弹的爆炸效果成员变量是UParticleSystem类。两个类的区别是粒子效果模板(UParticleSystem)用于定义粒子效果的属性和行为(是一种规则),而粒子效果组件(UParticleSystemComponent)用于实例化、渲染和控制粒子效果的运行时行为;或者目前的情况时,持续一段时间的、动态的、有位移的用UParticleSystemComponent,静态的、一瞬间的用UParticleSystem。

我们在攻击函数中通过UGameplayStatics::SpawnEmitterAttached使用这个粒子效果,其函数原型为UParticleSystemComponent* UGameplayStatics::SpawnEmitterAttached(UParticleSystem* EmitterTemplate, USceneComponent* AttachToComponent, FName AttachPointName),我们将粒子效果附着到角色的网格组件上,并附着到手部位置。

我们可以通过修改角色的Mesh组件使用材料来为角色添加类似受击发光的效果。

将原本连接到发光度的节点替换为我们的材料函数。

这个材料函数上半分支和之前受击发光物体的材料函数类似,区别在于加了一条表示颜色的分支。因为白色的RGB是(1, 1, 1),所以表示颜色的三维向量乘以一个常数可以表示不同颜色发光度。

我们将闪光速度转换为变量,在创建材料的实例后,就可以方便地在实例中调整闪光速度。将该材料实例应用到角色Mesh组件的Material后,就可以实现角色受击闪光的效果。

我们之前显示血量时使用的是类的默认值,但我们可以通过给角色创建一个最大血量的属性来替代。

我们在USAttributeComponent类中创建了一个最大血量的成员变量,并在构造函数中赋初值。

这样在血条UI的蓝图中,我们就可以直接使用新的血量和最大血量计算百分比,从而给血条材料中的参数赋值,改变血条不同颜色的占比。

也可以修改属性组件类中的ApplyHealth成员函数的实现,

我们之前制作了一个UI,这个UI将一个对象作为参数,在对象受击时创建该UI并传入自身,从而将对象的位置作为UI出现的位置。但我们并没有实现出现的UI就是受击伤害的效果。

我们所要做的就是用给UI中的Text变量赋值(将组件作为变量)。这里的逻辑是,(1)每当子弹与物体发生overlap后,就调用该物体的属性组件成员变量的ApplyHealthChange成员函数,ApplyHealthChange成员函数一边修改Health属性值(属性组件类中的float成员变量),一边将OnHealthChanged委托进行广播(属性组件类中的委托成员变量);(2)该物体的属性组件成员变量的OnHealthChanged委托在构造函数中已经与该物体的一些成员函数(这里是OnHealthChanged,与委托名相同,不要搞混)绑定,因此这些成员函数一直在监听委托是否触发,一旦触发就执行函数。

因此,要实现物体受击后,改变UI中的Text变量,可以给该委托多绑定一个函数,在这个函数中创建UI,然后将委托中的Delta参数传递给UI的Text变量(委托声明时有一个Delta参数表示伤害值,在ApplyHealthChange中也被使用)。我们通过蓝图完成,先将Delta赋值给一个float类型的变量,再在UI中把该float类型的变量赋给Text。

我们还可以给Text添加UI动画,和之前血槽旁边数字的动画类似,新增Animation,为Text新增Track,在时间轴上添加不同的Text,然后进行自动的插值。

动画完成后可以在蓝图中调用,放置在创建UI之后,

2023_08_07

Assignment 3(2):医疗包,攻击时相机震动效果

我们可以直接制作一个医疗包的C++类,继承之前创建的ISGameplayInterface接口类,类似于宝箱的实现方法。但是可以想到之后还会有很多类似的需要交互的物品,所以我们可以制作一个交互物品基类。

交互物品基类继承AActor和ISGameplayInterface,有一个碰撞组件,实现ISGameplayInterface中的纯虚函数(但实际上实现为空,因为每个交互物品实现的效果不同,所以在基类中不做任何操作)。

我们对交互物品的交互逻辑是这样的,我们与物品交互后,物品应不可见且无碰撞(进入失效状态),在一段时间后再回复可见和碰撞(恢复有效状态)。因此,我们创建了Set函数直接控制对象的可见性和碰撞,Show和Hide函数调用Set函数,并在Hide函数中通过时间句柄调用Show函数。

它们的实现如下。其中,Set函数中SetVisibility

的函数原型为void SetVisibility(bool bNewVisibility, bool bPropagateToChildren=false),所以它不仅控制父类成员的可见性,还能控制子类成员的可见性。

交互物品基类创建好后,我们的医疗包类就可以继承交互物品类。

我们在医疗包类中要真正地实现Interact函数,同时因为医疗包类自身要实现的功能,我们增加了治疗量成员变量。

在交互的实现中,我们非常自然地先判断触发交互的Actor是否有效,获取该Actor中的属性组件成员变量,并判断其有效性。这里增加了两个有些重复逻辑,第一个是如果Actor的血量是满的,就不能捡血包。第二个是判断交互后角色血量的实际变化,如果实际变量非零,则确实发生了交互,那么就调用Hide函数,血包进入失效状态。

教程提供了一些CameraShake的资产,我们可以尝试使用它们。当子弹击中目标时,我们让玩家的镜头发生抖动。

我们在子弹基类中添加CameraShakeBase子类的成员变量,并允许在编辑器中进行赋值。

我们在Explode中调用它。这里我们只考虑一个玩家的情况,所以使用GetWorld()->GetFirstPlayerController()获得第一个玩家的控制器,并在上面调用CameraShake,

关键词: