Advertisement
Guest User

UAbilityComponent

a guest
Jul 12th, 2023
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.96 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include "CoreMinimal.h"
  4. #include "Components/ActorComponent.h"
  5. #include "Engine/DataTable.h"
  6. #include "AbilityComponent.generated.h"
  7.  
  8. class UInputAction;
  9.  
  10. class UDecalComponent;
  11. class USoundWave;
  12.  
  13. class UTurnQueue;
  14.  
  15. UENUM(BlueprintType)
  16. enum class EAbilityIndicatorType : uint8 {
  17. Melee = 0 UMETA(DisplayName = "Melee"),
  18. Range = 1 UMETA(DisplayName = "Range"),
  19. // Không biết tên, CC, AOE, Burst?
  20. };
  21.  
  22. UCLASS(Abstract, Blueprintable)
  23. class UAbilityComponent : public UActorComponent
  24. {
  25. GENERATED_BODY()
  26.  
  27. public:
  28. UAbilityComponent();
  29.  
  30. UFUNCTION(BlueprintCallable)
  31. void SetIndicatorDecalComponent(UDecalComponent* NewIndicatorDecalComponent);
  32.  
  33. UFUNCTION(BlueprintCallable, Category = "Ability")
  34. void SetTimerOnDecision();
  35.  
  36. // https://forums.unrealengine.com/t/how-to-override-c-function-in-blueprint/327399/4?u=xeryvelgarde
  37. // Keep this in mind, change them back to virtual functions late
  38. UFUNCTION(BlueprintCallable, Category = "Ability")
  39. void OnDecision();
  40.  
  41. UFUNCTION(BlueprintCallable)
  42. void SetAbilityIcon(UTexture2D* NewAbilityIcon);
  43.  
  44. UFUNCTION(BlueprintCallable)
  45. void SetAbilityPhase(EPhase NewAbilityPhase);
  46.  
  47. UFUNCTION(BlueprintCallable)
  48. void SendSignalToTriggerOnPhase();
  49.  
  50. UFUNCTION(BlueprintCallable)
  51. void SetAbilitySoundHovered(USoundWave* NewAbilitySoundHovered);
  52.  
  53. UFUNCTION(BlueprintCallable)
  54. void SetAbilitySoundPressed(USoundWave* NewAbilitySoundPressed);
  55.  
  56. UFUNCTION(BlueprintCallable)
  57. void SetAbilityRange(float NewAbilityRange);
  58.  
  59. UFUNCTION(BlueprintCallable)
  60. void SetSetDestinationInputAction(UInputAction* NewSetDestinationInputAction);
  61.  
  62. protected:
  63. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Ability Indicator Type")
  64. TEnumAsByte<EAbilityIndicatorType> AbilityIndicatorType;
  65.  
  66. UPROPERTY(BlueprintReadOnly, Category = "Ability")
  67. UTurnQueue* TurnQueue;
  68.  
  69. UFUNCTION(BlueprintCallable)
  70. void SetTargetPosition(FVector NewTargetPosition);
  71.  
  72. // https://forums.unrealengine.com/t/how-to-override-c-function-in-blueprint/327399/4?u=xeryvelgarde
  73. // Keep this in mind, change them back to virtual functions late
  74. UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Ability")
  75. void PreDecision(UDecalComponent* NewIndicatorDecalComponent, const float& MaxIndicatorDistance, UInputAction* NewSetDestinationInputAction);
  76. virtual void PreDecision_Implementation(UDecalComponent* NewIndicatorDecalComponent, const float& MaxIndicatorDistance, UInputAction* NewSetDestinationInputAction);
  77.  
  78. UFUNCTION(BlueprintImplementableEvent, Category = "Ability")
  79. void Resolution();
  80.  
  81. /*
  82. virtual void Decision();
  83.  
  84. virtual void Resolution();
  85. */
  86.  
  87. UFUNCTION(BlueprintCallable, Category = "Ability")
  88. void SetIndicatorDecalAtLocation();
  89.  
  90. private:
  91. virtual void BeginPlay() override;
  92.  
  93. FTimerHandle DecisionTimerHandle;
  94. FTimerDelegate DecisionTimerDelegate;
  95.  
  96. UPROPERTY(BlueprintGetter = GetIndicatorDecalComponent, BlueprintSetter = SetIndicatorDecalComponent)
  97. UDecalComponent* IndicatorDecalComponent;
  98.  
  99. UFUNCTION(BlueprintPure)
  100. UDecalComponent* GetIndicatorDecalComponent() const;
  101.  
  102. void PostDecision();
  103.  
  104. UPROPERTY(BlueprintGetter = GetAbilityIcon, BlueprintSetter = SetAbilityIcon)
  105. UTexture2D* AbilityIcon;
  106.  
  107. UFUNCTION(BlueprintPure)
  108. UTexture2D* GetAbilityIcon() const;
  109.  
  110. UPROPERTY(BlueprintGetter = GetAbilityPhase, BlueprintSetter = SetAbilityPhase)
  111. EPhase AbilityPhase;
  112.  
  113. UFUNCTION(BlueprintPure)
  114. EPhase GetAbilityPhase() const;
  115.  
  116. UPROPERTY(BlueprintGetter = GetAbilitySoundHovered, BlueprintSetter = SetAbilitySoundHovered)
  117. USoundWave* AbilitySoundHovered;
  118.  
  119. UFUNCTION(BlueprintPure)
  120. USoundWave* GetAbilitySoundHovered() const;
  121.  
  122. UPROPERTY(BlueprintGetter = GetAbilitySoundPressed, BlueprintSetter = SetAbilitySoundPressed)
  123. USoundWave* AbilitySoundPressed;
  124.  
  125. UFUNCTION(BlueprintPure)
  126. USoundWave* GetAbilitySoundPressed() const;
  127.  
  128. UPROPERTY(BlueprintGetter = GetAbilityRange, BlueprintSetter = SetAbilityRange)
  129. float AbilityRange;
  130.  
  131. UFUNCTION(BlueprintPure)
  132. float GetAbilityRange() const;
  133.  
  134. class UEnhancedInputLocalPlayerSubsystem* EnhancedInputLocalPlayerSubsystem;
  135. class UEnhancedPlayerInput* EnhancedPlayerInput;
  136.  
  137. UPROPERTY(BlueprintGetter = GetSetDestinationInputAction, BlueprintSetter = SetSetDestinationInputAction)
  138. UInputAction* SetDestinationInputAction;
  139.  
  140. UFUNCTION(BlueprintPure)
  141. UInputAction* GetSetDestinationInputAction() const;
  142.  
  143. UPROPERTY(BlueprintGetter = GetTargetPosition, BlueprintSetter = SetTargetPosition)
  144. FVector TargetPosition;
  145.  
  146. UFUNCTION(BlueprintPure)
  147. FVector GetTargetPosition() const;
  148.  
  149. UFUNCTION(BlueprintPure)
  150. FVector GetPlayerCursorLocation() const;
  151. };
  152.  
  153. #include "Battle/AbilityComponent.h"
  154. #include "Battle/TurnQueue.h"
  155. #include "Components/DecalComponent.h"
  156. #include "EnhancedInputSubsystems.h"
  157. #include "Kismet/GameplayStatics.h"
  158. #include "Kismet/KismetMathLibrary.h"
  159.  
  160. // Sets default values for this component's properties
  161. UAbilityComponent::UAbilityComponent()
  162. {
  163. // Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
  164. // off to improve performance if you don't need them.
  165. PrimaryComponentTick.bCanEverTick = false;
  166.  
  167. // ...
  168.  
  169. IndicatorDecalComponent = CreateDefaultSubobject<UDecalComponent>(FName(TEXT("IndicatorDecalComponent")));
  170.  
  171. TurnQueue = CreateDefaultSubobject<UTurnQueue>(FName(TEXT("TurnQueue")));
  172. }
  173.  
  174. void UAbilityComponent::BeginPlay()
  175. {
  176. Super::BeginPlay();
  177. }
  178.  
  179. UTexture2D* UAbilityComponent::GetAbilityIcon() const
  180. {
  181. return AbilityIcon;
  182. }
  183.  
  184. void UAbilityComponent::SetAbilityIcon(UTexture2D* NewAbilityIcon)
  185. {
  186. AbilityIcon = NewAbilityIcon;
  187. }
  188.  
  189. EPhase UAbilityComponent::GetAbilityPhase() const
  190. {
  191. return AbilityPhase;
  192. }
  193.  
  194. void UAbilityComponent::SetAbilityPhase(EPhase NewAbilityPhase)
  195. {
  196. AbilityPhase = NewAbilityPhase;
  197. }
  198.  
  199. USoundWave* UAbilityComponent::GetAbilitySoundHovered() const
  200. {
  201. return AbilitySoundHovered;
  202. }
  203.  
  204. void UAbilityComponent::SetAbilitySoundHovered(USoundWave* NewAbilitySoundHovered)
  205. {
  206. AbilitySoundHovered = NewAbilitySoundHovered;
  207. }
  208.  
  209. USoundWave* UAbilityComponent::GetAbilitySoundPressed() const
  210. {
  211. return AbilitySoundPressed;
  212. }
  213.  
  214. void UAbilityComponent::SetAbilitySoundPressed(USoundWave* NewAbilitySoundPressed)
  215. {
  216. AbilitySoundPressed = NewAbilitySoundPressed;
  217. }
  218.  
  219. float UAbilityComponent::GetAbilityRange() const
  220. {
  221. return AbilityRange;
  222. }
  223.  
  224. void UAbilityComponent::SetAbilityRange(float NewAbilityRange)
  225. {
  226. AbilityRange = NewAbilityRange;
  227. }
  228.  
  229. UInputAction* UAbilityComponent::GetSetDestinationInputAction() const
  230. {
  231. return SetDestinationInputAction;
  232. }
  233.  
  234. void UAbilityComponent::SetSetDestinationInputAction(UInputAction* NewSetDestinationInputAction)
  235. {
  236. SetDestinationInputAction = NewSetDestinationInputAction;
  237. }
  238.  
  239. UDecalComponent* UAbilityComponent::GetIndicatorDecalComponent() const
  240. {
  241. return IndicatorDecalComponent;
  242. }
  243.  
  244. void UAbilityComponent::SetIndicatorDecalComponent(UDecalComponent* NewIndicatorDecalComponent)
  245. {
  246. IndicatorDecalComponent = NewIndicatorDecalComponent;
  247. }
  248.  
  249. void UAbilityComponent::PreDecision_Implementation(UDecalComponent* NewIndicatorDecalComponent, const float& MaxIndicatorDistance, UInputAction* NewSetDestinationInputAction)
  250. {
  251. SetIndicatorDecalComponent(NewIndicatorDecalComponent);
  252. SetAbilityRange(MaxIndicatorDistance);
  253. SetSetDestinationInputAction(NewSetDestinationInputAction);
  254.  
  255. if (EnhancedInputLocalPlayerSubsystem == nullptr)
  256. {
  257. EnhancedInputLocalPlayerSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetWorld()->GetFirstPlayerController()->GetLocalPlayer());
  258. EnhancedPlayerInput = EnhancedInputLocalPlayerSubsystem->GetPlayerInput();
  259. }
  260. }
  261.  
  262. void UAbilityComponent::SetTimerOnDecision()
  263. {
  264. if (GetWorld())
  265. GetWorld()->GetTimerManager().SetTimer(DecisionTimerHandle, this, &UAbilityComponent::OnDecision, 0.35f, true, 0);
  266. }
  267.  
  268. void UAbilityComponent::OnDecision()
  269. {
  270. if (EnhancedPlayerInput == nullptr|| SetDestinationInputAction == nullptr) {
  271. if (GetWorld())
  272. GetWorld()->GetTimerManager().ClearTimer(DecisionTimerHandle);
  273.  
  274. return;
  275. }
  276.  
  277. if (EnhancedPlayerInput->GetActionValue(SetDestinationInputAction).Get<bool>())
  278. {
  279. if (GetWorld())
  280. GetWorld()->GetTimerManager().ClearTimer(DecisionTimerHandle);
  281.  
  282. SetTargetPosition(GetPlayerCursorLocation());
  283. }
  284. else
  285. {
  286. SetIndicatorDecalAtLocation();
  287. }
  288. }
  289.  
  290. FVector UAbilityComponent::GetPlayerCursorLocation() const
  291. {
  292. FHitResult HitResult;
  293. GetWorld()->GetFirstPlayerController()->GetHitResultUnderCursor(ECollisionChannel::ECC_Visibility, true, HitResult);
  294. return HitResult.Location;
  295. }
  296.  
  297. void UAbilityComponent::SetIndicatorDecalAtLocation()
  298. {
  299. if (GetOwner() == nullptr || IndicatorDecalComponent == nullptr)
  300. return;
  301.  
  302. FVector PlayerCursorLocation = GetPlayerCursorLocation();
  303. // Cự ly của indicator nên tương đối, 0 là địa điểm của nhân vật
  304. FVector PlayerCharacterLocation = GetOwner()->GetActorLocation();
  305.  
  306. if (FVector::Dist(PlayerCursorLocation, PlayerCharacterLocation) > GetAbilityRange())
  307. {
  308. FHitResult Hit;
  309. FVector End = PlayerCharacterLocation + UKismetMathLibrary::FindLookAtRotation(PlayerCharacterLocation, PlayerCursorLocation).Vector() * GetAbilityRange();
  310. const FCollisionQueryParams CollisionQueryParams;
  311. const FCollisionResponseParams CollisionResponseParams;
  312.  
  313. GetWorld()->LineTraceSingleByChannel(Hit, PlayerCharacterLocation, End, ECollisionChannel::ECC_Visibility, CollisionQueryParams, CollisionResponseParams);
  314.  
  315. PlayerCursorLocation = Hit.Location;
  316. }
  317.  
  318. GetIndicatorDecalComponent()->SetWorldLocation(PlayerCursorLocation);
  319. }
  320.  
  321. FVector UAbilityComponent::GetTargetPosition() const
  322. {
  323. return TargetPosition;
  324. }
  325.  
  326. void UAbilityComponent::SetTargetPosition(FVector NewTargetPosition)
  327. {
  328. TargetPosition = NewTargetPosition;
  329. }
  330.  
  331. void UAbilityComponent::PostDecision()
  332. {
  333. GetIndicatorDecalComponent()->SetWorldLocation(GetTargetPosition());
  334. }
  335.  
  336. void UAbilityComponent::SendSignalToTriggerOnPhase()
  337. {
  338. // .AddDynamic: expression must be an lvalue or function designator
  339. switch (AbilityPhase)
  340. {
  341. /*
  342. case EPhase::Decision:
  343. TurnQueue->OnPlayerInputSignature.AddDynamic(this, &UAbilityComponent::OnDecision);
  344. break;
  345. */
  346. case EPhase::Prep:
  347. TurnQueue->OnPrepSignature.AddDynamic(this, &UAbilityComponent::Resolution);
  348. break;
  349. case EPhase::Dash:
  350. TurnQueue->OnDashSignature.AddDynamic(this, &UAbilityComponent::Resolution);
  351. break;
  352. case EPhase::Blast:
  353. TurnQueue->OnBlastSignature.AddDynamic(this, &UAbilityComponent::Resolution);
  354. break;
  355. case EPhase::Move:
  356. TurnQueue->OnBlastSignature.AddDynamic(this, &UAbilityComponent::Resolution);
  357. break;
  358. }
  359. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement