当前位置: 首页 > news >正文

编程基础:表驱动


能帮到你的话,就给个赞吧 😘


文章目录

  • 查找:从元素集中查找到数据
    • 顺序查找:O(n):遍历查找到符合条件的元素地址
    • 定址查找:O(1):给定地址查找到元素
      • 关键:以条件作为地址
      • rate = rateTable[age][health]:给定age和health两个地址
  • 表驱动
    • 定义条件结构体:使用枚举量化条件
    • 定义条件检测方法
    • 定义动画表:以条件为索引

查找:从元素集中查找到数据

顺序查找:O(n):遍历查找到符合条件的元素地址

定址查找:O(1):给定地址查找到元素

关键:以条件作为地址

rate = rateTable[age][health]:给定age和health两个地址

表驱动

定义条件结构体:使用枚举量化条件

#pragma once#include "CoreMinimal.h"
#include "UObject/Struct.h"
#include "HorseTypes.generated.h"/** 下马方向枚举 - 定义角色下马时的左右方向选择 */
UENUM(BlueprintType)
enum class EDismountDirection : uint8
{Left,       // 左侧下马 - 角色从马匹左侧下马Right,      // 右侧下马 - 角色从马匹右侧下马Automatic   // 自动选择 - 系统根据障碍物等条件自动选择最佳方向
};/** 地面类型枚举 - 描述角色下马时所处的地形类型 */
UENUM(BlueprintType)
enum class EGroundType : uint8
{Flat,       // 平地 - 坡度较小的平坦地面Slope,      // 斜坡 - 有一定坡度的倾斜地面Stairs,     // 台阶 - 类似楼梯的阶梯状地形Uneven      // 不平坦地形 - 崎岖不平的复杂地形
};/** 角色移动状态枚举 - 表示马匹在下车时的运动状态 */
UENUM(BlueprintType)
enum class EMovementState : uint8
{Standing,   // 静止 - 马匹处于完全静止状态Walking,    // 步行 - 马匹以较慢速度行走Running,    // 奔跑 - 马匹以中等速度奔跑Galloping   // 飞驰 - 马匹以最高速度疾驰
};/** 下马情境枚举 - 描述下马时的场景上下文 */
UENUM(BlueprintType)
enum class EDismountContext : uint8
{Normal,     // 正常下马 - 非战斗状态下的常规下马Combat,     // 战斗状态 - 战斗中紧急下马NearObject, // 靠近物体 - 靠近墙壁、树木等物体时下马Mounted     // 从马背上 - 直接从骑行状态下马
};/** * 下马条件结构体* 整合所有影响下马动画选择的关键条件参数* 作为动画查询系统的核心数据结构,实现条件到动画的精准映射*/
USTRUCT(BlueprintType)
struct FHorseDismountConditions
{GENERATED_BODY() // 虚幻引擎反射系统宏,生成必要的元数据和代码/** 下马方向 - 决定角色从左侧、右侧还是自动选择方向下马 */UPROPERTY(BlueprintReadWrite, Category = "Conditions")EDismountDirection Direction;/** 地面类型 - 描述当前地形属于平地、斜坡、台阶还是不平坦地形 */UPROPERTY(BlueprintReadWrite, Category = "Conditions")EGroundType Ground;/** 移动状态 - 记录马匹在下马前的运动状态(静止、步行、奔跑等) */UPROPERTY(BlueprintReadWrite, Category = "Conditions")EMovementState Movement;/** 下马情境 - 标记下马时的场景上下文(正常、战斗、靠近物体等) */UPROPERTY(BlueprintReadWrite, Category = "Conditions")EDismountContext Context;/** 是否有障碍物 - 标记下马方向是否存在障碍物(如墙壁、树木) */UPROPERTY(BlueprintReadWrite, Category = "Conditions")bool bHasObstacle;/** 坡度角度 - 量化地面倾斜程度(单位:度),用于更精细的动画选择 */UPROPERTY(BlueprintReadWrite, Category = "Conditions")float SlopeAngle;/** * 构造函数 - 初始化所有条件参数为默认值* 确保结构体在创建时处于合理的初始状态*/FHorseDismountConditions(): Direction(EDismountDirection::Automatic)  // 默认自动选择下马方向, Ground(EGroundType::Flat)                 // 默认平地地形, Movement(EMovementState::Standing)        // 默认静止状态, Context(EDismountContext::Normal)         // 默认正常下马情境, bHasObstacle(false)                       // 默认无障碍物, SlopeAngle(0.0f)                          // 默认坡度为0度(水平){}
};/** * 下马动画映射结构体* 建立"下马条件组合"与"对应动画资源"之间的映射关系* 用于数据驱动的动画选择系统*/
USTRUCT(BlueprintType)
struct FAnimationMapping
{GENERATED_BODY()/** 触发该动画的条件组合 - 当检测到的条件与此匹配时使用该动画 */UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Animation")FHorseDismountConditions Conditions;/** 动画蒙太奇资源 - 包含具体的下马动画片段 */UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Animation")UAnimationMontage* AnimationMontage;/** 动画片段名称 - 指定蒙太奇中需要播放的具体片段 */UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Animation")FName AnimationSection;/** 动画过渡时间 - 从当前动画切换到该下马动画的平滑过渡时间(单位:秒) */UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Animation")float TransitionTime;
};

