rlewicki / AdvancedSightSupport

This is a repository for tracking bug reports, feature requests and general support for Advanced Sight plugin for Unreal Engine 5
https://www.unrealengine.com/marketplace/en-US/product/advanced-sight
0 stars 0 forks source link

Save state of the plugin #1

Open arvindrajayadav opened 6 days ago

arvindrajayadav commented 6 days ago

Hi, moving this question from the UE site. Please let me know if this isn't the appropriate place.

The original question: I want to save the state of the entire Advanced Sight subsystem at a given moment in time. I'm implementing a Prince of Persia: Sands of Time style rewind mechanic, so as you can imagine, I want to store the state of everything in the world for the past X frames so the player can "rewind time" and restore those previous states as necessary. Can you please tell me the best way to go about doing that?

You responded: This one shouldn't be too hard actually given that entire system is data driven, so you would only need to snap shot current data and then overwriting it when "reverting" the time. Unfortunately doing that at the moment would require writing C++ and this would need to be done using the system itself which is C++ only. If your project is blueprint only I can try to write an extension that would allow to create and restore a snapshot and put it somewhere online.

arvindrajayadav commented 6 days ago

Luckily, my project is C++ based and writing C++ isn't a problem, so please let me know what data I need to save and what class/location is the best place to do it. Thanks!

rlewicki commented 6 days ago

Hi @arvindrajayadav, thanks a lot for reaching out here! So the property you are interested in most is the Queries from UAdvancedSightSystem class. This array of structs store all the necessary information and current state of the system for all agents using this system so creating a snapshot of it would store the current state of the system and then you would simply need to overwrite it.

Unfortunately I have made it a protected property which is a bad choice on my side because it means you can't access it directly. There are few potential solutions to this problem, two of them would require you to make a very minor code change in the plugin.

  1. Move Queries property from protected to public space inside UAdvancedSightSystem.
  2. Mark UAdvancedSightSystem as abstract class by adding Abstract to it's UCLASS macro at the top. Then create a subclass of this class inside your game's code module.
  3. If none of the above works for you, I can make the property public and release a hotfix patch to the marketplace so you don't have to modify plugin's code yourself.

Let me know if any of the above works for you.

arvindrajayadav commented 6 days ago

It would be nice if you can update the plugin, because modifying it myself would mean losing later changes you make (or I can copy the source to my project, but then I'll need to manually merge your updates in the future).

rlewicki commented 5 days ago

Alright, I will roll out new version either tonight or tomorrow morning, Epic usually takes 2-3 days to process the update and publish it to the launcher. Will let you know when it's available!

rlewicki commented 5 days ago

@arvindrajayadav just want to confirm that I have submitted the update to Epic and am waiting now for them to publish it!

rlewicki commented 5 days ago

Actually, I just received an email confirming that new update is available right now. That was surprisingly quick on their end.

arvindrajayadav commented 4 days ago

I tried saving queries like this but it doesn't quite seem to work. I feel like something else in the character state (maybe in the AI) is persisting, perhaps it's setting a target somewhere else (like the BTree?)

void APlayerCharacter::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    if (PlayerData->bRewindTimeInProgress)
    {
        if (PlayerData->bPlayerAffectedByRewindingTime)
        {
            bool bResultValid = false;
            FUStateSnapshot_FirstPersonCharacter Snapshot = History->GetLastStateFromHistory(bResultValid);
            if (bResultValid)
            {
                //other code here, deleted because it's not relevant to the question
                if (AdvancedSightSubsystem != nullptr)
                {
                    AdvancedSightSubsystem->Queries = Snapshot.Queries;
                }
            }
        }       
    }
    else
    {
        FUStateSnapshot_FirstPersonCharacter Snapshot;

        //other code here, deleted because it's not relevant to the question

        if (AdvancedSightSubsystem != nullptr)
        {
            Snapshot.Queries = AdvancedSightSubsystem->Queries;
        }

        History->AddStateToHistory(Snapshot);
    }
}

I've attached a video of what rewinding time looks like, maybe that will help figure out what else I need to save.

https://github.com/rlewicki/AdvancedSightSupport/assets/1761417/8aa37596-63b2-4f8a-acb8-49a6c742fcc1

The enemy character is going back in time, but it's always ! and it goes to the player's location as soon as time rewinding stops and it's allowed to move again.

rlewicki commented 3 days ago

I see, yes, the widget blueprint logic is event based so it will require a bit more tweaking. In case of rewinding it might be worth re-doing the logic so it actually determines it's state every frame rather than listening for events from the sight component.

That being said, the sight logic in the system might be working just fine, it might be it's just the visual layer of the UI that shows the state incorrectly. To verify that I would suggest using the debug tool, it should show you the actual state of the system.

You can find more info on debug tools here: https://rlewicki.tech/advanced-sight-docs/debug.html