Announcement

Collapse
No announcement yet.

Is it possible to let the editor tick while in the middle of a script?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Is it possible to let the editor tick while in the middle of a script?

    I got a bug in 4.22, I have a bunch of python scripts that take a while to complete the execution.

    After spawning a custom bp actor and a level sequence actor, I try to set the spawned level sequence actor as a property on the spawned custom bp actor and I got a stack overflow error.

    Code:
    sequence = unreal.EditorLevelLibrary.spawn_actor_from_object(some_sequence, loc, rot)
    
    actor = unreal.EditorLevelLibrary.spawn_actor_from_object(some_bp_actor, loc, rot)
    
    actor.set_editor_property("the_sequence", sequence)
    After debugging I found that the problem on the FSequencer::GetHandleToObject function. The FMovieSceneObjectCache ObjectCaches is empty. From what I could test the ObjectCaches is set on the Tick function. If the ObjectCaches is empty, then the GetHandleToObject will call itself forever, and thus, the stack overflow.

    So I'm wondering if there's a way to make the editor tick without having to quit the python script. The workaround would be to make a timer on c++ and break my script execution in 2 parts, one before ticking and another after ticking.
    Last edited by Rodja; 04-19-2019, 04:59 PM.

    #2
    For this particular issue, I was able to create a workaround by forcing the level sequence asset to evaluate.

    Here's the function on the C++ side, exposed to BP and python:
    Code:
    void USequencerUtils::ForceSequencerEvaluate(ULevelSequence* Sequence)
    {
        IAssetEditorInstance* AssetEditor = FAssetEditorManager::Get().FindEditorForAsset(Sequence, true);
        FLevelSequenceEditorToolkit* LevelSequenceEditor = (FLevelSequenceEditorToolkit*)AssetEditor;
        if (LevelSequenceEditor != nullptr)
        {
            // Get current Sequencer
            ISequencer* Sequencer = LevelSequenceEditor->GetSequencer().Get();
            Sequencer->ForceEvaluate();
        }
    }
    And here's what I'm doing in Python:

    Code:
    sequence = unreal.EditorLevelLibrary.spawn_actor_from_object(sequence_asset, loc, rot)
    
    actor = unreal.EditorLevelLibrary.spawn_actor_from_object(actor_asset, loc, rot)
    
    # On 4.22 the editor needs to tick for the sequencer to be re-evaluated.
    
    # We are forcing this evaluation on the c++ by using the force_sequencer_evaluate
    
    # which will take a Level Sequence ASSET as the input, and will re-evaluate that level sequence asset
    
    if UEVersion.compare('>=4.22'):
        unreal.EditorPlayer.force_sequencer_evaluate(sequence_asset)
    However, I would still like to hear from you all on how you handle situations like this, where you need the editor to tick in the middle of a Python script execution.

    Comment

    Working...
    X