Managing Items in Range
UZCInteractableManager
ActorComponent that can be added to the Character and will automatically handle the management and de/activation of interactables.
Keeps track of all interactable items in range dynamically adding or removing based of proximity.
Runs the player look checks to know if any of the items need to activate (show popup) or deactivate (hide popup)
Manage Items
Items in range are stored in a TMap keyed off the Unique Object ID of the object.
Note: Here we store the most generic type AActor as the ptr value, but you could replace that with a more specific type or base class
This allows us to store and activate (if needed) a large number of concurrent items in range as well as saving perf costs by not performing vector math checks if we aren't in range of anything
.h
// UZCInteractableManager.h
// Keeps a running list of all items currently in range. Keyed by object unique ID
UPROPERTY()
TMap<uint32, TWeakObjectPtr<class AActor>> ItemsInRange;
Entering/Exiting Range
When Items notice an Actor has come in range, it will inform any that has this component type (UZCInteractableManager) of the event.
This is how we know to add or remove items from the Map.
.h
// UZCInteractableManager.h
// Add the item which entered range to our item range map
void ItemEnteredRange(class AActor* EnteringActor);
// Remove the item which left range from our item range map
void ItemExitedRange(class AActor* ExitingActor);
.cpp
// ZCUinteractableManager.cpp
void UZCInteractableManager::ItemEnteredRange(class AActor* EnteringActor)
{
if (EnteringActor)
{
// Add the item to our map, keyed by the unique ID of the object
ItemsInRange.FindOrAdd(EnteringActor->GetUniqueID(), MakeWeakObjectPtr<AActor>(EnteringActor));
}
}
void UZCInteractableManager::ItemExitedRange(class AActor* ExitingActor)
{
if (ExitingActor)
{
ItemsInRange.Remove(ExitingActor->GetUniqueID());
}
}
Check for items being looked at
We need to run a check for every item in range and determine if the player is looking at it or not so we can show/hide the pickup popup.
.h
// UZCInteractableManager.h
// Checks all items in range if we should show or hide the popup visibility
void CheckForItemsInRange();
.cpp
// UZCInteractableManager.cpp
// Called every frame
void UZCInteractableManager::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
CheckForItemsInRange();
}
CheckForItemsInRange will only run if we are in range of items, so majority of the time it will not be doing any actual work.
Apply the same vector logic as mentioned in Raycast-less Look Based Interactables to determine if the player is looking at an item or not.
Last updated