Logic Driver - Easily Design Gameplay Systems with State Machines

Hi TeunVT,

I spent some time tonight both reading about Oculus Quest and testing the UE 4.22 version with the android SDK and I can’t recreate any issues on my end. I don’t have an Oculus Quest available so my testing is directly to an android phone. If you can provide more details on how you’re using the state machine I might be able to figure out what’s going on.

Is the state machine an actor component or an object on an actor?
What’s the context type?
The state machine was started successfully for a period of time before the error occurred?

And did this error just start today? There was an update to the plugin published early this morning for 4.22.

Please e-mail support@recursoft.net – it’s a little easier that way and the forums don’t always send a notification.

Thanks!

Actually I think I was able to recreate this. It looks like the state machine isn’t being destroyed properly when an actor is deleted and once garbage collection occurs it causes a crash when the engine attempts to tick the state machine. Working on a fix now. Nice catch, thanks for reporting it!

If you want to get around it now, add logic in to stop or shut down the state machine when your actor is destroyed.

Update 1.4.1
S****upports Unreal Engine 4.20 - 4.23

(4.23 will be published after official engine release)

New Features:
New Transition Nodes and Support for Event Triggers

  • Optional transition nodes have been added to help support transition logic which may need to occur before and after evaluation such as binding to an event.

  • On Transition Initialized (When the state leading to the transition is entered)

  • On Transition Shutdown (When the state leading to the transition is exited)

  • On Transition Pre-Evaluate (Before each evaluation. Performance warning)

  • On Transition Post-Evaluate (After each evaluation. Performance warning)

  • Can Transition Evaluate Getter/Setter which can be used in the transition context. If false the transition is never evaluated and can never be taken.

Changes:

  • GetWorld - State machine instances’ GetWorld implementation will now only attempt to return the context’s world as this is the only world the state machine should care about. Previously it would check GEngine and the outer object. If ImplementsGetWorld was called on the state machine blueprint during design time it would fail.
  • GetContext - State machine instances’ GetContext implementation will only return the context which was set during initialize. Previously it would return the outer object if no context was set. All contexts should be set using the Initialize method.

Bug Fixes:

  • State Machine instances have improved cleanup handling to prevent a possible crash when garbage collection occurs.

Hi Recursoft,

We’ve got a crash using an addon related to component network replication. It happens, that client receives two RepNotifies in the same tick: R_NetworkedTransitions and R_Instance, in this order. R_Instance is not yet initialzied while trying to process transitions, so R_Instance->GetNodeMap(); returns empty NodeMap which is followed by nullptr access violation.
Hope you can help!


access violation is here: USMStateMachineComponent::DoProcessTransactions() [client\plugins\logicdriver\source\smsystem\private\smstatemachinecomponent.cpp:359]

Thanks!

Thank you for reporting it and the detailed description. I was able to recreate it and fix it.

New behavior is REP_NetworkedTransitions will now queue transitions that are attempting to be processed before the instance is initialized.
REP_OnInstanceLoaded will process queued transitions after the instance is initialized.
New flag added to StateMachine components ‘bDiscardTransitionsBeforeInitialize’ which will discard transitions that occur before the instance is initialized. (Basically the old behavior but without crashing!)

This has been submitted for 4.21-4.23. Epic may take a day or more to build and publish.

Edit:
This update is now available as version 1.4.2.

Update 1.5
S****upports Unreal Engine 4.21 - 4.23

New Features:
Intermediate Reference Graphs

  • State machine references now support an intermediate graph to allow direct control over the reference.
  • The context of the reference can be changed.

  • A new optional node Get State Machine Reference is available in this graph.

  • Reference variables can be read or set from here.

  • An optional entry point On State Machine Start is available for initializing properties.

  • This fires when the root state machine of the blueprint owning the reference starts.

Save & Restore States

  • The guid of the active state can be easily retrieved for serialization.

  • GetNestedActiveStateGuid

  • To restore a state machine to its previous state it only needs the active guid and will automatically set initial states of all affected state machines.

  • LoadFromState

  • If the current state of a nested state machine which doesn’t contain the active state is important use GetAllCurrentStateGuids and LoadFromMultipleStates.

  • Normally nested state machines clear their state on exit. Added bReuseCurrentState and bReuseIfNotEndState flags to state machine nodes to allow this behavior to change.

Editor Settings

  • Color and debug information can now be configured.