定义条件检测方法

FHorseDismountConditions UHorseComponent::DetectDismountConditions()
{FHorseDismountConditions Conditions;// 检测地面类型Conditions.Ground = DetectGroundType();// 检测移动状态Conditions.Movement = DetectMovementState();// 检测下马方向Conditions.Direction = DetermineDismountDirection();// 检测是否有障碍物FVector StartLocation = OwningCharacter->GetActorLocation();FVector EndLocation = StartLocation + OwningCharacter->GetActorForwardVector() * ObstacleCheckDistance;FHitResult HitResult;Conditions.bHasObstacle = UKismetSystemLibrary::LineTraceSingle(GetWorld(),StartLocation,EndLocation,ETraceTypeQuery::TraceTypeQuery1,false,TArray<AActor*>(),EDrawDebugTrace::None,HitResult,true);// 检测下马场景(简化版)Conditions.Context = Conditions.bHasObstacle ? EDismountContext::NearObject : EDismountContext::Normal;return Conditions;
}EGroundType UHorseComponent::DetectGroundType()
{if (!OwningCharacter) return EGroundType::Flat;FVector StartLocation = OwningCharacter->GetActorLocation();FVector EndLocation = StartLocation + FVector(0, 0, -GroundCheckDistance);FHitResult HitResult;bool bHit = UKismetSystemLibrary::LineTraceSingle(GetWorld(),StartLocation,EndLocation,ETraceTypeQuery::TraceTypeQuery1,false,TArray<AActor*>(),EDrawDebugTrace::None,HitResult,true);if (!bHit) return EGroundType::Flat;// 计算坡度float Angle = FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(HitResult.Normal, FVector::UpVector)));((FHorseDismountConditions*)nullptr)->SlopeAngle = Angle;if (Angle < 5.0f)return EGroundType::Flat;else if (Angle < 25.0f)return EGroundType::Slope;else if (Angle < 45.0f)return EGroundType::Stairs;elsereturn EGroundType::Uneven;
}EMovementState UHorseComponent::DetectMovementState()
{if (!OwningCharacter) return EMovementState::Standing;float Speed = OwningCharacter->GetVelocity().Size();if (Speed < 50.0f)return EMovementState::Standing;else if (Speed < 200.0f)return EMovementState::Walking;else if (Speed < 400.0f)return EMovementState::Running;elsereturn EMovementState::Galloping;
}EDismountDirection UHorseComponent::DetermineDismountDirection(const FHorseDismountConditions& Conditions)
{// 安全检查:确认角色(OwningCharacter)和马匹(HorseActor)的有效性,避免空指针错误if (!OwningCharacter || !HorseActor) return EDismountDirection::Left;// 检测点计算:计算左右两侧检测点(距离角色100单位的左右位置)FVector RightSide = OwningCharacter->GetActorLocation() + OwningCharacter->GetActorRightVector() * 100.0f;FVector LeftSide = OwningCharacter->GetActorLocation() - OwningCharacter->GetActorRightVector() * 100.0f;//障碍物检测:从左右检测点分别向下发射 150 单位的射线(FVector(0,0,-150)),通过射线是否命中物体判断两侧是否有障碍物(如墙壁、岩石、地形突起等)。FHitResult RightHit, LeftHit;	// 声明碰撞结果变量// 检测右侧是否有障碍物(向下发射150单位射线,检测地面或物体)bool bRightBlocked = UKismetSystemLibrary::LineTraceSingle(GetWorld(), RightSide, RightSide + FVector(0, 0, -150), ETraceTypeQuery::TraceTypeQuery1, false, TArray<AActor*>(), EDrawDebugTrace::None, RightHit, true);// 检测左侧是否有障碍物(同上逻辑)bool bLeftBlocked = UKismetSystemLibrary::LineTraceSingle(GetWorld(), LeftSide, LeftSide + FVector(0, 0, -150), ETraceTypeQuery::TraceTypeQuery1, false, TArray<AActor*>(), EDrawDebugTrace::None, LeftHit, true);// 方向决策:优先选择无障碍物的一侧if (bRightBlocked && !bLeftBlocked)return EDismountDirection::Left;  // 右侧有障碍,选左侧if (bLeftBlocked && !bRightBlocked)return EDismountDirection::Right; // 左侧有障碍,选右侧return EDismountDirection::Left;		// 两侧都无障碍(或都有障碍)时,默认选择左侧(符合多数游戏操作习惯)
}

