ACT浅思
ACT浅思
ACT 表现
动作
动作节奏:
flowchart LR
前摇--->攻击判定--->后摇-->后摇-可打断
需要控制好每个阶段的时间分配,表现不同的节奏;
较长的后摇可以方便玩家明确下一步操作(不攻击、打断后摇继续攻击),判定更明确;
较短的后摇可以增加动作连续性连续,提升手感;
动画配合:
动画曲线配合:从动画中提取曲线,配合曲线调整位移;比如移动,需要在脚落下的那一刻位移速度最大,其余阶段几乎不位移;
攻击方、受击方动画、位移需要匹配;
动作设计:
Anticipation & Follow Through:预期、跟随;在确定性的时间做更多奖励性的动作演出,此时玩家会更加专注,比如支援突击等玩家主动触发的明确时刻;利用跟随增强动画流畅感和力量感,比如格挡时的强化慢镜头,利用一些跟随,同时提供反应时间;再比如局外人物展示界面,在结束阶段利用 衣物飘带、尾巴 等动力学变化强化演出效果;
Slow In / Slow Out:慢入、快速表演、慢出;同时可以增加蓄力抖动等加强压迫感;
Exaggeration & Strong Posing: ...
[UE]ReplicationGraph浅析
ReplicationGraph浅析
简介
UnrealEngine 基本的网络同步在进行同步时需要对每个连接判断每个 Actor 是否需要同步,开销较大;
可以通过实现 Replication ,实现一个不同的 ReplicationDriver 来优化性能;
Replication 将 World 分为多个区域 Grid,把 Actor 根据所在 Grid 进行分类编组,可以快速找出需要同步的 Actor,同时确定哪些区域需要进行同步复制。
数据结构
classDiagram
class UReplicationGraph
FGlobalActorReplicationInfo :同步的 Actor 信息,包括
Settings:FClassReplicationInfo,每个 Actor Class 对应的同步配置,包括 CullDistance、ReplicationPeriodFrame、PriorityScale 等;
Events:FGlobalActorReplicationEvents Events,记录休眠状态的改变时,从休眠列表中添加或者移除;
FC ...
[UE]Networking源码浅析
Networking源码浅析
定义
Bunch:表示一组相关的网络数据,包含 RPC / 属性同步 等信息,UE 中 DS/Client 通信的基本单位。
Packet:UDP 的基本传输单位,可以打包一个或多个 Bunch,在接受端进行解析。
NetDriver:管理网络通信,比如管理连接、处理数据包的发送和接收、处理网络事件。
NetConnection:表示一个网络连接,与一个 NetDriver 关联,并通过 NetDriver 进行实际的网络通信。
Channel:管理网络传输,进行数据分类,提供 SendBunch、ReceivedRawBunch 方法,由 NetConnection 管理,一个 NetConnection 可以包含多种 Channel。
FObjectReplicator:处理对象的网络同步,保存属性快照,进行状态改变发送、更新同步状态、接受与发送消息。
ActorChannel:关联特定的 Actor 负责其同步,包含多个 FObjectReplicator 用于复制其 Actor、ActorComponent 。
FRepLayout:管理复制的 ...
[UE]弱网工具Clumsy的使用
弱网工具Clumsy的使用
Clumsy 用于弱网测试时,进行本地弱网环境的模拟,基于 WinDivert 实现,可以出模拟延迟、丢包等网络状态。
Downloads
下载地址:Clumsy;官方文档:Clumsy Manual
下载后的几个重点文件:
打开 Clumsy.exe 可以看到以下内容:
可以看出这里有几个重点的 Function,一般重点使用 Lag 延迟、Drop 丢包。
在 Filtering 填入对应的 Command 后,设置 Functions,点击 Start 即可开始模拟。
同时可以在 Config.txt 中,预设一些 Presets 方便下次使用。
UE DS 中的使用
对于 UE的 DS 环境,首先为了具体到某一个 Client / DS,采用 Filter Port 的机制,对某个具体的端口号进行操作。
用 netstat -aon\Findstr 进程ID,查询 DS/Client 进程,通过 UDP 进行链接。
DS 的 port 一般可以在启动命令中找到 -port=17777;
Client 的 port 可以在 DS 的 Log 中, ...
[UE]夺旗模式框架
夺旗模式框架
描述
夺旗模式:
场景里会按照一定的规则刷新出不同类型的旗帜(不同类型的旗帜有不同的得分、血量、表现等);
玩家会被分成若干个队伍,抢夺刷新出来的旗帜,将旗帜带到自己队伍目标点进行销毁,则可以获得分数;
玩家持有旗帜时,旗帜可能会掉落或被抢夺:被其它玩家撞击到则旗帜被抢夺到其它玩家身上;旗帜的血量归零则会掉落回场景;
有正式赛与加时赛两种类型的比赛,首先会开启正式赛;对于正式赛,率先达到目标分的队伍获胜;如果平局则开启加时赛,否则进行结算;对于加时赛,率先得分的队伍获胜,如果平局则以两队平局进行结算;
要点总结:
旗帜实体:旗帜本身有自己的类型、得分、血量;
旗帜刷新:场景内根据一定规则(倒计时刷新、旗子上缴)会刷出不同类型旗帜;
旗帜传递:玩家可以拾取场景里的旗帜、相互抢夺旗帜、掉落旗帜(持有旗帜血量归零)、将旗帜送给终点得分等;玩家可以组队,共享队伍得分;同队伍之间的玩家可以传递旗帜;
单局流程:所有玩家就绪分队后,传送到起始点准备开赛;如果一局比赛平分,一定条件下可以触发下一场比赛继续;
模式基础
单局流程
首先,一个完整的夺旗赛,由若干个子比赛构成,子比赛 ...
[UE]CommonParams解决方案
CommonParams解决方案
在实现业务框架的时候,经常需要支持传参的功能(比如 Buff 系统中,AddBuff 的时候,通常需要支持外部传入一个 BuffParams ,在内部解析出各种 Param 使用。)
这个参数需要支持基本的数据保存、同步等。
初始的想法
一个最简单的想法,是打包一个结构体,支持各种类型的传入,比如:
12345678910USTRUCT()struct Params{ UPROPERTY() uint64 uVar0; UPROPERTY() int iVar0; UPROPERTY() float fVar0;}
这样虽然很简单,同时可以通过反射来同步。
但是有一个巨大的问题,那就是在解析参数的时候,只知道 Var0 这种没有名字的抽象的概念,使用者需要记住 Var0 对应的是什么数据,很不直观。
CommonVariantParams
维护一个 CommonVariantParams,通过 TMap <FString, FVariant> ValueMap 来保存数据,同时自定义 ...
[UE]GameSubSystem简单实现
GameSubSystem简单实现
一种简单的维护 SubSystem 的解决方案,参考 UE 自带的 FSubsystemCollection 实现。
在维护各个业务时,经常需要将一个上层的 Manager,下面再拆出若干个子系统,需要一种快捷的方法快速扩展出一套 SUbSystem 系统。
基本结构
classDiagram
Manager..*FGameSubSystemCollection
class Manager {
SubSystemCollections : FGameSubSystemCollection~USubSystemBase~
}
class FGameSubSystemCollection {
FGameSubSystemCollection()
}
FGameSubSystemCollectionBaseUGameSubSystemBase
class UGameSubSystemBase {
LastTickTime : float
+ Init()
+ Uninit()
...
[UE]TeamSystem框架
TeamSystem框架
一个简单的组队系统:支持玩家的 加入、退出 队伍,以及维护队伍的各种数据(比如 Members、Score)。
首先需要一个全局的 TeamManager ,以及一个在 Player 身上的 TeamComponent 负责维护 Player 相关的组队信息;
同时,将业务拆分为多个 TeamSubSystems。
以及最重点的 数据同步,根据不同的数据类型,进行不同方式的数据同步。
TeamSubSystemBase
首先,需要将业务拆分为多个 SubSystem ,通过 TeamManager 持有 SubSystemCollection 来实现这个功能。
需要一个 TeamSubSystemBase ,在这里传入 System = TeamManager 以及为后续同步数据的分发做准备。
参考:[UE]GameSubSystem简单实现
123456789101112131415161718UCLASS(Abstract)class UTeamSubSystemBase : public UGameSubSystemBase{ GENERAT ...
[UE]CommonDelegate解决方案
CommonDelegate解决方案
实现业务时,经常需要用到全局级别的 CommonDelegate;
定义如下 UTestCommonDelegate,即可定义出 UTestCommonDelegate::GetDelegate()->OnTestEvent 这样的一个 Delegate;
123456789101112131415161718// TestCommonDelegateUCLASS()class UTestCommonDelegate : public UCommonDelegateBase{ GENERATED_BODY()public: UFUNCTION() static UTestCommonDelegate* GetDelegate() { return GetCommonDelegate<UTestCommonDelegate>(); } public: DECLARE_DELEGATE_AnyParams(FTestEvent, int32 /*IntVal*/); ...
[UE]LocalDS的启动
LocalDS 的启动
启动 DS
1234567set Map=ThirdPersonMapset PlayerNum=2set DSEXE=UnrealEditor-Win64-Debug-Cmdset DSProj=../../UnrealEngine/UE/Engine/Binaries/Win64/%DSEXE% ../../../../../TestProject/TestProject.uprojectrem -----DS-----start %DSProj% %Map% ? -MaxPlayers=%PlayerNum% -port=17777 -game -server -log=DS.log
这里的 DSProj 需要定位到该文件(根据不同的 UE Version、BuildConfig 构建出的名字可能不同):
后续的 .uproject 路径,也是以该 .exe 为基础位置的相对路径。
同时,这里通过 %Map% 指定了 DS 上的 Map,-port 指定了本地端口号,并将 log 输出在 DS.log 中
特别的,如果不通过 %Map% 指定对应 Map ...