Hello there.
I am creating a personal Gameplay Action System. I already created some actions like throws, crouches, etc and now I am creating an action for aiming.
With this action, I want to visualize my projectile’s path when I will throw it.
What I already do is create the path and connected it with my socket, but there is few issues:
- When I click the key for the InputAction, the path appear but then, after few seconds, it will disappear. I already tried to increase the Params.DrawDebugTime, but if I increase it too much, then after it will not disappear.
- I want my path to start from the socket (and I achieved that) and finish where my mouse is pointing on the ground (not achieved). I already figured out something, but is clearly not working.
I leave here my .h file:
#pragma once
#include "CoreMinimal.h"
#include "SAction.h"
#include "SAction_AIM.generated.h"
class ASStyler;
/**
*
*/
UCLASS()
class RANGER_API USAction_AIM : public USAction
{
GENERATED_BODY()
protected:
UPROPERTY(VisibleAnywhere, Category = "AIM")
FName HandSocket;
UPROPERTY(EditAnywhere, Category = "AIM")
float ProjectileRadius;
UPROPERTY(EditAnywhere, Category = "AIM")
float ProjectileVelocity;
UPROPERTY(EditAnywhere, Category = "AIM")
float AIMDelay;
UPROPERTY(EditAnywhere, Category = "AIM")
TSubclassOf<ASStyler> Styler;
UFUNCTION()
void AIMDelay_Elapsed(ACharacter* InstigatorCharacter);
public:
virtual void StartAction_Implementation(AActor* Instigator) override;
virtual void StopAction_Implementation(AActor* Instigator) override;
USAction_AIM();
};
Here my .cpp file:
// Fill out your copyright notice in the Description page of Project Settings.
#include "SAction_AIM.h"
#include "PlayerCharacter.h"
#include "SStyler.h"
#include "Components/SplineComponent.h"
#include "GameFramework/Character.h"
#include "Kismet/GameplayStatics.h"
USAction_AIM::USAction_AIM()
{
HandSocket = TEXT("Muzzle_01");
ProjectileRadius = 500.0f;
ProjectileVelocity = 2000.0f;
AIMDelay = 0.1f;
}
void USAction_AIM::StartAction_Implementation(AActor* Instigator)
{
Super::StartAction_Implementation(Instigator);
if (ensure(Instigator))
{
FTimerHandle TimerHandle_AIMDelay;
FTimerDelegate Delegate;
Delegate.BindUFunction(this, "AIMDelay_Elapsed", Instigator);
GetWorld()->GetTimerManager().SetTimer(TimerHandle_AIMDelay, Delegate, AIMDelay, false);
}
}
void USAction_AIM::StopAction_Implementation(AActor* Instigator)
{
Super::StopAction_Implementation(Instigator);
AActor* ActorInst = UGameplayStatics::GetActorOfClass(GetWorld(), Styler);
ASStyler* StylerInst = Cast<ASStyler>(ActorInst);
if (StylerInst)
{
StylerInst->GetSplineComponent()->ClearSplinePoints(true);
}
}
void USAction_AIM::AIMDelay_Elapsed(ACharacter* InstigatorCharacter)
{
if(ensure(InstigatorCharacter))
{
FTransform HandTransform = InstigatorCharacter->GetMesh()->GetSocketTransform(HandSocket);
FPredictProjectilePathParams PredictParams;
PredictParams.StartLocation = HandTransform.GetLocation();
PredictParams.LaunchVelocity = HandTransform.GetRotation().GetForwardVector() * ProjectileVelocity;
PredictParams.MaxSimTime = 2.0f;
PredictParams.DrawDebugType = EDrawDebugTrace::ForDuration;
PredictParams.ActorsToIgnore.Add(InstigatorCharacter);
PredictParams.bTraceWithCollision = true;
PredictParams.bTraceComplex = true;
PredictParams.DrawDebugTime = 22.0f;
FPredictProjectilePathResult PredictResult;
bool bHit = UGameplayStatics::PredictProjectilePath(GetWorld(), PredictParams, PredictResult);
if(bHit)
{
TArray<FVector> PointLocation;
for (FPredictProjectilePathPointData PathPoint : PredictResult.PathData)
{
PointLocation.Add(PathPoint.Location);
}
FVector MouseLoc = FVector::Zero();
FVector MouseDir = FVector::Zero();
APlayerController* PC = UGameplayStatics::GetPlayerController(GetWorld(), 0);
PC->DeprojectMousePositionToWorld(MouseLoc, MouseDir);
FHitResult HitResult;
bool bHitTrace = GetWorld()->LineTraceSingleByChannel(HitResult, MouseLoc, MouseLoc + MouseDir * 2000.0f, ECC_Visibility);
if (bHitTrace)
{
PointLocation.Add(HitResult.Location);
}
AActor* ActorInst = UGameplayStatics::GetActorOfClass(GetWorld(), Styler);
ASStyler* StylerInst = Cast<ASStyler>(ActorInst);
if (StylerInst)
{
StylerInst->GetSplineComponent()->SetSplinePoints(PointLocation, ESplineCoordinateSpace::World);
}
}
}
}
I am sorry if there are some big mistakes.
Thanks for the help in advice!