重构MakeShot
2023年8月11日 2024年1月11日
说明
- 本节使用的重构被称作提取
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;