Comment Bubbles

  • State nodes now support standard comment bubbles.

Added Helpers to Retrieve State and Transition Information from a State Machine Graph

  • GetStateInfo and GetTransitionInfo
  • Retrieve blueprint friendly read only structs containing helpful information.
  • Any contained guids can be checked against the instance itself with TryGetStateInfo or TryGetTransitionInfo.

New Common State Machine Events

  • Added OnTransitionTaken, OnStateChange, and OnStateMachineUpdated events to instances and components.
  • State and transition events include the new blueprint friendly structs as parameters.

**Replace With… **

  • Added Replace With sub menu for converting the selected node to another type while preserving transitions.
  • This is destructive to the node and its contents.

Changes:

  • State nodes will better validate and display errors.

  • State machine references will no longer default to an empty nested state machine when a reference is forcibly deleted and instead stay in an error state to allow the reference to be changed.

  • Organized blueprint functions into different categories.

  • Blueprint helper nodes will now display which state they represent.

  • State machine instances have more general helper functions exposed in C++ and blueprints to retrieve information such as current states or all referenced instances.

  • Improved descriptions of Tick overrides to better reflect what they actually change.

  • They have always affected the Update rate of a state machine but do not affect overloaded Tick functions.

New Platforms Whitelisted:

  • Development

  • Linux

  • Runtime

  • Linux

  • PS4

  • XboxOne

  • Switch

  • TVOS

  • Linux has been tested and is supported. No testing has been performed on the other platforms.

Bug Fixes:

  • Fixed state machine references ticking independently of the parent which could cause state machines to update twice per tick.

  • Added bAllowIndependentTick which defaults to false and bCallTickOnManualUpdate which defaults to true.

  • The new default behavior should fix the issue while not breaking uses of Tick overload on references. However be sure the Parent Tick is still called if you overload Tick.

  • Fixed Promote to Variable not displaying on some node pins.

Hi

Is there an easy way to access public variables in the state-machine that’s referenced in the state machine actor component?

Yep, on the actor component call GetInstance and cast that to your correct blueprint type.

Hi

I think I might have encountered a bug. I put a event tick in the event graph of the statemachine, and in the runtime the statemachine will not run, in the statemachine graph, the active time of the current state will remain zero forever. I am using the latest version of the plugin and able to reproduce this in both UE 4.21 and UE 4.23.

Are you calling the parent tick too? Right click on the Tick node and select Add Call to Parent Function. If that’s not called the state machine won’t be able to update automatically.

You mean I should add a parent tick after the event tick, right? I did that and still get the same result.

Yes, adding a parent node and connecting it right after the event tick should be all you need. Can you e-mail a screen shot of your event graph to support@recursoft.net?

Ok, so I tried again. Now I know what’s wrong. I should connect the delta time between event tick and parent tick, too. Sorry for the bothering!

Hi,

I also asked on https://www.unrealengine.com/marketp…itor/questions but I think it’s better copy this here.

Building a dialogues based on SMachines. I need somehow to keep extra details, which are specific for a given state. Basically every State is a dialogue sentence. Once in that State, I need to grab a string sentence from somewhere in the State and send it to UI.

The most convenient way would be to create extra properties (local constants or variables???) for narrative artist. Also I am thinking of custom States with custom functionality, which can be used in along with default States. I guess that functionality is not there, but if you share your ideas, I would be very grateful.

No worries and I’m glad it’s working! Pretty sure I’ve forgotten to do that before too. I’ll check to see if I can auto create and wire a parent tick node on new state machine creation.

Local variables per state is currently in development and may do what you want. If your data is constant it could be set as a default value. But if it’s constant already, can you just include it in the blueprint node you use to send text to the UI (or another text creation node) rather than redefine it as a variable? Or include it in a data table somewhere and reference that? The individual states weren’t really designed for data storage. Blueprint member variables work of course but are state machine wide.

Another option would be to create a separate state machine for each state and create blueprint variables for the sentence, and reference each state machine in master state machines (basically treat multiple state machines as single states), but that’s probably far less convenient.

If there are other use cases you can share regarding this I can see if they can be met or added with local variable development.

Thank you for your reply. I made a deep analysis. Seems like SMachines is a developer oriented solution. Using this for dialogues would be overkill, as it does not allow to extend States/Transition functionality. As long as showing dialog sentences is a repeatable procedure one should copy/paste same code in the States, instead of creating a specific State for the dialogues, reuse it, and allow to change it’s settings (character name, sentence, etc) without a code manipulation.

