GameDesign 板


LINE

网页版 https://yekdniwue.blogspot.com/2020/08/CustomMove2.html 简介 在前一篇我已经介绍一个完整的范例, 说明如何制作一个支援网路的功能, 如何做测试, 跟如何验证这个做好的功能, 在网路延迟的环境是否能正常运作。 前一个做法确定是不行的,玩家会感到画面不流畅。 因此本篇要介绍如何正确地修改移动相关的功能, 让Server端能够信任Client发送的指令, 避免Server频繁的矫正Client的位置。 这篇其实会比较偏向程式码实作,叙述会少很多。 简单来说就是看code比较快啦。 当初是从CharacterMovementComponent的Crouch挖出来的。 所以如果想要自己试试看的话,可以去挖出引擎有关Crouch的程式来看。 跟之前一样,里面的程式码都是我经过精简过了, 多余的实作项目我尽可能的都没列在里面, 所以最好还是按照顺序看完,以免出错。 再继续往下看之前,请确认以下的词你都知道是什麽意思: 1. Replicated Property 2. ROLE Authority 3. ROLE Simulated Proxy 4. ROLE AutonomousProxy 碍於篇幅的关系,这边不会多做介绍。如果有不熟悉的项目,请先前往 https://docs.unrealengine.com/en-US/Gameplay/Networking/Actors/Roles/index.html 恶补一下。 为角色新增移动模式 要制作这种由玩家的操作改变移动速度的作法, 其实要用到的是MovementMode的切换。 也就是制作一个新的MovementModeStrafe, 然後玩家按键的时候进到这个MovementMode, 放开的时候回到预设的MovementMode。 为了达到这个目的,我们总共需要新增 两个C++ class,以及一个BP class, 所以就是5个档案。 1. CustomCharacter 2. CustomMoveComponent 3. BP_CustomCharacter 而移动速度的改变,核心做法是override GetMaxSpeed(), 如果角色正在Strafe状态,MaxSpeed就回传 Super::GetMaxSpeed()*StrafeSpeedRatio CustomCharacter实作 大致上要实作的项目 CustomCharacter要能接受玩家的输入,所以跟之前的作法一样, 要开出Strafe以及UnStrafe两个函式给外部使用。 为了得知Strafe/UnStrafe的状态变化时机,所以我也开出了四个函式: 1. OnStartStrafe 2. OnEndStrafe 3. BP_OnStartStrafe 4. BP_OnEndStrafe 分别是C++以及BP的事件,提供给Gameplay需要的时候使用。 Server需要将Movement的状态同步给SimulatedProxy, 所以要新增一个变数bIsStrafed, 用来让SimulatedProxy获得事件通知。 也因为要Replicate变数bIsStrafed, 就要实作GetLifetimeReplicatedProps函式。 因为我们会以CustomMoveComponent取代 原生的CharacterMovementComponent, 我会建立一个指标指向CustomMoveComponent。 然後在Constructor的时候做替换。 替换MoveComponent以及同步变数 在Constructer替换MoveComponent, 然後在GetLifetimeReplicatedProps同步变数bIsStrafed, 并且只同步给Simulated Proxy。 因为Autonumous Proxy在输入的当下就切换状态了。 Strafe与UnStrafe实作 在CustomCharacter内,Strafe跟UnStrafe只是负责 将指令带给CustomMoveComponent, 後续就交给CustomMoveComponent在传递资讯的时候做处理。 变数同步与事件通知 收到变数bIsStrafed改变的通知时, 我们就是呼叫CharMovement对应的函式做处理。 而收到OnStartStrafe与OnEndStrafe时,就是呼叫BP版本的对应函式。 可能会有人有疑惑说为什麽一个事件要分C++跟BP两个函式, 而不是直接使用BlueprintNativeEvent直接一个函式定义起来。 主要是因为如果使用NativeEvent,那BP端是可以不呼叫C++实作的。 这个做法可以确保C++的部分一定会被执行到,不会被跳过。 到这边CustomCharacter的实作就结束了。 CustomMoveComponent实作 大致上要实作的项目 CustomCharacter的实作其实还是比较偏Gameplay层, 就是开出函式,建立事件通知。 CustomMoveComponent要实作的项目才是核心的部份, 里面的程式码比较少见(其他系统不会看到这些类别与函式)。 CustomMoveComponent的实作根据不同的ROLE,有不同的实作部份 1. Autonomuous Proxy handling 2. Authority handling Autonomuous Proxy要把bWantsToStrafe的资讯塞进FCustomSavedMove中, 这样client给Server的每个移动资讯都会带有这个移动是否是Strafe的资讯。 Authority从FCustomSavedMove内抽出bWantsToStrafe的资讯後, 就会以正确的速度计算移动,需要减速移动就会减速移动。 因为移动跟速度变化绑定在同一包, 所以Server不会认为Client的移动有异常,就不会做位置矫正。 一些基本杂项设定 设定PawnOwner: 有两个地方要设定PawnOwner。SetUpdatedComponent以及PostLoad。 Strafe与UnStrafe: 如果是Server(Authority)的话,直接变更bIsStrafed, 这样SimulatedProxy会在OnRep_IsStrafed收到通知并处理。 而到底移动速度的更改怎麽实作,就是透过检查现在是否是Strafe, 然後override GetMaxSpeed函式,如果Strafe中就乘上减速比例。 移动资讯传递 剩下的部份就是处理移动资讯的传递, 总共还有以下几个函式在CustomMoveComponent要实作: 1. UpdateCharacterStateBeforeMovement 2. UpdateFromCompressedFlags 3. GetPredictionData_Client 修改Client送给Server的移动结构 要把Strafe的状态告诉Server,就是要将Strafe的状态塞进移动资料。 在FSavedMove的CompressedFlags提供了四个custom的bit可供我们使用, 也就是说我们被允许最多建立出16种移动状态。 在这边我会借用FLAG_Custom_0的0代表UnStrafe,1代表Starfe。 为了修改FSavedMove,我们要实作自己的版本: class FCustomSavedMove : public FSavedMove_Character 而SavedMove是被装在FNetworkPredictionData_Client_Character里面。 所以我们要实作自己的版本: class FNetworkPredictionData_Client_Custom : public FNetworkPredictionData_Client_Character 然後实作函式AllocateNewMove,里面回传我们自定义的FCustomSavedMove。 最後就是在CustomMoveComponent里面实作GetPredictionData_Client。 在GetPredictionData_Client里面我们要回传自定义的class FNetworkPredictionData_Client_Custom。 这样就能以我们自定义的移动结构取代原来的移动结构了。 将Strafe状态整合进移动资料 可分为输入输出两种情况, 输入:Client把Strafe状态塞进移动资料传给Server。 输出:Server从移动资料获得Client送来的Strafe状态。 输入实作: Client(Autonumous)传送移动资料给Server的处理流程: CharacterMovementComponent::TickComponent() ReplicateMoveToServer SetMoveFor CanCombineWith PerformMovement UpdateCharacterStateBeforeMovement CallServerMove GetCompressedFlags SetMoveFor: 从CustomMoveComponent复制bWantsToStrafe到FCustomSavedMove。 CanCombineWith: 如果bWantsToStrafe有变动,那两个SavedMove要避免合并, 以免Strafe状态的资料因为合并而遗失。 UpdateCharacterStateBeforeMovement: 在套用移动前再次检查状态是否有变化。 GetCompressedFlags: 将bWantsToStrafe存入CompressedFlags的FLAG_Custom_0。 输出实作: Server(Authority)收到玩家资料的处理流程: ServerMove_Implementation MoveAutonomous UpdateFromCompressedFlags PerformMovement UpdateCharacterStateBeforeMovement UpdateFromCompressedFlags: 从SavedMove的FLAG_Custom_0取得Strafe状态,存入CustomMoveComponent。 UpdateCharacterStateBeforeMovement: 在套用移动前再次检查状态是否有变化。 Server端Strafe状态的变化事件会在这里触发。 程式码在哪? 说了这麽多,你一定想问"到底要不要附程式码" 你可以参考我当初找到的范例 [连结] 或是参考UnrealEngine的原始码有关bWantsToCrouch相关的部份。 或是参考我实作的版本,已做成Plugin,但是BP角色的串接就要自己实作了。 [连结] 最後一哩路 按照以上作法实作,BP的character改为继承CustomCharacter之後, 只要在使用者输入的时候呼叫Strafe/UnStrafe,就完成了。 其他的事情都已经在C++处理完毕。如图所示。 [图] 实作完毕後你可以用前一篇提的方法做测试, 会发现就算lag设为500ms也不会有异常。 可参考影片: [影片] 结论 本系列所提的方法是为了解决如果玩家操作可以改变移动速度, 如果没有把状态变化跟移动资料一起传给Server, Server与Client就会计算出不同的位置, 然後Client就会收到Server传来的位置矫正, 造成玩家感受不良的问题。 然而一般常见的玩家对玩家,例如缓速技能,冻结技能, 这种牵扯的对象不是只有玩家对Server, 就没有办法使用这种方式处理。 要解决这种问题的困难度也高很多。 目前没有继续往後研究下去,所以这个系列应该会到此结束。 哪一天真的有实作出来并且经过验证再分享吧(应该不会有机会)。 --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 59.120.146.90 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/GameDesign/M.1596596646.A.EE7.html
1F:推 coolrobin: 未看先推 08/05 21:24
2F:推 sampp1213205: 有没有考虑做教学影片放YouTube 08/05 21:49
3F:推 coolrobin: y大的内容比较偏引擎、技术研究 不太适合录成影片吧 08/05 23:25
4F:→ yekdniw: 有很多原因 主因是制作影片需要时间太长 08/06 10:01
5F:→ yekdniw: 所以暂时没有考虑 谢谢~ 08/06 10:01







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:BabyMother站内搜寻

TOP