Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save michaeltchapman/53dd048441036da7065a1c7f815663a4 to your computer and use it in GitHub Desktop.
Save michaeltchapman/53dd048441036da7065a1c7f815663a4 to your computer and use it in GitHub Desktop.
#include "maladius.h"
#include "BaseCharacter.h"
#include "AbilitySystemComponent.h"
#include "AttachedNonRotatingParticleCue.h"
AAttachedNonRotatingParticleCue::AAttachedNonRotatingParticleCue(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
IsOverride = true;
PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.bStartWithTickEnabled = true;
bAutoDestroyOnRemove = true;
AutoDestroyDelay = 0.f;
bUniqueInstancePerSourceObject = true;
bUniqueInstancePerInstigator = false;
bAllowMultipleOnActiveEvents = true;
bAllowMultipleWhileActiveEvents = true;
bHasHandledOnRemoveEvent = false;
NumPreallocatedInstances = 4;
bHasHandledOnActiveEvent = false;
bHasHandledWhileActiveEvent = false;
bAutoAttachToOwner = false;
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
Particles = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("Particles"));
Particles->SetupAttachment(RootComponent);
Particles->SetVisibility(false);
Offset = FVector(0.f);
bDropToFloor = false;
bSetParticleParameter = false;
bAttributeAsParameter = false;
}
void AAttachedNonRotatingParticleCue::OnOwnerDestroyed(AActor* DestroyedActor)
{
Super::OnOwnerDestroyed(DestroyedActor);
Particles->DeactivateSystem();
}
/** Called when returning to the recycled pool. Reset all state so that it can be reused. Return false if this class cannot be recycled. */
bool AAttachedNonRotatingParticleCue::Recycle()
{
Super::Recycle();
Particles->ResetParticles();
Particles->SetVisibility(false);
PrimaryActorTick.SetTickFunctionEnable(false);
return true;
}
void AAttachedNonRotatingParticleCue::Tick(float Deltatime)
{
Super::Tick(Deltatime);
if (AttachedComponent)
{
if (bUseMeshSocket)
{
SetActorLocation(AttachedComponent->GetSocketLocation(SocketName));
}
else {
SetActorLocation(AttachedComponent->GetComponentLocation() + Offset);
}
if (bSetParticleParameter && BaseChar)
{
UAbilitySystemComponent *AbilityComp = BaseChar->GetAbilitySystemComponent();
if (AbilityComp)
{
float MaxAttr = AbilityComp->GetNumericAttribute(ScaledAttribute);
if (bUseParameterInverse)
{
MaxAttr = 1.0f - MaxAttr;
}
if (bAttributeAsParameter)
{
Particles->SetFloatParameter(ParticleParameter, MaxAttr);
Particles->SetVectorParameter(ParticleParameter, FVector(MaxAttr));
}
}
}
}
}
/** Called when we are about to reuse the GC. Should undo anything done in Recycle like hiding the actor */
void AAttachedNonRotatingParticleCue::ReuseAfterRecycle()
{
Super::ReuseAfterRecycle();
Particles->SetVisibility(true);
PrimaryActorTick.SetTickFunctionEnable(true);
}
bool AAttachedNonRotatingParticleCue::OnActive_Implementation(AActor* MyTarget, const FGameplayCueParameters& Parameters)
{
BaseChar = Cast<ABaseCharacter>(MyTarget);
FVector SpawnLocation = MyTarget->GetActorLocation();
if (bDropToFloor)
{
static const FVector RayOffset = FVector(0.f, 0.f, 500.f);
FHitResult AdjustHit;
GetWorld()->LineTraceSingleByChannel(AdjustHit, SpawnLocation + RayOffset, SpawnLocation - RayOffset, COLLISION_BLOCKWORLD);
if (AdjustHit.bBlockingHit)
{
Offset = AdjustHit.ImpactPoint - SpawnLocation + FVector(0.f, 0.f, 10.f);
}
}
if (bUseMeshSocket)
{
AttachedComponent = Cast<USceneComponent>(MyTarget->GetComponentByClass(UMeshComponent::StaticClass()));
if (AttachedComponent)
{
SetActorLocation(AttachedComponent->GetSocketLocation(SocketName));
}
}
else {
AttachedComponent = MyTarget->GetRootComponent();
SetActorLocation(AttachedComponent->GetComponentLocation() + Offset);
}
if (bSetParticleParameter)
{
if (BaseChar)
{
UAbilitySystemComponent *AbilityComp = BaseChar->GetAbilitySystemComponent();
if (AbilityComp)
{
float MaxAttr = AbilityComp->GetNumericAttribute(ScaledAttribute);
if (bUseParameterInverse)
{
MaxAttr = 1.0f - MaxAttr;
}
if (bAttributeAsParameter)
{
Particles->SetFloatParameter(ParticleParameter, MaxAttr);
Particles->SetVectorParameter(ParticleParameter, FVector(MaxAttr));
}
else {
Particles->SetFloatParameter(ParticleParameter, Parameters.RawMagnitude / MaxAttr);
Particles->SetVectorParameter(ParticleParameter, FVector(Parameters.RawMagnitude / MaxAttr));
}
}
}
}
Particles->SetVisibility(true);
Particles->ActivateSystem();
return true;
}
bool AAttachedNonRotatingParticleCue::OnRemove_Implementation(AActor* MyTarget, const FGameplayCueParameters& Parameters)
{
Particles->DeactivateSystem();
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment