六一的部落格


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




说明

  • 本节使用的重构被称作提取 The Extract Method , 将函数切分, 使得代码可读性更高
  • 对武器类的MakeShot重构
  • 纯理论逻辑放在 protected , 供派生类调用

调整逻辑

 1void ASTUBaseWeapon::MakeShot()
 2{
 3    if(!GetWorld()) return;
 4
 5    // 获取PlayerController
 6    const auto Player = Cast<ACharacter>(GetOwner());
 7    if (!Player) return;
 8
 9    const auto Controller = Player->GetController<APlayerController>();
10    if (!Controller) return;
11
12    // 通过Controller获取CameraComponent的位置和方向
13    FVector ViewLocation;
14    FRotator ViewRotation;
15    Controller->GetPlayerViewPoint(ViewLocation, ViewRotation);
16
17    // 通过CameraComponent的位置和方向计算轨迹信息
18    const FVector TraceStart = ViewLocation;
19    const FVector ShootDirection = ViewRotation.Vector();
20    const FVector TraceEnd = TraceStart + ShootDirection * TraceMaxDistance;
21
22    // 提供轨迹获取碰撞信息
23    FHitResult HitResult;
24
25    FCollisionQueryParams CollisionParams;
26    CollisionParams.AddIgnoredActor(GetOwner());
27
28    GetWorld()->LineTraceSingleByChannel(HitResult, TraceStart, TraceEnd, ECollisionChannel::ECC_Visibility, CollisionParams);
29
30    // 获取枪口信息: 只用到了位置分量
31    const FTransform SocketTransform = WeaponMeshComponent->GetSocketTransform(MuzzleSocketName);
32
33    // 使用碰撞信息和枪口信息绘制轨迹和交点
34    if (HitResult.bBlockingHit)
35    {
36        DrawDebugLine(GetWorld(), SocketTransform.GetLocation(), HitResult.ImpactPoint, FColor::Red, false, 3.0f, 0, 3.0f);
37        DrawDebugSphere(GetWorld(), HitResult.ImpactPoint, 10.0f, 24, FColor::Red, false, 5.0f);
38        UE_LOG(LogBaseWeapon, Display, TEXT("Bone: %s"), *HitResult.BoneName.ToString());
39    }
40    else
41    {
42        DrawDebugLine(GetWorld(), SocketTransform.GetLocation(), TraceEnd, FColor::Red, false, 3.0f, 0, 3.0f);
43    }
44}

拆分

ShootThemUp: Weapon/STUBaseWeapon.cpp


GetPlayerController

1APlayerController *ASTUBaseWeapon::GetPlayerController() const
2{
3    const auto Player = Cast<ACharacter>(GetOwner());
4    if (!Player) return nullptr;
5
6    return Player->GetController<APlayerController>();
7}

GetPlayerViewPoint

1bool ASTUBaseWeapon::GetPlayerViewPoint(FVector &ViewLocation, FRotator &ViewRotation) const
2{
3    const auto Controller = GetPlayerController();
4    if (!Controller) return false;
5
6    Controller->GetPlayerViewPoint(ViewLocation, ViewRotation);
7    return true;
8}

GetTraceData

 1bool ASTUBaseWeapon::GetTraceData(FVector& TraceStart, FVector& TraceEnd) const
 2{
 3    FVector ViewLocation;
 4    FRotator ViewRotation;
 5    if (!GetPlayerViewPoint(ViewLocation, ViewRotation)) return false;
 6
 7    TraceStart = ViewLocation;
 8    const FVector ShootDirection = ViewRotation.Vector();
 9    TraceEnd = TraceStart + ShootDirection * TraceMaxDistance;
10    return true;
11}

MakeHit

1void ASTUBaseWeapon::MakeHit(FHitResult &HitResult, const FVector &TraceStart, const FVector &TraceEnd)
2{
3    if (!GetWorld()) return;
4
5    FCollisionQueryParams CollisionParams;
6    CollisionParams.AddIgnoredActor(GetOwner());
7
8    GetWorld()->LineTraceSingleByChannel(HitResult, TraceStart, TraceEnd, ECollisionChannel::ECC_Visibility, CollisionParams);
9}