定义动画表:以条件为索引

// 为FHorseDismountConditions实现哈希函数,使其可作为TMap的键
template<>
struct THash<FHorseDismountConditions>
{FORCEINLINE static uint32 GetHash(const FHorseDismountConditions& Key){uint32 Hash = 0;Hash = HashCombine(Hash, GetTypeHash(Key.DismountDir));Hash = HashCombine(Hash, GetTypeHash(Key.Ground));Hash = HashCombine(Hash, GetTypeHash(Key.Movement));Hash = HashCombine(Hash, GetTypeHash(FMath::RoundToInt(Key.SlopeAngle)));Hash = HashCombine(Hash, GetTypeHash(Key.bIsInCombat));return Hash;}
};// 实现相等运算符,用于TMap的键比较
FORCEINLINE bool operator==(const FHorseDismountConditions& A, const FHorseDismountConditions& B)
{return A.DismountDir == B.DismountDir &&A.Ground == B.Ground &&A.Movement == B.Movement &&A.bIsInCombat == B.bIsInCombat &&FMath::IsNearlyEqual(A.SlopeAngle, B.SlopeAngle, 1.0f);
}// 直接定义TMap类型别名,方便使用
using FHorseDismountAnimationMap = TMap<FHorseDismountConditions, UAnimationMontage*>;//动画表
FHorseDismountAnimationMap dismountAnimationTable;FHorseDismountConditions Conditions;UAnimationMontage*FoundMontage = dismountAnimationTable.Find(Conditions);
http://www.dtcms.com/a/395096.html

相关文章:

  • 内网穿透的应用-RemoteJVMDebug+cpolar:内网服务器调试的无界解决方案
  • 如何将PPT每一页批量导出为高清JPG图片?一文讲清操作流程
  • 高防服务器如何实现安全防护?ddos攻击会暴露ip吗?
  • linux硬盘分区管理
  • spring boot实现MCP服务器,及其cursor测试使用的方法
  • web前端开发与服务器通信的技术变迁历程
  • 市值机器人:智能力量与监管博弈下的金融新生态
  • LeetCode:46.二叉树展开为链表
  • LeetCode算法日记 - Day 50: 汉诺塔、两两交换链表中的节点
  • 力扣每日一刷Day24
  • LeetCode 226. 翻转二叉树
  • leetcode 2331 计算布尔二叉树的值
  • docker: Error response from daemon: Get “https://registry-1.docker.io/v2/“
  • 从50ms到30ms:YOLOv10部署中图像预处理的性能优化实践
  • 6. Typescript 类型体操
  • [C++:类的默认成员函数——Lesson7.const成员函数]
  • 园区3D可视化数字孪生管理平台与 IBMS 智能化集成系统:打造智慧园区新范式​
  • 【Javaweb】Restful开发规范
  • 【C++】深入理解const 成员函数
  • 使用vscode自带指令查找有问题的插件
  • JAVA算法练习题day18
  • springboot3 exception 全局异常处理入门与实战
  • spring简单入门和项目创建
  • lVS 负载均衡技术
  • 【论文阅读】OpenDriveVLA:基于大型视觉语言动作模型的端到端自动驾驶
  • Redis 缓存更新策略与热点数据识别
  • 新手小白——Oracle新建表完成题目
  • 如何让百度快速收录网页如何让百度快速收录网页的方法
  • Bugku-1和0的故事
  • 微硕WINSOK N+P MOSFET WSD3067DN56,优化汽车智能雨刷系统