六一的部落格


关关难过关关过,前路漫漫亦灿灿。




说明

  1. C++
  2. 落地速度Z方向的分量和坠落高度有关;速度越大,坠落高度越大
    t = sqrt(2*h/g) = v/g
  3. 跳跃时落地,也符合坠落定义;在一定范围内,坠落无伤害

坠落机制

  1. Character定义了坠落委托类型FLandedSignature,并有该类型成员ACharacter::LandedDelegate
  2. 委托类型的处理函数签名
    1void handler(const FHitResult& Hit);
    该委托类型支持蓝图
  3. Character在ACharacter::Landed通知客户端

思路

  • 我们可以注册LandedDelegate的委托服务,也可以覆写ACharacter::Landed,添加相应处理
  • 选择注册委托服务

坠落伤害计算

  1. 参数
    -
    坠落伤害范围 LandedDamageRange [c, d]
    落地速度范围 LandedDamageVelocityRange [a, b]
  2. 落地速度和对应的伤害
    速度 伤害
    < a 无伤
    [a, b] [c, d]
    c + (Velocity - a) (d - c) / (b - a)
    > b d
  3. 获取Character速度
    • APawn::GetVelocity
    • ACharacter:: GetCharacterMovement > UCharacterMovementComponent::Velocity

添加坠落伤害参数

protected

ShootThemUp: Player/STUBaseCharacter.h

1UPROPERTY(EditDefaultsOnly)
2FVector2D LandedDamageVelocityRange = {900.0f, 1200.0f};
3
4UPROPERTY(EditDefaultsOnly)	
5FVector2D LandedDamageRange = {10.0f, 100.0f};

注册坠落伤害的委托服务


搭建框架

  1. 添加空函数

    OnLanded函数名已被使用

    ShootThemUp: Player/STUBaseCharacter.cpp
    1void ASTUBaseCharacter::OnGroundLanded(const FHitResult &Hit) {} 
    
  2. 注册服务

    ShootThemUp: Player/STUBaseCharacter.cpp
    1// BeginPlay
    2LandedDelegate.AddDynamic(this, &ASTUBaseCharacter::OnGroundLanded);
  3. 函数声明

    private

    ShootThemUp: Player/STUBaseCharacter.h
    1UFUNCTION()
    2void OnGroundLanded(const FHitResult& Hit);

实现处理函数

坠落伤害属于环境伤害,无伤害源(Actor)和阵营(Controller)

ShootThemUp: Player/STUBaseCharacter.cpp

1void ASTUBaseCharacter::OnGroundLanded(const FHitResult &Hit)
2{
3    float Velocity = -GetVelocity().Z;
4    if (Velocity < LandedDamageVelocityRange.X)
5        return;
6    float LandedDamage = FMath::GetMappedRangeValueClamped(LandedDamageVelocityRange, LandedDamageRange, Velocity);
7    TakeDamage(LandedDamage, FDamageEvent{}, nullptr, nullptr);
8}

坠落伤害



说明

  1. C++
  2. 落地速度Z方向的分量和坠落高度有关;速度越大,坠落高度越大
    t = sqrt(2*h/g) = v/g
  3. 跳跃时落地,也符合坠落定义;在一定范围内,坠落无伤害

坠落机制

  1. Character定义了坠落委托类型FLandedSignature,并有该类型成员ACharacter::LandedDelegate
  2. 委托类型的处理函数签名
    1void handler(const FHitResult& Hit);
    该委托类型支持蓝图
  3. Character在ACharacter::Landed通知客户端

思路

  • 我们可以注册LandedDelegate的委托服务,也可以覆写ACharacter::Landed,添加相应处理
  • 选择注册委托服务

坠落伤害计算

  1. 参数
    -
    坠落伤害范围 LandedDamageRange [c, d]
    落地速度范围 LandedDamageVelocityRange [a, b]
  2. 落地速度和对应的伤害
    速度 伤害
    < a 无伤
    [a, b] [c, d]
    c + (Velocity - a) (d - c) / (b - a)
    > b d
  3. 获取Character速度
    • APawn::GetVelocity
    • ACharacter:: GetCharacterMovement > UCharacterMovementComponent::Velocity

添加坠落伤害参数

protected

ShootThemUp: Player/STUBaseCharacter.h

1UPROPERTY(EditDefaultsOnly)
2FVector2D LandedDamageVelocityRange = {900.0f, 1200.0f};
3
4UPROPERTY(EditDefaultsOnly)	
5FVector2D LandedDamageRange = {10.0f, 100.0f};

注册坠落伤害的委托服务


搭建框架

  1. 添加空函数

    OnLanded函数名已被使用

    ShootThemUp: Player/STUBaseCharacter.cpp
    1void ASTUBaseCharacter::OnGroundLanded(const FHitResult &Hit) {} 
    
  2. 注册服务

    ShootThemUp: Player/STUBaseCharacter.cpp
    1// BeginPlay
    2LandedDelegate.AddDynamic(this, &ASTUBaseCharacter::OnGroundLanded);
  3. 函数声明

    private

    ShootThemUp: Player/STUBaseCharacter.h
    1UFUNCTION()
    2void OnGroundLanded(const FHitResult& Hit);

实现处理函数

坠落伤害属于环境伤害,无伤害源(Actor)和阵营(Controller)

ShootThemUp: Player/STUBaseCharacter.cpp

1void ASTUBaseCharacter::OnGroundLanded(const FHitResult &Hit)
2{
3    float Velocity = -GetVelocity().Z;
4    if (Velocity < LandedDamageVelocityRange.X)
5        return;
6    float LandedDamage = FMath::GetMappedRangeValueClamped(LandedDamageVelocityRange, LandedDamageRange, Velocity);
7    TakeDamage(LandedDamage, FDamageEvent{}, nullptr, nullptr);
8}