Since god luo sky signs are done, that simply to the earth explosion star also to do it.

There are a few minor changes here, starting with changing TargetActor’s launch mode from Instant to User Confirm. The process becomes 1. Start targeting 2. Player confirm 3. End targeting and transfer data

The second is to tick the Actor, because the tracking itself is an Actor, so it can have a heartbeat (tick). We expect to be able to adjust the release location of abilities at any time before the player confirms it.

The rest are minor changes to skill effects and logic.

Let’s take a look at the final result

TargetActor

First or create TargetActor derived classes, named AbilityChibakuTenseiTargetActor.

Some changes have been made to the header file and the previous one, so I need to rewrite the Tick function. Two new Actor objects, one to show the location of skill release, this location will be updated in the Tick; One is used as a skill effect, which is the ball in the center of the video. There is also a function to get where the character’s line of sight hits the ground.

UCLASS(a)class GAS_LEARN_API AAbilityChibakuTenseiTargetActor : public AGameplayAbilityTargetActor
{
	GENERATED_BODY(a)public:
	AAbilityChibakuTenseiTargetActor(a);virtual void StartTargeting(UGameplayAbility* Ability) override;

	virtual void ConfirmTargetingAndContinue(a) override;

	virtual void Tick(float DeltaSeconds) override;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Ability Settings", meta=(ExposeOnSpawn = true))
	float Radius;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Ability Settings", meta=(ExposeOnSpawn = true))
	TSubclassOf<AActor> ConePointClass;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Ability Settings", meta=(ExposeOnSpawn = true))
	TSubclassOf<AActor> MeteorClass;
	
	// Get Player Looking Point Vector
	UFUNCTION(BlueprintCallable, Category="Chikabu Tensei")
	bool GetPlayerLookingPoint(FVector& LookingPoint);

protected:
	UPROPERTY()
	AActor* ConePoint;

	UPROPERTY()
	AActor* Meteor;
};
Copy the code

The constructor needs the Actor to have a heartbeat, so bCanEverTick=true is required

AAbilityChibakuTenseiTargetActor::AAbilityChibakuTenseiTargetActor()
{
	PrimaryActorTick.bCanEverTick = true;
	
}
Copy the code

Once you start tracking the target, create an Actor ConePoint to represent where the skill will be released.

void AAbilityChibakuTenseiTargetActor::StartTargeting(UGameplayAbility* Ability)
{
	OwningAbility = Ability;
	MasterPC = Cast<APlayerController>(Ability->GetOwningActorFromActorInfo() - >GetInstigatorController());
	SourceActor = Ability->GetOwningActorFromActorInfo(a); ConePoint =GetWorld()->SpawnActor<AActor>(ConePointClass, FVector::ZeroVector, FRotator::ZeroRotator);
}
Copy the code

GetPlayerLookingPoint GetPlayerLookingPoint GetPlayerLookingPoint GetPlayerLookingPoint GetPlayerLookingPoint GetPlayerLookingPoint

  1. PlayerController→GetPlayerViewPoint(ViewVector, ViewRotation) can get the sight direction and position of the character. Of course, you can replace this function by getting the position and orientation of the Character’s Camera.
  2. It then detects the collision location by firing a ray from the character’s line of sight via GetWorld()->LineTraceSingleByChannel.
  3. After a collision, LookingPoint = hitResult. ImpactPoint can get the line of sight position.
bool AAbilityChibakuTenseiTargetActor::GetPlayerLookingPoint(FVector& LookingPoint)
{
	// Get Player View Vector and View Rotation
	FVector ViewVector;
	FRotator ViewRotation;
	if(MasterPC)
		MasterPC->GetPlayerViewPoint(ViewVector, ViewRotation);

	FCollisionQueryParams QueryParams;
	QueryParams.bTraceComplex = false;
	if(SourceActor)
	{
		QueryParams.AddIgnoredActor(SourceActor->GetUniqueID());
	}
	
	FHitResult HitResult;
	
	bool TryTrace = GetWorld() - >LineTraceSingleByChannel(
		HitResult,
		ViewVector,
		ViewVector + ViewRotation.Vector(*)10000.0 f,
		ECollisionChannel::ECC_Visibility,
		QueryParams);

	if(TryTrace)
	{
		LookingPoint = HitResult.ImpactPoint;
	}
	else
	{
		LookingPoint = FVector::ZeroVector;
	}

	return TryTrace;
}
Copy the code

