BP_VolumeGas not properly removing all gas pillars

I am trying to improve ExampleLevel by making the gas pillars have visible gas clouds. I've implemented the editor-only functions in AFGGasPillarCloud that set up the links between gas pillars and gas cloud, and I can see the clouds getting spawned at all 5 pillar locations. However, only 2 out of 5 pillars have their gas clouds removed when destroying them. How can I figure out what is going on? (attachments in follow-up because :CertifiedDiscordMoment:)
Solution:
Works! So the key is that the effect height offset needs to be accounted for in my reimplementation of editor-only functionality. It's just a matter of changing one line. Attached the entire file just in case.
- mProximityPillarWorldLocations.Add(Pillar->GetActorLocation());
+ mProximityPillarWorldLocations.Add(Pillar->GetActorLocation() + FVector(0, 0, Pillar->GetEffectHeightOffset()));
- mProximityPillarWorldLocations.Add(Pillar->GetActorLocation());
+ mProximityPillarWorldLocations.Add(Pillar->GetActorLocation() + FVector(0, 0, Pillar->GetEffectHeightOffset()));
...
Jump to solution
8 Replies
Rex
RexOP3w ago
This is what I see in ContentInspector for the BP_VolumeGas actor in ExampleLevel after blowing up the 5 pillars. The most relevant parts are: mRemainingRelevantWorldLocations, mProximityPillarWorldLocations and mRemovedWorldLocations
Rex
RexOP3w ago
This is what I changed in FGGasPillarCloud.cpp (it's not perfect, but it should be good enough to get the job done)
#if WITH_EDITOR
#include "FGGasPillar.h"
#include "EngineUtils.h"
#include "Framework/Notifications/NotificationManager.h"
#include "Widgets/Notifications/SNotificationList.h"
#endif

#if WITH_EDITOR
static void ShowPostEditNotification(const FString& Message, SNotificationItem::ECompletionState State)
{
FNotificationInfo Info(FText::FromString(Message));
Info.ExpireDuration = 5.0f;
Info.bUseLargeFont = false;
TSharedPtr<SNotificationItem> Notification = FSlateNotificationManager::Get().AddNotification(Info);
if (Notification.IsValid()) {
Notification->SetCompletionState(State);
}
}

void AFGGasPillarCloud::GatherNearbyPillarLocations()
{
mProximityPillarWorldLocations.Empty();
for (TActorIterator<AFGGasPillar> ActorItr(GetWorld()); ActorItr; ++ActorItr) {
if (AFGGasPillar* Pillar = *ActorItr) {
if (GetDistanceTo(Pillar) <= mOverlapRadius) {
mProximityPillarWorldLocations.Add(Pillar->GetActorLocation());
Pillar->SetNearbyGasCloud(this);
Pillar->MarkPackageDirty();
}
}
}
const FString Message = FString::Printf(TEXT("Found %d gas pillars around gas cloud '%s'"), mProximityPillarWorldLocations.Num(), *GetName());
ShowPostEditNotification(Message, SNotificationItem::CS_Success);
this->MarkPackageDirty();
}

void AFGGasPillarCloud::NotifyGasPillarRemovedFromInfluence(AFGGasPillar* gasPillar)
{
if (gasPillar) {
mProximityPillarWorldLocations.Remove(gasPillar->GetActorLocation());
this->MarkPackageDirty();
}
}

void AFGGasPillarCloud::DebugDrawCurrentPillarLocations(){ }
#endif
#if WITH_EDITOR
#include "FGGasPillar.h"
#include "EngineUtils.h"
#include "Framework/Notifications/NotificationManager.h"
#include "Widgets/Notifications/SNotificationList.h"
#endif

#if WITH_EDITOR
static void ShowPostEditNotification(const FString& Message, SNotificationItem::ECompletionState State)
{
FNotificationInfo Info(FText::FromString(Message));
Info.ExpireDuration = 5.0f;
Info.bUseLargeFont = false;
TSharedPtr<SNotificationItem> Notification = FSlateNotificationManager::Get().AddNotification(Info);
if (Notification.IsValid()) {
Notification->SetCompletionState(State);
}
}

void AFGGasPillarCloud::GatherNearbyPillarLocations()
{
mProximityPillarWorldLocations.Empty();
for (TActorIterator<AFGGasPillar> ActorItr(GetWorld()); ActorItr; ++ActorItr) {
if (AFGGasPillar* Pillar = *ActorItr) {
if (GetDistanceTo(Pillar) <= mOverlapRadius) {
mProximityPillarWorldLocations.Add(Pillar->GetActorLocation());
Pillar->SetNearbyGasCloud(this);
Pillar->MarkPackageDirty();
}
}
}
const FString Message = FString::Printf(TEXT("Found %d gas pillars around gas cloud '%s'"), mProximityPillarWorldLocations.Num(), *GetName());
ShowPostEditNotification(Message, SNotificationItem::CS_Success);
this->MarkPackageDirty();
}

void AFGGasPillarCloud::NotifyGasPillarRemovedFromInfluence(AFGGasPillar* gasPillar)
{
if (gasPillar) {
mProximityPillarWorldLocations.Remove(gasPillar->GetActorLocation());
this->MarkPackageDirty();
}
}

void AFGGasPillarCloud::DebugDrawCurrentPillarLocations(){ }
#endif
I just rotated the whole setup 180 degrees and it somehow started working?
LogTemp: Error: [HOOK] NotifyGasPillarDestroyed_Before(BP_VolumeGas_01_2, BP_GasPillar_03_2)
LogTemp: Warning: gasPillar Loc: X=-6800.000 Y=3360.000 Z=0.000
LogTemp: Warning: gasPillar Cloud: BP_VolumeGas_01_2
LogTemp: Warning: mProximityPillarWorldLocations: 5
LogTemp: Warning: - 0: X=-9720.000 Y=5180.000 Z=0.000
LogTemp: Warning: - 1: X=-11860.000 Y=4480.000 Z=0.000
LogTemp: Warning: - 2: X=-6800.000 Y=3360.000 Z=0.000
LogTemp: Warning: - 3: X=-8730.000 Y=2000.000 Z=0.000
LogTemp: Warning: - 4: X=-11950.000 Y=1650.000 Z=0.000
LogTemp: Warning: mRemovedWorldLocations: 0
LogTemp: Warning: mRemainingRelevantWorldLocations: 5
LogTemp: Warning: - 0: X=-9720.000 Y=5180.000 Z=0.000
LogTemp: Warning: - 1: X=-11860.000 Y=4480.000 Z=0.000
LogTemp: Warning: - 2: X=-6800.000 Y=3360.000 Z=0.000
LogTemp: Warning: - 3: X=-8730.000 Y=2000.000 Z=0.000
LogTemp: Warning: - 4: X=-11950.000 Y=1650.000 Z=0.000
LogTemp: Error: [HOOK] NotifyGasPillarDestroyed_Before return
LogTemp: Error: [HOOK] NotifyGasPillarDestroyed_After(BP_VolumeGas_01_2, BP_GasPillar_03_2)
LogTemp: Warning: gasPillar Loc: X=-6800.000 Y=3360.000 Z=0.000
LogTemp: Warning: gasPillar Cloud: BP_VolumeGas_01_2
LogTemp: Warning: mProximityPillarWorldLocations: 5
LogTemp: Warning: - 0: X=-9720.000 Y=5180.000 Z=0.000
LogTemp: Warning: - 1: X=-11860.000 Y=4480.000 Z=0.000
LogTemp: Warning: - 2: X=-6800.000 Y=3360.000 Z=0.000
LogTemp: Warning: - 3: X=-8730.000 Y=2000.000 Z=0.000
LogTemp: Warning: - 4: X=-11950.000 Y=1650.000 Z=0.000
LogTemp: Warning: mRemovedWorldLocations: 0
LogTemp: Warning: mRemainingRelevantWorldLocations: 5
LogTemp: Warning: - 0: X=-9720.000 Y=5180.000 Z=0.000
LogTemp: Warning: - 1: X=-11860.000 Y=4480.000 Z=0.000
LogTemp: Warning: - 2: X=-6800.000 Y=3360.000 Z=0.000
LogTemp: Warning: - 3: X=-8730.000 Y=2000.000 Z=0.000
LogTemp: Warning: - 4: X=-11950.000 Y=1650.000 Z=0.000
LogTemp: Error: [HOOK] NotifyGasPillarDestroyed_After return
LogTemp: Error: [HOOK] NotifyGasPillarDestroyed_Before(BP_VolumeGas_01_2, BP_GasPillar_03_2)
LogTemp: Warning: gasPillar Loc: X=-6800.000 Y=3360.000 Z=0.000
LogTemp: Warning: gasPillar Cloud: BP_VolumeGas_01_2
LogTemp: Warning: mProximityPillarWorldLocations: 5
LogTemp: Warning: - 0: X=-9720.000 Y=5180.000 Z=0.000
LogTemp: Warning: - 1: X=-11860.000 Y=4480.000 Z=0.000
LogTemp: Warning: - 2: X=-6800.000 Y=3360.000 Z=0.000
LogTemp: Warning: - 3: X=-8730.000 Y=2000.000 Z=0.000
LogTemp: Warning: - 4: X=-11950.000 Y=1650.000 Z=0.000
LogTemp: Warning: mRemovedWorldLocations: 0
LogTemp: Warning: mRemainingRelevantWorldLocations: 5
LogTemp: Warning: - 0: X=-9720.000 Y=5180.000 Z=0.000
LogTemp: Warning: - 1: X=-11860.000 Y=4480.000 Z=0.000
LogTemp: Warning: - 2: X=-6800.000 Y=3360.000 Z=0.000
LogTemp: Warning: - 3: X=-8730.000 Y=2000.000 Z=0.000
LogTemp: Warning: - 4: X=-11950.000 Y=1650.000 Z=0.000
LogTemp: Error: [HOOK] NotifyGasPillarDestroyed_Before return
LogTemp: Error: [HOOK] NotifyGasPillarDestroyed_After(BP_VolumeGas_01_2, BP_GasPillar_03_2)
LogTemp: Warning: gasPillar Loc: X=-6800.000 Y=3360.000 Z=0.000
LogTemp: Warning: gasPillar Cloud: BP_VolumeGas_01_2
LogTemp: Warning: mProximityPillarWorldLocations: 5
LogTemp: Warning: - 0: X=-9720.000 Y=5180.000 Z=0.000
LogTemp: Warning: - 1: X=-11860.000 Y=4480.000 Z=0.000
LogTemp: Warning: - 2: X=-6800.000 Y=3360.000 Z=0.000
LogTemp: Warning: - 3: X=-8730.000 Y=2000.000 Z=0.000
LogTemp: Warning: - 4: X=-11950.000 Y=1650.000 Z=0.000
LogTemp: Warning: mRemovedWorldLocations: 0
LogTemp: Warning: mRemainingRelevantWorldLocations: 5
LogTemp: Warning: - 0: X=-9720.000 Y=5180.000 Z=0.000
LogTemp: Warning: - 1: X=-11860.000 Y=4480.000 Z=0.000
LogTemp: Warning: - 2: X=-6800.000 Y=3360.000 Z=0.000
LogTemp: Warning: - 3: X=-8730.000 Y=2000.000 Z=0.000
LogTemp: Warning: - 4: X=-11950.000 Y=1650.000 Z=0.000
LogTemp: Error: [HOOK] NotifyGasPillarDestroyed_After return
That's what happens with one of the non-working pillars. Looks like the location is in the lists but it doesn't get removed for some reason Ignore the decompiler pooping nonsense for SSE stuff... Should I save the position in the gas cloud with mEffectHeightOffset pre-added?
this_01 = &this->mRemovedWorldLocations;
pFVar13 = this_01->AllocatorInstance;
local_118 = (double)CONCAT44(uVar16,uVar15);
dVar6 = (double)param_1->mEffectHeightOffset + local_118; // <--- mEffectHeightOffset
pFVar11 = pFVar13 + (this->mRemovedWorldLocations).ArrayNum;
for (; pFVar13 != pFVar11; pFVar13 = pFVar13 + 1) {
dVar17 = pFVar13->X - (double)local_128;
dVar18 = pFVar13->Y - uStack_120;
dVar5 = pFVar13->Z - dVar6;
if (dVar18 * dVar18 + dVar17 * dVar17 + dVar5 * dVar5 < 40000.0) goto LAB_1806c7014;
}
this_01 = &this->mRemovedWorldLocations;
pFVar13 = this_01->AllocatorInstance;
local_118 = (double)CONCAT44(uVar16,uVar15);
dVar6 = (double)param_1->mEffectHeightOffset + local_118; // <--- mEffectHeightOffset
pFVar11 = pFVar13 + (this->mRemovedWorldLocations).ArrayNum;
for (; pFVar13 != pFVar11; pFVar13 = pFVar13 + 1) {
dVar17 = pFVar13->X - (double)local_128;
dVar18 = pFVar13->Y - uStack_120;
dVar5 = pFVar13->Z - dVar6;
if (dVar18 * dVar18 + dVar17 * dVar17 + dVar5 * dVar5 < 40000.0) goto LAB_1806c7014;
}
Rex
RexOP3w ago
The two gas pillars that work properly are the ones with the smallest absolute value for mEffectHeightOffset. IIRC it's -150. Since the code checks whether the distance squared is less than 40000, this would explain why only these two work: the other three pillars' values are greater than 200 (sqrt(40000)). Time to test my theory!
No description
Rex
RexOP3w ago
Though I'll need to edit the header for AFGGasPillar since I can't access mEffectHeightOffset from AFGGasPillarCloud Oh, I'm stupid, I missed the getter
float GetEffectHeightOffset() const { return mEffectHeightOffset; }
float GetEffectHeightOffset() const { return mEffectHeightOffset; }
Rex
RexOP3w ago
For reference. All pillars are at Z=0, so Z is mEffectHeightOffset
No description
Solution
Rex
Rex3w ago
Works! So the key is that the effect height offset needs to be accounted for in my reimplementation of editor-only functionality. It's just a matter of changing one line. Attached the entire file just in case.
- mProximityPillarWorldLocations.Add(Pillar->GetActorLocation());
+ mProximityPillarWorldLocations.Add(Pillar->GetActorLocation() + FVector(0, 0, Pillar->GetEffectHeightOffset()));
- mProximityPillarWorldLocations.Add(Pillar->GetActorLocation());
+ mProximityPillarWorldLocations.Add(Pillar->GetActorLocation() + FVector(0, 0, Pillar->GetEffectHeightOffset()));
Rex
RexOP3w ago
Just noticed a slight issue: NotifyGasPillarRemovedFromInfluence needs + FVector(0, 0, gasPillar->GetEffectHeightOffset()) as well. Didn't catch this because it doesn't get called when there's only one gas cloud in the level (which is true for ExampleLevel) I'm going to PR this anyway
Robb
Robb6d ago
thanks for working on this and showing the process you went through here, educational stuff
Want results from more Discord servers?
Add your server