I’m trying to make a classic laser sight system to visually show the player where his bullets will bounce. Now I have figured out the logic and implemented everything with line traces, however whenever I try to spawn the laser Niagara system, after some brief time the editor crashes and I get an EXCEPTION_STACK_OVERFLOW error. How can I go about solving this?
This is the code that I am trying to use to make this happen:
void ABaseGun::StartLaserSight()
{
this->DistanceToCover = this->MaximumRange;
this->LaserStart = this->ProjectileSpawnPoint->GetComponentLocation();
this->LaserEnd = this->LaserStart + this->ProjectileSpawnPoint->GetForwardVector() * this->DistanceToCover;
FHitResult HitResult;
TArray<TEnumAsByte<EObjectTypeQuery>> CollisionObjectTypes;
// Only WorldStatic objects will be registered
CollisionObjectTypes.Add(UEngineTypes::ConvertToObjectType(ECC_WorldStatic));
TArray<AActor*> ActorsToIgnore;
bool GotHit = UKismetSystemLibrary::LineTraceSingleForObjects(GetWorld(), this->LaserStart, this->LaserEnd,
CollisionObjectTypes, true, ActorsToIgnore, EDrawDebugTrace::None, HitResult, true);
if (GotHit)
{
this->NiagaraComp->SetNiagaraVariableVec3(FString("Laser Start"), this->LaserStart);
this->NiagaraComp->SetNiagaraVariableVec3(FString("Laser End"), HitResult.Location);
UNiagaraFunctionLibrary::SpawnSystemAtLocation(GetWorld(), this->NiagaraComp->GetAsset(), this->LaserStart,
FRotator(0, 0, 0), FVector(1, 1, 1), true, true, ENCPoolMethod::None, true);
this->DistanceToCover -= FVector::Dist(this->LaserStart, HitResult.Location);
this->LaserStart = HitResult.Location;
FVector UnitVector = UKismetMathLibrary::GetDirectionUnitVector(HitResult.TraceStart, HitResult.TraceEnd);
FVector ReflectionVector = UKismetMathLibrary::GetReflectionVector(UnitVector, HitResult.Normal);
this->LaserEnd = this->LaserStart + ReflectionVector * this->DistanceToCover;
this->BounceLaser();
}
else
{
this->NiagaraComp->SetNiagaraVariableVec3(FString("Laser Start"), this->LaserStart);
this->NiagaraComp->SetNiagaraVariableVec3(FString("Laser End"), this->LaserEnd);
UNiagaraFunctionLibrary::SpawnSystemAtLocation(GetWorld(), this->NiagaraComp->GetAsset(), this->LaserStart,
FRotator(0, 0, 0), FVector(1, 1, 1), true, true, ENCPoolMethod::None, true);
}
}
void ABaseGun::BounceLaser()
{
if (this->DistanceToCover <= 0) { return; }
FHitResult HitResult;
TArray<TEnumAsByte<EObjectTypeQuery>> CollisionObjectTypes;
// Only WorldStatic objects will be registered
CollisionObjectTypes.Add(UEngineTypes::ConvertToObjectType(ECC_WorldStatic));
TArray<AActor*> ActorsToIgnore;
bool GotHit = UKismetSystemLibrary::LineTraceSingleForObjects(GetWorld(), this->LaserStart, this->LaserEnd,
CollisionObjectTypes, true, ActorsToIgnore, EDrawDebugTrace::None, HitResult, true);
if (GotHit)
{
this->DistanceToCover -= FVector::Dist(this->LaserStart, HitResult.Location);
this->LaserStart = HitResult.Location;
FVector UnitVector = UKismetMathLibrary::GetDirectionUnitVector(HitResult.TraceStart, HitResult.TraceEnd);
FVector ReflectionVector = UKismetMathLibrary::GetReflectionVector(UnitVector, HitResult.Normal);
this->LaserEnd = this->LaserStart + ReflectionVector * this->DistanceToCover;
this->BounceLaser();
}
}
Above I am just trying to get one beam working but I still crash the same. I really have no clue why is this happening as well as why is the beam stuttering behind the moving player. The above functions are called in Event Tick as I also have no clue on where to even put this since it has to be updated every single frame otherwise it looks horrible.
Also to note, I have set the Niagara system to be 'Complete (Let Particles Finish then Kill Emitter).
All in all I am trying to get the following effect:
- Create Niagara system at the location of the gun’s muzzle
- Set the end of that beam to either the hit location of the trace or a certain distance away from the gun (the range of the weapon)
- If we do get a hit, create another system starting at that location and ending at the reflected vector X remaining distance away
- Continue doing this as long as we have not reached the maximum distance of the weapon
- Refresh each tick
Any suggestions on how to do this and not tank the performance or crash the editor?