0

I’m trying to convert my Clue Management System in C++ and have made a Primary Data Asset to easily change the clue data. To make it as efficient and memory optimal as I can, I've decided to use soft object pointers to Data Assets that are loaded in as the clues are collected.

I'm trying to convert my Clue Management System in C++ and have made a Primary Data Asset to easily change the clue data. In my Clue Item code I have an interface call for attempting to interact with the Clue:

bool AClueBase::AttemptInteraction_Implementation(UInteractComponent* Interactor)
{
    UE_LOG(LogClue, Display, TEXT("Clue Interacting"));
    
    UClueManagerSubsystem* ClueManager = GetGameInstance()->GetSubsystem<UClueManagerSubsystem>();
    if(!ClueManager) return false;
    
    UE_LOG(LogClue, Display, TEXT("Clue Manager Valid"));
    
    return ClueManager->CollectClue(ClueDataAsset);
}

This works fine, with the Clue Data Asset being a UPROPERTY:

UPROPERTY(BlueprintReadOnly, EditInstanceOnly) TSoftObjectPtr<UPrimaryDataAsset_Clue> ClueDataAsset;

The Function it is trying to call on the Clue Manager Subsystem is:

bool UClueManagerSubsystem::CollectClue(TSoftObjectPtr<UPrimaryDataAsset_Clue> Clue)
{
    if(!Clue) return false;
    
    UE_LOG(LogClue, Display, TEXT("Collecting Clue: %s"), *Clue->GetClueName());
    FAreaClues AreaClues;
    // If the Map has the Enum already, then we need to save a reference to the current value
    if(CollectedClues.Contains(Clue->GetClueLocation()))
    {
    // If the Map has the Enum already, then we need to save a reference to the current value
        AreaClues = CollectedClues[Clue->GetClueLocation()];
        
        UE_LOG(LogClue, Display, TEXT("Clue Location already in Map"));
    }

    if(AreaClues.CollectedClues.Contains(Clue)) return false;

    UE_LOG(LogClue, Display, TEXT("Clue doesn't already exist in Map"), *Clue->GetClueName());
    
    AreaClues.CollectedClues.Add(Clue, true);
    CollectedClues.Add(Clue->GetClueLocation(), AreaClues);
    
    UE_LOG(LogClue, Display, TEXT("Clue Successfully Added"), *Clue->GetClueName());

    OnCollectedClue.Broadcast(Clue);
    
    return true;
}

It doesn't get past the first guard clause in this function, so the soft object pointer is a nullptr apparently. I am new to C++ with Soft Object Pointers so I might be entirely misusing them, so any correction would be greatly appreciated :)

Paul Brown
  • 21
  • 2
  • [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) – Jesper Juhl Feb 05 '23 at 03:05
  • A soft object pointer is usually used to address an asset that can either be loaded, unloaded or null. If you want to use the asset, you have to load it using [`LoadSynchonous()`](https://docs.unrealengine.com/4.27/en-US/API/Runtime/CoreUObject/UObject/TSoftObjectPtr/LoadSynchronous/) and then pass it as a pointer or a reference, after you have checked, if it is valid. – Max Play Feb 06 '23 at 23:45

0 Answers0