In the Tick function, you first get the LookLocation, and then update the position of the ConePoint to the look-forward position.

void AAbilityChibakuTenseiTargetActor::Tick(float DeltaSeconds)
{
	Super::Tick(DeltaSeconds);

	FVector LookLocation;
	GetPlayerLookingPoint(LookLocation);

	ConePoint->SetActorLocation(LookLocation);
}
Copy the code

Basic ConfirmTargetingAndContinue function as well as in the previous article.

The only difference is that once collision detection is complete, a fireball Actor representing the effect of the skill is generated, and the ball is also placed in TargetData.

void AAbilityChibakuTenseiTargetActor::ConfirmTargetingAndContinue(a)
{
	// ViewLocation is the location where collision detection is generated
	FVector ViewLocation;
	GetPlayerLookingPoint(ViewLocation);

	TArray<FOverlapResult> OverlapResults;
	TArray<TWeakObjectPtr<AActor>> OverlapActors;

	FCollisionQueryParams QueryParams;
	QueryParams.bTraceComplex = false;
	QueryParams.bReturnPhysicalMaterial = false;
	if(SourceActor)
	{
		QueryParams.AddIgnoredActor(SourceActor->GetUniqueID());
	}

	bool TryOverlap = GetWorld() - >OverlapMultiByObjectType(
		OverlapResults,
		ViewLocation,
		FQuat::Identity,
		FCollisionObjectQueryParams(ECC_Pawn),
		FCollisionShape::MakeSphere(Radius),
		QueryParams);

	if(TryOverlap)
	{
		for(FOverlapResult& OverlapResult: OverlapResults)
		{
			APawn* PawnOverlapped = Cast<APawn>(OverlapResult.Actor);
			if(PawnOverlapped)
			{
				OverlapActors.AddUnique(PawnOverlapped);
			}
		}
	}

	FVector MeteorSpawnLocation = ConePoint->GetActorLocation(a); MeteorSpawnLocation += ConePoint->GetActorUpVector(*)100.0 f;
	Meteor = GetWorld()->SpawnActor<AActor>(MeteorClass, MeteorSpawnLocation, ConePoint->GetActorRotation());
	ConePoint->Destroy(a); OverlapActors.Add(Meteor);
	FGameplayAbilityTargetDataHandle TargetData =  StartLocation.MakeTargetDataHandleFromActors(OverlapActors);
	TargetDataReadyDelegate.Broadcast(TargetData);
	
}
Copy the code

Create two actors, one for ConePoint and one for Meteor

Here the effect does not do any requirements, you can like. The only thing you need to be careful about is setting the life cycle of the Meteor so that it self-destructs.

Cone Point

Meteor

Added a particle effect that requires a life cycle of 5.0s

Role of the blueprint

Create a new Custom Event in the role blueprint that causes the role to move in the Target direction over time.

The method is to set a Timer and destroy the Timer Handler after the duration expires

Here the Push Timer is the event that has an effect in the Timer. It has the same effect as the previous Push Character Event, which imposes an Impluse on the center of the sphere.

Chibaku Tensei Ability

In fact, I think a better way would be to add a Sphere Collision to BP_Meteor to do GE instant damage to enemies within the effect every once in a while, but this time I just did it for convenience and just played with it.

Create the GA_ChibakuTensei, release the skill and launch the previously implemented Target Actor Task

Note the data Settings here, we chose a skill range of 1000. ConePoint Class and Meteror Class are the blueprint actors just created

After the Data is retrieved, it stores the Actors and Meteor that collided, and Meteor is placed in the last position of the Data array. Launch the Custom Event you just implemented for each Character in the target scope, and then apply the skill effects.

Other things include playing animations, sound effects, and so on. Same as in the last article, I won’t write it, trust you!

test

GAS Primer collection