GetMuzzleWorldLocation

1FVector ASTUBaseWeapon::GetMuzzleWorldLocation() const
2{
3    return WeaponMeshComponent->GetSocketLocation(MuzzleSocketName);
4}

MakeShot

 1void ASTUBaseWeapon::MakeShot()
 2{
 3    if (!GetWorld()) return;
 4
 5    FVector TraceStart, TraceEnd;
 6    if (!GetTraceData(TraceStart, TraceEnd)) return;         
 7
 8    FHitResult HitResult;
 9    MakeHit(HitResult, TraceStart, TraceEnd);
10
11    if (HitResult.bBlockingHit)
12    {
13        DrawDebugLine(GetWorld(), GetMuzzleWorldLocation(), HitResult.ImpactPoint, FColor::Red, false, 3.0f, 0, 3.0f);
14        DrawDebugSphere(GetWorld(), HitResult.ImpactPoint, 10.0f, 24, FColor::Red, false, 5.0f);
15        // UE_LOG(LogBaseWeapon, Display, TEXT("Bone: %s"), *HitResult.BoneName.ToString());
16    }
17    else
18    {
19        DrawDebugLine(GetWorld(), GetMuzzleWorldLocation(), TraceEnd, FColor::Red, false, 3.0f, 0, 3.0f);
20    }
21}

添加声明

protected

ShootThemUp: Weapon/STUBaseWeapon.h

1APlayerController *GetPlayerController() const;
2bool GetPlayerViewPoint(FVector &ViewLocation, FRotator &ViewRotation) const;
3bool GetTraceData(FVector& TraceStart, FVector& TraceEnd) const;
4void MakeHit(FHitResult &HitResult, const FVector &TraceStart, const FVector &TraceEnd);
5FVector GetMuzzleWorldLocation() const;

重构MakeShot



说明

  • 本节使用的重构被称作提取 The Extract Method , 将函数切分, 使得代码可读性更高
  • 对武器类的MakeShot重构
  • 纯理论逻辑放在 protected , 供派生类调用

调整逻辑

 1void ASTUBaseWeapon::MakeShot()
 2{
 3    if(!GetWorld()) return;
 4
 5    // 获取PlayerController
 6    const auto Player = Cast<ACharacter>(GetOwner());
 7    if (!Player) return;
 8
 9    const auto Controller = Player->GetController<APlayerController>();
10    if (!Controller) return;
11
12    // 通过Controller获取CameraComponent的位置和方向
13    FVector ViewLocation;
14    FRotator ViewRotation;
15    Controller->GetPlayerViewPoint(ViewLocation, ViewRotation);
16
17    // 通过CameraComponent的位置和方向计算轨迹信息
18    const FVector TraceStart = ViewLocation;
19    const FVector ShootDirection = ViewRotation.Vector();
20    const FVector TraceEnd = TraceStart + ShootDirection * TraceMaxDistance;
21
22    // 提供轨迹获取碰撞信息
23    FHitResult HitResult;
24
25    FCollisionQueryParams CollisionParams;
26    CollisionParams.AddIgnoredActor(GetOwner());
27
28    GetWorld()->LineTraceSingleByChannel(HitResult, TraceStart, TraceEnd, ECollisionChannel::ECC_Visibility, CollisionParams);
29
30    // 获取枪口信息: 只用到了位置分量
31    const FTransform SocketTransform = WeaponMeshComponent->GetSocketTransform(MuzzleSocketName);
32
33    // 使用碰撞信息和枪口信息绘制轨迹和交点
34    if (HitResult.bBlockingHit)
35    {
36        DrawDebugLine(GetWorld(), SocketTransform.GetLocation(), HitResult.ImpactPoint, FColor::Red, false, 3.0f, 0, 3.0f);
37        DrawDebugSphere(GetWorld(), HitResult.ImpactPoint, 10.0f, 24, FColor::Red, false, 5.0f);
38        UE_LOG(LogBaseWeapon, Display, TEXT("Bone: %s"), *HitResult.BoneName.ToString());
39    }
40    else
41    {
42        DrawDebugLine(GetWorld(), SocketTransform.GetLocation(), TraceEnd, FColor::Red, false, 3.0f, 0, 3.0f);
43    }
44}

