Due to a particular setup in my game, I would like to prevent two of the same class from overlapping each other. They are stationary, and contain a box collider.
To be more clear, I created a Location class (Here is Location.cpp):
And I have some derived classes, lets call them Ruins and BanditCamp (Here is BanditCamp.h. Ruins.h/.cpp is exactly the same):
#pragma once
#include "CoreMinimal.h"
#include "Location.h"
#include "BanditCamp.generated.h"
UCLASS()
class HERA_API ABanditCamp : public ALocation
{
GENERATED_BODY()
};
I want to check if any class derived from Location is overlapping with each other. This is my best attempt so far. Is this a decent approach at detecting what I want to avoid?
Again, we are back in Location.cpp
void ALocation::BeginPlay()
{
Super::BeginPlay();
for (const FOverlapInfo& overlaps : BoxCollider->GetOverlapInfos())
{
checkf(overlaps.OverlapInfo.GetComponent()->GetOwner()->GetClass() == ALocation::StaticClass(), TEXT("One Location is overlapping another box component. Most likely, this is another Location and will cause errors in the UI!"));
}
}
Yes check and ensure should only trigger if their condition is false. I use asserts a lot as well since they allow you to check for any unexpected mistakes in code or when you setup specific objects. Plus you get automatic breakpoints when they are violated and you’re running with a debugger attached.
Since you are only checking for == ALocation::StaticClass() this means all overlaps must be other instances of ALocation. If your instance overlaps anything other than that the check should trigger. I think you have the condition reversed, you want the assert to fail (condition being false) whenever the overlap is another ALocation. So it should be checkf(!overlaps.OverlapInfo.GetComponent()->GetOwner()->IsA(ALocation::StaticClass()), ...);. This allows anything to overlap the ALocation unless it is another ALocation or derived from ALocation. You can also use overlaps.OverlapInfo.GetComponent()->GetOwner()->GetClass()->IsChildOf() instead of IsA.
Since in your case the message reads like a non-critical issue I’d also like to recommend the “map check for errors”. You could implement that in your ALocation class. You should be able to attach the actor instance(s) to the error message which allows you to directly link to the actor in the level.
I sincerely appreciate the explanation! Thank you so much
I think something was off with live coding because after shutting down the engine and restarting it (I build from source) I discovered I had the condition reversed. Weird….anywho, thanks again!!
Oh one another question if you don’t mind, please: if I wanted to create a Map Check for this, do you have an example? I am seeing other folks specify to only use it with a WITH_EDITOR macro to not package it in a finished build, but those posts are several years old and I don’t know if that is necessary anymore.
Yes the declarations of virtual void CheckForErrors(); in AActor, UActorComponent and FLevelInstanceActorImpl all are in WITH_EDITOR blocks. So if you implement it in a derived class you have to do the same if you do void CheckForErrors() override;.
AStaticMeshActor even has a check very similar to yours. It checks whether two of the same static meshes are placed almost exactly on top of each other. In case you duplicate/paste one without moving it somewhere else.