Download

Is this approach possible with C++? (types from C#)

Hi, I’m new to UE4 and C++, until now I’ve worked with Unity and C# for indie development. My problem is that I’d like to replicate the state machine I use for my characters in Unity. I find it useful and versatile to work with Type in this case, but I’m having a hard time with it in C++.

Dictionary<Type, State> _states = new Dictionary<Type, State>();
private State _state;
public float timeOnState = 0;

public void SetState(Hashtable args = null, System.Action<System.Action> callback = null) where T : State, new()
{

    if (_state != null)
    {
        _state.OnStateExit();
    }
    timeOnState = 0;
    State state;

    if (_states.TryGetValue(typeof(T), out state))
    {
        _state = state;
        if (_state.character == null)
            _state.character = this;
        _state.OnStateEnter(args, callback);
        return;
    }

    var t = new T
    {
        character = this,
    };

    _states[typeof(T)] = t;
    _state = t;
    t.OnStateEnter(args, callback);
}

I have tried templates and it works fine when calling SetState<MyState>() but the problem comes when trying to store the types themselves in order to reuse them if they have already been created.

I know I could forget about types and use an enum to identify states, and a factory to instantiate them when needed, but I’d like to learn if this approach is possible.

Thanks

It should definitely be possible. With vanilla C++ it would be harder but not impossible, so since you’re trying to do it in UE4 I’ll skip this bit. A lot of the parts that you’d have to manually build to make it work are already provided by UE4’s framework.

To start with, you’ll have to choose whether or not your state types are UObjects or structures. UObjects will be slightly easier since they already have shared parent type, but you can do the same thing with structures as long as you inherit all your structures from a single structure type. But we’ll go with UObject for the remainder of the post.

For the sake of the rest of the post I’m assuming that the function is declared as:

template< class T >
void SetState( )

but you could have T be whatever identifier you want.

Your dictionary becomes a map: TMap< UClass*, UObject* > at the least. You might want to make a new type one step above that with all the virtual functions your states can implement. That would then be the type you use for the second template parameter.

The equivalent to typeof(T) would be T::StaticClass( ). That will return the UClass* for the type being specified.

Lastly, the equivalent to new T would be NewObject< T >( this ). That’s assuming this is a member function on some other UObject/AActor type. That parameter is the “owner” (of a sort) of the object that you’re creating. You won’t be able to pass anything into it as constructor parameters (because UE4 reserves control of the constructor for UObjects) so you’ll need an Init-like function to call after you create the object.

I really like state machines too. Good luck, templates can be tricky even for seasoned C++ programmers.

1 Like