Windows+左方向键,视口贴到左边;Windows+右方向键,视口贴到右边
一、视角切换:调整第一人称和第三人称的视角有两种方案,
1、双摄像机,通过使用SetActive来使能选定的相机
问题是:这对第三人称动画的质量要求非常高
2、双Mesh,通过SetOnlyOnwerSee和SetOwnerNoSee来指定玩家具体看到的是哪一个Mesh,接下来会主要采用该方式
二、开镜:也有两种方案
方案一简单分三种情况,一种是机瞄状态(红点或者无倍镜下执行开镜动作),第二种是狙击状态(含有高倍镜的枪才能触发),第三种仅仅是拉近镜头(堡垒之夜中无倍镜枪械的镜头拉近,适用于榴弹枪火箭炮等)
机瞄状态下:使用枪械自带的摄像头,无UI或者是引入UI(类似于holo),依据不同的枪还要调整摄像头的位置
狙击状态下:使用枪械自带的摄像头,放大
普通拉近:使用人物摄像头
当前问题是如何访问各种枪的摄像头CameraComponent?实际上,当Actor具备相机的时候,Set view target会自动以相机作为中心)
第三人称机瞄要额外做的事情太多(后续整理,下面是效果)
第二种方案是直接设置原相机的FOV,从属于方案一,比较简陋。
Yaw 和Pitch的获取需要改为Delta(ControlRotation-ActorRotation)的方式获取,驱动AimOffset节点正常工作,才能使得枪正确的进行pitch方向的瞄准。上一篇的结尾处解决了机瞄开镜的问题。
三、射击模式:单发(实际中单发是达不到shroud全自动的效果的,笑,主要是手速问题)、三连发(Brust)、全自动
单发:引入冷却(这里的冷却依照是否需要reload来做,如果需要reload,则进行reload,然后再发射子弹),否则,直接发射子弹
全自动:定时器,GetWorldTimerManager().SetTimer(TimerHandle, this, &ABaseWeapon::Fire,0.08 , true,0.f); //延迟时间0.f,第一次就会执行Fire,
三连发:定时器,但是引入定时器启动次数的计数,多来一个BrustFire,用于定时器的调用,再BrustFire中检测Brust定时器的执行次数
if (CanShot()) {
bIsInFireTimeDelay = true;
GetWorldTimerManager().SetTimer(TimerHandle, this, &ABaseWeapon::BrustFire, 0.075, true, 0.f);}
else {
bInBrustRound = false;//会出现由于子弹不够三连发只发了两发或者一发的情况
BrustCount = 0;//还需要重置BrustCount
}三连发的逻辑较为复杂一点
四、背包系统Inventory System初步(首先设计WeaponInventory):
药品、弹药这种小物品有一个Num属性用来, 记录数量,为了统计物品的数量,还要设置名称。
对于枪支,就不需要设置Num。 使用结构体来记录信息
PickUp(在发生collision的时候可选择PickUp,(按照之前的想法PickUp函数中可以选择销毁当前物品或者是在游戏场景中隐藏该物体,还是销毁的好,因为如果隐藏的话,一直DropDown再拾取的话,该物品会越来越多,DropDown那就直接在Drop的位置上生成物品。),但该想法是错误的,只有使用物品UseItem才能做到消耗物品
对应Inventory(尼尔机械纪元分两栏、武器栏和物品栏),这样的话TArray<WeaponBase*>WeaponInventory可以直接作为武器栏,相应的TArray<AActor*>ItemInventory就作为Item栏,PickUp则隐藏,并且设置物体为NoCollision
注意事项:Weapon要能够Tick,这样子在SetActorHiddenInGame(false)之后才能够显示出来
首先设计WeaponInventory需要解决的问题:
1、weapon要能(并且放的位置应该在人物的面前)以随机的姿态放到地面还是立在地面?当前解决方案:在人的面前横放
FRotator是(Pitch,yaw,roll) FVector ItemOrigin=GetActorLocation() + FVector(0, 0, -70)+GetActorForwardVector()*120;
FRotator ItemRotation = FRotator(90,GetBaseAimRotation().Yaw,0);
2、拾取操作:一种是发生Overlap直接进行自动拾取,简单粗暴,缺少交互性,但是有的时候就是不需要交互,修改版,Begin Overlap的时候将监听Enable玩家的输入,End Overlap的时候将禁用监听玩家的输入,Input F键(Event PickUp)拾取写在物品中
第二种是通过鼠标点击的方式交互式拾取,这也是一种通过射线检测的拾取方式<视觉拾取>,适合RPG,策略游戏
第三种是通过准星瞄准进行射线检测的方式,需要记录Overlaping的单个物体<视觉拾取>,适合FPS.如果晕3D的话这种方式就会很难受
我原本实现Overlaping后,记录该Overlaping的物体,并设置该Overlaping物体的bCanBePickUp为true(该属性值在EndOverlap事件中设置为False),(这种方式的弊端在于如果有两个或多个离得比较近的物体,只有一个是自己想拾取的,那么就会出现误拾取的操作)
第四种是通过UI的方式,其实UE4蓝图提供了Get Overlaping Actors。这样子比较方便UI操作。(可以用bAutoPickUp来表明该物体能否被自动拾取,这样子就可以结合第一种)PickUpItem(ItemActor* ItemToPickUp)最终是和UI绑定使用的。
目前来说药品物件等直接使用自动拾取即可,枪支的话可以使用第三种方式进行拾取。并且都可以通过第四种方式拾取。目前测试框架先用自动拾取 。
3、切换装备:
保持人物手中必须有一把枪(动画资源有限,暂时不做没有枪状态下的逻辑),(可以添加背包的枪支上限)
第一种方式:需要来回的改变背包中的元素,不合理。
鼠标滚轮向上切:检测背包中是否有枪,有的话,切换成背包的第一把。并把手头的枪放进列表最后。
鼠标滚轮向下切:将背包最后一把枪和当前枪换,手头的枪放到列表的最前面
第二种方式:提供一个WeaponIndex,
通过WeaponIndex的记录表明当前访问到哪一个位置
丢枪后要DetachFromActor
所有枪丢完后Zoom会出问题,要修改
五、设计ItemInventory
第三次修改架构主要是weapon也是一种Item,
1、建立两个类:BaseItem(属于Actor),ItemInventoryComponent(属于ActorComponent),并且把BaseWeapon的基类改为BaseItem,初步完善类功能
需要注意的是子弹的Pickups和实际射出的子弹在造型上的不同(不应该把一颗子弹放在地上让人家去捡,而是应该把一盒子弹放在地上
对于子弹盒,需要把ItemNum用起来,而且在拾取的时候检查是否已经存在列表中了,如果存在,就把该种物品的数量增加就好。
暂时没有找到可以TArray中的API,所以就使用for循环根据ItemName遍历搜索了。
需要思考CurrentWeapon什么时候会为空(限制,手头只有一把枪的时候不能丢弃)
2、编写枪使用子弹的部分逻辑 ,主要是弹夹容量,子弹数量,背包中子弹数量这样子。
有想过类似堡垒之夜的库存整理方式,那么就需要额外的做一个弹药库。
六、UI设计
需要解决的问题:存在有的时候丢弃Drop中SetActorHiddenInGame(false)执行失败的情况。可能是Bug。
接下来进行UI的设计,官方有一套Drag and Drop教程
几点说明:
Texture2D要使用Make brush from Texture 绑定,不能够直接绑定图片
对于含有Button的,Override On Mouse Button Down不会执行(事件不触发),使用Preview on Mouse Button Down可以正常执行
当前的打算是把这套系统和GAS结合起来,为了学习GAS,看了Udemy的一套视频教程,感觉讲的挺好的
七、积分系统,经济系统
八、敌人
九、局域网
(本篇内容用于记录当下的进度,已经过程中遇到问题时的一些思考)
停止射击游戏的研究了,现在可以着手自己想做的游戏了