Just in case. You said local variables are in development. Please could you consider to implement that in such way:

  • Expose State instance. That would be great to have it. It should give access to local variable anyway - right?
  • If you expose State instance, would you allow to create custom States, with a custom functionality? Basically instead of placing all code usual way through the States Machine editor, one could implement this using a blueprint. And then select custom State in the State Machine Editor (similar to “Add State Machine Reference…”). This will catch several rabbits: it will allow private variables and functions. Will make it artist friendly, t.e. developer creates a custom State nodes with extra options for artist to select in the Details window.
  • Same idea for Transitions. Expose Transition instance. Allow local variables and functions. But this guy seems more tricky, t.e. how we gonna select a custom Transition from the list?

Seems lots work to me. But should you grab it on board that would be awesome. :wink:

So ideally… developer creates New State Class (or New Transition Class) blueprints.

In a state machine blueprint be able to set the state or transition to the created classes. Possibly similar to state machine references. Then be able to set instance values in the details window of each state or transition. And to be clear, you only need instance variables to change, and not the BP logic itself, correct? I ask because that would be extremely difficult.

If I have that right, I’ll consider ways of implementing this (or parts of it). I don’t want to commit to anything yet because you’re right in that the work to do this isn’t trivial and multiple problems would have to be solved like passing the context (and using it from within each state or transition), replication settings, etc. It might be better to see if I can enhance state machine references to set instance values in the details window and then use those as states.

Also in case it helps, inheritance works for state machines now. You can have a base state machine class with variables and functions, and use those in a child state machine class. Additionally with state machine references you can enable an intermediate graph and set properties of the reference there. All though that is done in a BP graph and not the details window. I’m also not sure how well that will work if you have the same reference multiple times on the same graph.

But to your first point, this is likely overkill for dialogue systems. I know there are plenty of dialogue editors on the market. Awhile ago I started working on a dialogue system based on logic driver. A blueprint editor where each node is actually a BP graph to construct a dialogue sentence, auto constructed from text or user created. Definitely have me consider working on it again, as a separate plugin or maybe including it in logic driver. I could see mixing state logic with dialogues being handy.

To be precise change variables and append logic similar way one can do this in the State editor. Changing internal logic is not needed. Idea is: create a node, append custom logic (aka node with predefined logic), expose variables, use anywhere. Same idea as BTT nodes.

I think that will do.

Logic Driver State Machine is indeed very close to the necessary requirements to build a custom logic. By custom I mean being as flexible as possible in building complex interactive scripts. There is Screenwriter asset on the market exactly for that. Sadly it’s buggy (the reason we did try States Machine solution), but if you take a closer look you will find how both are solving same tasks using almost similar ways.

I think it’s not coincidence you did work on both Logic Driver and the dialogues :slight_smile: It really allows to build custom and complex dialogues on top of that.

The next intended feature of Logic Driver was local state variables, but I’ve reached a point in development where I need to put it on hold. The reason is nearly everything around expanding local variables is off limits in the engine. Classes aren’t fully exported and methods that need to be overridden aren’t virtual or are static. Despite those limitations local variables are mostly working in a development branch, except in order to achieve this was basically one hack after another. And it’s not something I’m comfortable releasing or supporting (or even using myself and I really wanted this feature).

LocalVar.PNG

In short, to support local variables properly requires some engine level changes.

So in its place I think I’ll shift development toward eventually supporting custom state classes similar to what

suggested. This will allow reusable classes while also naturally supporting member variables. I think this idea can be expanded upon nicely to allow unique types of nodes which could be used for other systems such as dialogues or quests.

The first step toward that is adding template support and details view editing for state machine references which should be in the next update.
Archetype.PNG

Last note: 4.24 version released earlier this week.

Hi, I ran into a situation where I need the Entry of SubStateMachine to branch out conditionally. To do that I put an Entry Conduit as below:

The SubStateMachine will exit if no animation is played. Either Slash_UL_L2L and Slash_UR_L2R will trigger their respective animations and kept the SubStateMachine from being exited.

The problem is the transition Entry->Slash_UL_L2L is evaluated 1 frame later after SubStateMachine is entered, at which point this SubStateMachine has already transitioned out.

I noticed that each Transition takes 1 tick to complete, even for a Transition between State-Conduit. Can you make the transition through Conduit nodes happens instantly instead?