ActionRoguelike源码中相对于个人的新用法探索

从知乎迁移到CSDN 原文地址:炉间书客
源码地址:ActionRoguelike Source Git hub
课程地址:Professional Game Development in C++ and Unreal Engine

  • C++源码中SpawnActor中的生成参数配置:SpawnActor中的FActorSpawnParameter附带了生成时的一些额外控制参数,用于精细的控制生成的Actor:
  1. Name:生成的Actor的名字,没有传递参数的情况下,会自动的命名成[Class]_[Number]
  2. Template:使用现有的Actor作为模板来生成新的Actor,生成的Actor会使用这个Actor实例的属性值来赋值给自身,这对复制世界场景下的现有Actor来说十分有用(相当于影分身)
  3. Owner:生成该Actor的拥有者,可为空
  4. Instigator:伤害控制来源(通常指该Actor的Controller亦或是生成该Actor的Owner),可为空
  5. OverrideLevel: 当前所在Level,可为空,当为空时,该参数有自己的一套寻找规则
  6. SpawnCollisionHandlingOverride: 有碰撞穿透的情况下,可用的生成策略,分别为:默认规则;总是生成;调整生成位置并总是生成;调整生成位置但是如果有碰撞的情况下并不生成;如果有碰撞不生成
  7. ESpawnActorNameMode: 生成Actor时,命名处理规则(尤指命名冲突):致命中断,错误并返回为空,不可用时返回为空
  • ensure宏与IsValid():
  1. ensure系列宏函数:
  • ensure系列宏函数是对UE_ENSURE_IMPL宏的再次封装,分别用于不同精细程度的消息打印控制
  • UE_ENSURE_IMPL可以用来检测非致命的运行时错误,当出现错误时会打印一条崩溃记录并向闪退服务器发送一条记录(这条记录中包含崩溃的堆栈信息),而不会闪退
  • UE_ENSURE_IMPL第一个参数是lambda函数的传参控制,always用于控制你是否自己处理可能出现的每一个错误,…为打印出错日志时的附加信息
  • ensure可以被嵌入在判定语句中,尤其在那些你需要获取提供崩溃记录的地方非常有用(从这个角度讲,ensure在运行时获取实时记录非常有用)。
  • UE_ENSURE_IMPL具有跨平台性质,在不同的运行平台上都能很好的工作,这对平台调试来说非常友好
  • ensure针对UE_ENSURE_IMPL有四个封装宏,分别为:ensure,ensureMsgf, ensureAlways, ensureAlwaysMsgf,它们的区别主要在于对错误的处理及打印错误消息时的内容参数控制
  • UE_ENSURE_IMPL 传入的是表达式
  1. IsValid()函数:
  • IsValid是依赖于Object继承体系的(它是Object中的函数),换言之,非继承自Object的对象无法使用IsValid
  • IsValid只对指针是否为空以及是否在GC的回收中进行了判定,也就是说IsValid不能处理除这两种情况外的状态判定
  • IsValid传入的是对象的常量指针
  • 关于SAction模块的思考
  1. SAction继承自UObject,而SAction具有属性同步,这需要在持有SAction的SActionComponent中实现ReplicateSubobjects方法,来完成ActorChannel的同步链
  2. UObject中没有ReplicateSubojects方法,同理,在遇到Object的同步的时候,需要手动添加到ReplicateSubobjects中
  3. 比较典型的应用:UAbilitySystemComponent中的UGameplayAbility同步,UGameTasksComponent中的UGameplayTask同步
  4. SAction中四个核心函数:CanStart, StartAction, StopAction, IsRunning, 这四个函数都是蓝图可实现;同步数据为Action开始时间,Action的持有者USActionComponent指针,Action运行状态(是否在运行中,Instigator)
  5. USActionComponent中的核心方法: AddAction, RemoveAction, GetAction, ServerStartAction, ServerStopAction, StartActionByName及 StopActionByName, 管理SAction的生成,运行,停止,及回收
  6. SAction与SActionComponent类似于工厂模式,SAction负责具体的Action逻辑,而SActionComponent负责产生,管理SAction
  7. USAction_ProjectileAttack继承自SAction,是SAction一种具体的子弹攻击应用方案,具体伤害逻辑在AttackDelay_Elapsed中,该函数调用存在于服务器端的计时器中
  8. USActionEffect 继承自SAction, 是一种Buff效果的实现方式(持续一段时间,持久性Buff等),值得一提的是在AGameStateBase中存有获取服务器端世界时间的方法GetServerWorldTimeSeconds(), 关于世界时间的计算的统一性来说,最好统一按照服务器端时间计算
  9. 该模块给个人的感觉是GAS的精简版,用来完成属性,Buff等的逻辑更新与显示
  • SAICharacter中的AI锁敌策略
  1. SAICharacter中采用的是多播的方式,从USAttributeComponent的属性管理模块及PawnSensingComponent感知模块中注册了FSeePawnDelegate, FOnAttributeChanged。PawnSensingComponent中另一个比较常用的多播是FHearNoiseDelegate OnHearNoise, 该多播委托用于当听到噪声后作出一些操作
  2. SGameMode中的怪物生成策略
  • 在GameMode中有一个环境查询成员属性SpawnBotQuery(UEnvQuery), 该成员属性在蓝图中的查询策略为:距离所有玩家的距离以及路径可达性
  • 游戏开始时,通过UEnvQueryManager::RunEQSQuery查询函数获取
  • UEnvQueryInstanceBlueprintWrapper实例,然后绑定多播委托GetOnQueryFinishedEvent()获取生成坐标(QueryInstance->GetResultsAsLocation())
  • 根据坐标点及生成怪物配置,随机位置点来生成怪物(在实际项目开发中,生成怪物有严格的规则,并不一定是自动化随机生成,比如说生成怪物体积等,都是有策略的配置生成方式)
  • 序列化与反序列化策略:
  1. SaveGame中保留了两种数据存储:1.玩家数据(分数,生成位置,旋转等);2.世界场景中的Actor存储,核心数据为TArray<uint8>类型的数据存储
  2. SaveGameSubsystem中实现了写入及加载数据的核心方法,这两个方法针对SaveGame中的核心保存数据进行了序列与反序列化
  3. 玩家数据的反序列化,主要针对的是PlayerState的数据反序列读取,PlayerState中实现了SavePlayerStateLoadPlayerState方法,这两个方法和SaveGame子系统中的方法是类似的,只不过当前这两个方法针对的是当前的玩家数据,多见于玩家的上下线数据存储
  4. SaveGameSettings中保留了序列化配置的SaveSlotName,通过该属性来读取反序列化数据.
  • 世界场景中可交互物体的框架策略:
  1. 可交互物体都实现了接口ISGameplayInterface,该接口主要声明了3个核心方法:
  • OnActorLoaded : 该Actor被重新加载后调用
  • GetInteractText : 获取交互描述文字
  • Interact: 交互逻辑实现
    这3个方法完成了所有可交互物体的响应方式
    SInteractionComponent组件实现了交互Actor的查找及交互接口方法调用,核心方法为FindBestInteractableServerInteract, 前者完成了交互Actor的最优查找,后者实现了具体的交互物体的Interact方法调用

猜你喜欢

转载自blog.csdn.net/u011047958/article/details/125265422
今日推荐