26,怪物受击接口改为C++

整条链路如下:

一、核心设计目标

实现玩家攻击 → 敌人受击的完整链路

接口与业务逻辑分离,蓝图 / C++ 双向兼容

变量全私有,仅通过Set/Get访问,数据安全可控

死亡判断前置过滤,性能与逻辑双保障

二、分层架构与实现细节

  1. 接口层(HitHandle_enemy.h)
    作用:定义统一受击协议,不包含任何业务逻辑
    cpp
    运行
    UINTERFACE(MinimalAPI)
    class UHitHandle_enemy : public UInterface
    { GENERATED_BODY() };

class ROUGHLIKE1_API IHitHandle_enemy

{

GENERATED_BODY()

public:

UFUNCTION(BlueprintNativeEvent, Category = "Hit")

void INT_HitHandleEnemy(AActor* DamageCauser, float Damage, float Force);

virtual void INT_HitHandleEnemy_Implementation(AActor* DamageCauser, float Damage, float Force) = 0;

};

采用BlueprintNativeEvent,支持蓝图重写与 C++ 实现

函数参数与你蓝图原接口完全对齐:伤害来源、伤害值、推力

  1. 敌人类实现层(Enemy.h/.cpp)

2.1 类继承与接口绑定

cpp

运行

// Enemy.h

UCLASS()

class ROUGHLIKE1_API AEnemy

: public APaperZDCharacter

, public IHitHandle_enemy

{

GENERATED_BODY()

public:

// 接口实现声明

virtual void INT_HitHandleEnemy_Implementation(AActor* DamageCauser, float Damage, float Force) override;

复制代码
// 通用受击入口(蓝图/C++均可调用)
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Combat | Attack")
void OnTakeHit(AActor* DamageCauser, float Damage, float Force);
virtual void OnTakeHit_Implementation(AActor* DamageCauser, float Damage, float Force);

// 全私有变量的Set/Get接口(HP、死亡状态、伤害数据等)
// ...(完整实现见之前的代码)

};

2.2 核心转发逻辑(接口与通用入口解耦)

cpp

运行

// Enemy.cpp

// 接口仅做转发,不写业务逻辑

void AEnemy::INT_HitHandleEnemy_Implementation(AActor* DamageCauser, float Damage, float Force)

{

OnTakeHit(DamageCauser, Damage, Force);

}

// 通用受击入口,蓝图重写优先级高于C++默认实现

void AEnemy::OnTakeHit_Implementation(AActor* DamageCauser, float Damage, float Force)

{

// C++默认空实现,逻辑由蓝图编写

}

接口层仅转发,保留原有接口兼容性

OnTakeHit作为统一入口,支持蓝图调试与后续迁移 C++

  1. 玩家侧调用层(MyPaperZDCharacter.cpp)

作用:攻击检测 + 伤害计算 + 接口调用,完全收进 C++

cpp

运行

void AMyPaperZDCharacter::INT_AttackDetection_Implementation(FVector boxPosition, FVector boxExtension)

{

// 1. 死亡前置过滤,直接阻断无效攻击

if (IsDead) return;

复制代码
// 2. 盒体检测命中敌人
// ...(检测逻辑)

// 3. 遍历敌人,统一分发伤害
for (AActor* target : outActors)
{
    if (!target || !target->ActorHasTag(FName("enemy"))) continue;

    // 4. C++内完成暴击伤害计算(替代蓝图逻辑)
    bool bIsCrit = UKismetMathLibrary::RandomBoolWithWeight(AttackCritChance);
    float finalDamage = AttackBaseDamage * (bIsCrit ? AttackCritMultiplier : 1.0f);
    int32 truncatedForce = static_cast<int32>(force);

    // 5. 标准接口调用(必须用Execute_前缀)
    if (target->Implements<UHitHandle_enemy>())
    {
        IHitHandle_enemy::Execute_INT_HitHandleEnemy(
            target, this, finalDamage, truncatedForce);
    }
}

}

  1. 蓝图层实现(敌人蓝图)
    作用:仅实现受击业务逻辑,不写任何分发逻辑
    删除蓝图中原有的Event INT Hithandle节点,避免覆盖 C++ 转发
    保留Event On Take Hit事件,编写受击逻辑:
    调用SetDamageCauser/SetReceivedDamage/SetReceivedForce
    扣血SetHP(GetHP() - Damage)
    HP 归零时调用SetDead(true)
相关推荐
远离UE42 天前
UE5 UV邻接 Niagara潜水模拟 学习笔记
ue5·uv
AA陈超3 天前
005 T03 — 角色基类与移动系统 详细功能设计文档
ue5
AA陈超3 天前
004 T02 - 俯视角摄像机系统 设计文档
网络·c++·ue5·虚幻引擎
AA陈超3 天前
006 T03 — 蓝图操作指南
c++·游戏·架构·ue5·github·虚幻引擎
Duo1J5 天前
【UE】Slate 编辑器工具开发01 - Slate语法 & 常用控件
ue5·编辑器·游戏引擎·ue4
朗迹 - 张伟6 天前
UE5.7 PCG从入门到精通系列课程【第五课:PCG沿一条样条线生成物体】
ue5·pcg
AA陈超6 天前
003 XiYou 西游 — P0 阶段实施计划
c++·笔记·学习·ue5
朗迹 - 张伟7 天前
UE5.7 PCG从入门到精通系列课程【第三课:程序化生成森林】
ue5·pcg
朗迹 - 张伟8 天前
UE5.7 PCG从入门到精通系列课程【第二课:使用PCG制作草地系统】
ue5·pcg