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)
相关推荐
归真仙人2 天前
【UE项目迁移银河麒麟(Linux)局域网会话搜索失败排查】
ue5·ue4·vr·unreal engine·银河麒麟
fanfan_hongyun4 天前
UE5.1 应用InWebSocketClient-main 接收websocket信息
ue5
远离UE45 天前
Chaos、WFC 与 FJA 原理与区别笔记
ue5
平行云5 天前
3D应用推流太贵太慢?ImmerShare Lite:利用本地算力实现极简一键分享
unity·ue5·实时云渲染·云桌面·像素流·云游戏·串流
fanfan_hongyun6 天前
UE5.1 VaRest插件 读取json http请求
ue5
SpiderCodeJ6 天前
【UE5】- UE MCP :在UE5.8编辑器中内置链接Codex
ue5·codex·智能体·mcp
weixin_4046793110 天前
ue5 widget 之间的蓝图通讯
ue5
zr想努力10 天前
GAS学习(UE5自用)
学习·ue5
平行云10 天前
国产GPU云渲染适配实战:驱动兼容、编码调优与多路并发
unity·ue5·webrtc·webgl·实时云渲染·云桌面·像素流送
fanfan_hongyun10 天前
UE5.1 学习记录-玩家控制器
学习·ue5