拆分

ShootThemUp: Weapon/STUBaseWeapon.cpp


GetPlayerController

1APlayerController *ASTUBaseWeapon::GetPlayerController() const
2{
3    const auto Player = Cast<ACharacter>(GetOwner());
4    if (!Player) return nullptr;
5
6    return Player->GetController<APlayerController>();
7}

GetPlayerViewPoint

1bool ASTUBaseWeapon::GetPlayerViewPoint(FVector &ViewLocation, FRotator &ViewRotation) const
2{
3    const auto Controller = GetPlayerController();
4    if (!Controller) return false;
5
6    Controller->GetPlayerViewPoint(ViewLocation, ViewRotation);
7    return true;
8}

GetTraceData

 1bool ASTUBaseWeapon::GetTraceData(FVector& TraceStart, FVector& TraceEnd) const
 2{
 3    FVector ViewLocation;
 4    FRotator ViewRotation;
 5    if (!GetPlayerViewPoint(ViewLocation, ViewRotation)) return false;
 6
 7    TraceStart = ViewLocation;
 8    const FVector ShootDirection = ViewRotation.Vector();
 9    TraceEnd = TraceStart + ShootDirection * TraceMaxDistance;
10    return true;
11}

MakeHit

1void ASTUBaseWeapon::MakeHit(FHitResult &HitResult, const FVector &TraceStart, const FVector &TraceEnd)
2{
3    if (!GetWorld()) return;
4
5    FCollisionQueryParams CollisionParams;
6    CollisionParams.AddIgnoredActor(GetOwner());
7
8    GetWorld()->LineTraceSingleByChannel(HitResult, TraceStart, TraceEnd, ECollisionChannel::ECC_Visibility, CollisionParams);
9}

GetMuzzleWorldLocation

1FVector ASTUBaseWeapon::GetMuzzleWorldLocation() const
2{
3    return WeaponMeshComponent->GetSocketLocation(MuzzleSocketName);
4}

MakeShot

 1void ASTUBaseWeapon::MakeShot()
 2{
 3    if (!GetWorld()) return;
 4
 5    FVector TraceStart, TraceEnd;
 6    if (!GetTraceData(TraceStart, TraceEnd)) return;         
 7
 8    FHitResult HitResult;
 9    MakeHit(HitResult, TraceStart, TraceEnd);
10
11    if (HitResult.bBlockingHit)
12    {
13        DrawDebugLine(GetWorld(), GetMuzzleWorldLocation(), HitResult.ImpactPoint, FColor::Red, false, 3.0f, 0, 3.0f);
14        DrawDebugSphere(GetWorld(), HitResult.ImpactPoint, 10.0f, 24, FColor::Red, false, 5.0f);
15        // UE_LOG(LogBaseWeapon, Display, TEXT("Bone: %s"), *HitResult.BoneName.ToString());
16    }
17    else
18    {
19        DrawDebugLine(GetWorld(), GetMuzzleWorldLocation(), TraceEnd, FColor::Red, false, 3.0f, 0, 3.0f);
20    }
21}

添加声明

protected

ShootThemUp: Weapon/STUBaseWeapon.h

1APlayerController *GetPlayerController() const;
2bool GetPlayerViewPoint(FVector &ViewLocation, FRotator &ViewRotation) const;
3bool GetTraceData(FVector& TraceStart, FVector& TraceEnd) const;
4void MakeHit(FHitResult &HitResult, const FVector &TraceStart, const FVector &TraceEnd);
5FVector GetMuzzleWorldLocation() const;