I’m working as C++ programmer on an Unreal Engine 5 survival RPG inspired by Enshrouded and Valheim. I work across UE5 C++ and Blueprints, owning multiplayer/replication and core gameplay systems (AI, party system, world map & waypoints/compass, interaction, and UI/UX). My focus is a modular, data-driven architecture with safe pointers (TObjectPtr/TWeakObjectPtr), const-correctness, and early-out guards—plus ongoing profiling and optimizations to keep Gameplay smooth and the codebase scalable.

Modular Map & Waypoint System — Component-Driven, Safe & Optimized (UE5)

The map/compass is fully modular: attach a UMapMarkerComponent to any Actor and it auto-registers on the Map and Compass. Designers can tweak the icon, size, color, and visibility directly in the editor—no hardcoded links. Below is the waypoint add flow, which converts a screen click into a world-space marker and safely spawns it.

Waypoint Placement (UI → World)

void UWorldMapUI::AddWaypoint(const FVector2D ScreenPosition) const
{
    const UMapSubsystem* MapSubsystem = UMapSubsystem::Get(this);
    if (!IsValid(MapSubsystem) || MapSubsystem->RegisteredMarkers.Num() >= 3)
    {
        LOG_WARN(MapSystemLog, "Cannot add more than 3 waypoints. Remove one first.");
        return;
    }

    if (!MapTexture)
    {
        LOG_ERROR(MapSystemLog, "MapTexture border is null!");
        return;
    }

    const FGeometry Geo = MapTexture->GetCachedGeometry();
    const FVector2D LocalPt = Geo.AbsoluteToLocal(ScreenPosition);

    const FVector2D Size = Geo.GetLocalSize();
    if (LocalPt.X < 0 || LocalPt.X > Size.X || LocalPt.Y < 0 || LocalPt.Y > Size.Y)
        return;

    const ULandSubsystem* LandSubsystem = ULandSubsystem::Get(this);
    if (!IsValid(LandSubsystem)) return;

    FVector WorldPos = LandSubsystem->TextureToWorld(LocalPt, Size, 0.f);
    if (UMapSubsystem* MSS = UMapSubsystem::Get(this); IsValid(MSS))
    {
        WorldPos = MSS->ProjectToGround(WorldPos, 100000.f, 20.f);
    }

    if (IsValid(MarkerClass))
    {
        FActorSpawnParameters Params;
        Params.Owner = GetOwningPlayer();
        if (GetWorld()->SpawnActor<AActor>(MarkerClass, WorldPos, FRotator::ZeroRotator, Params))
        {
            LOG_INFO(MapSystemLog, "Spawned Marker at %s", *WorldPos.ToString());
        }
        else
        {
            LOG_ERROR(MapSystemLog, "Failed to spawn Marker actor!");
        }
    }
}
What’s happening here:
  • Subsystem gate & limit: Fetch UMapSubsystem. If invalid or at the 3-waypoint cap, exit early to keep UI readable and avoid spam.
  • Screen → widget space: Use GetCachedGeometry() + AbsoluteToLocal to map the click into the map widget’s local coords, then bounds-check.
  • Widget → world space: Delegate to ULandSubsystem::TextureToWorld so UI stays dumb; all terrain/UV mapping logic lives in the land subsystem.
  • Ground projection: UMapSubsystem::ProjectToGround snaps to terrain with a bounded trace (depth/step), so markers never float.
  • Spawn with ownership: Spawn the configured MarkerClass at the resolved position and set Owner to the local player for clean lifetime/relevance.
Why this design is solid:
  • Modular & editor-driven: Any Actor with UMapMarkerComponent auto-registers to Map/Compass. Icon, size, color, and visibility are editable per instance.
  • Const-correct, early exits: The UI call is const and cheap; invalid state bails immediately, keeping frame time predictable.
  • Safe pointers: Use IsValid(...) checks; store UObjects as TObjectPtr<> in owners, and external actor refs as TWeakObjectPtr<> to avoid dangling refs.
  • No transient allocs: Pure stack temps here; heavy work (traces, conversions) is bounded. No arrays/ToArray() churn in the hot path.
  • Separation of concerns: UI handles input & feedback, ULandSubsystem handles mapping, UMapSubsystem manages registration and projection.
Editor workflow (quick)
  • Add UMapMarkerComponent to any actor you want visible.
  • Tweak icon/size/visibility in Details; the component registers in BeginPlay().
  • Click the map to place up to three waypoints; markers appear on Map + Compass with distance/direction.

Screenshots

Contact

Got any Suggestions or queries? Reach out or check out the game on Play Store.