총 게임에서 버튼을 가만히 눌렀을 때, 연사 총기(기관총)와 점사 총기(샷건)는 발사 로직이 다르다.
플래그 변수와 Timer를 설정하는 것으로도 충분히 구현 가능하나, 로직이 복잡해지면 가독성이 떨어질 수 있다.
그래서 Enhanced input system을 활용해 플래그 변수와 Timer를 전혀 사용하지 않고 로직을 깔끔하게 만드는 방법을 연구했다.
UPROPERTY(EditAnywhere, Category = "Stat|Firing Mode") float FireRate = 0.15f; UPROPERTY(EditAnywhere, Category = "Stat|Firing Mode") bool bAutomatic = false; // For burst firing. If this value is 2 or more, weapon can burst fire. Set bAutomatic true first. UPROPERTY(EditAnywhere, Category = "Stat|Firing Mode") int32 BurstShot = 0; void SetupWeaponInput(); void SetFiringMode(); void FirePressed(const FInputActionValue& Value); void AimPressed(const FInputActionValue& Value); void AimReleased(const FInputActionValue& Value); void ReloadPressed(const FInputActionValue& Value); UPROPERTY(EditAnywhere, Category = "Input") class UInputMappingContext* WeaponMappingContext; UPROPERTY(EditAnywhere, Category = "Input") class UInputAction* FireAction; UPROPERTY(EditAnywhere, Category = "Input") UInputAction* AimAction; UPROPERTY(EditAnywhere, Category = "Input") UInputAction* ReloadAction;
void AWeapon::SetupWeaponInput() { APlayerController* PlayerController = Cast<APlayerController>(OwnerCharacter->GetController()); if (PlayerController) { if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer())) { Subsystem->AddMappingContext(WeaponMappingContext, 1); if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerController->InputComponent)) { EnhancedInputComponent->BindAction(FireAction, ETriggerEvent::Triggered, this, &AWeapon::FirePressed); EnhancedInputComponent->BindAction(AimAction, ETriggerEvent::Started, this, &AWeapon::AimPressed); EnhancedInputComponent->BindAction(AimAction, ETriggerEvent::Completed, this, &AWeapon::AimReleased); EnhancedInputComponent->BindAction(ReloadAction, ETriggerEvent::Started, this, &AWeapon::ReloadPressed); SetFiringMode(); } Subsystem->RequestRebuildControlMappings(FModifyContextOptions(), EInputMappingRebuildType::RebuildWithFlush); } } } void AWeapon::SetFiringMode() { if (FireAction && FireAction->Triggers.Num()) { UInputTriggerPulse* Pulse = Cast<UInputTriggerPulse>(FireAction->Triggers[0]); if (Pulse) { if (bAutomatic == false) // Non-automatic fire { Pulse->Interval = 999.f; Pulse->TriggerLimit = 1; } else if (BurstShot < 2) // Full-automatic fire { Pulse->Interval = FireRate; Pulse->TriggerLimit = 0; } else // Burst-automatic fire { Pulse->Interval = FireRate; Pulse->TriggerLimit = BurstShot; } } else { UE_LOG(LogTemp, Log, TEXT("FireAction's trigger pulse is null.")); } } }
도움이 됐습니다.