How to override a function like those done in unrealscript states?

Well in unrealscript, we have code like this:

class Pawn extends Actor;

simulated function BeginFire(Byte FireModeNum)
{
      //do something
}

state Active
{
    simulated function BeginFire(Byte FireModeNum)
    {
          //do something else
    }
}

Then if we call :

GotoState('Active');
BeginFire(0);// Active.BeginFired called

However in UE4, I can only use c++ class to implement states:

class  AWeaponBase : public AActor
{
        UStateBase* currentstate;
        void BeginFire(char FireModeNum);
}

class UStateActive : public UStateBase 
{
         void BeginFire(char FireModeNum);
}

now assume if we call :

SetState(UStateActive );
BeginFire(0);//want the state override version

How can this be done?
I find a function might serve this purpose well:

 UFunction* FindFunction( FName InName ) const;

But ‘find’ usually imply it might not be a very fast function and would cause performance problem if called every tick.

So what’s the most clean way to accomplish the uc state in c++?

Hi LonelySnake,

I’m assuming UStateBase is a class you wrote yourself? If so, then in your BeginFire function you should just be able to do something like this:

if (currentstate)
{
	currentstate->BeginFire(FireModeNum);
}

Or is your question about how you can create that new state based off of the class?

Yes, it’s a class inherit UObject.

I considered your solution before post this question:
If I use currentstate to call a function, the function must be declared in the UStateBase and one must know it in advance.
Another problem is that as the development goes on the UStateBase might be filled with most of the AWeaponBase’s functions and the functions of its subclasses.

I also think about deriving both weapon and state from a same base, but the derived state class wont be compatible to all the derived weapon class which wont be so handy as us state.

So I think my problem is:
How to call a weapon function without knowing if it is override by current state, if currentstate override it call the override version, if not call the weapon version, called by a same statement.

If I cant do it excatly like uc in UE4,I think I can use this

UFunction* FindFunction( FName InName ) const

to check if the state has a function to partly do it.

Then the question remain is if this find function will cause a performance impact if called several times in a tick.

Hi LonelySnake,

Regarding the speed of FindFunction: it depends. Any performance-related questions should always be tested. Functions can run faster on some machines than others, that’s simply the nature of programming. FindFunction itself does seem to cache the results it finds, however dynamically invoking functions is slow.

When it comes to your state system, why not just have different functions for each state? AWeaponBase could have the base BeginFiring method, and each class that extends AWeaponBase could manage its own way of beginning to fire? Having a state system like that seems like it would get expensive (eventually), potentially confusing, and add an unnecessary level of abstraction.

The reason why I prefer uc state, is that I can put all the weapon behavior functions in the weapon class, and I can only write the extended and override function only in the specific derived class, without modifying the weapon base class.Very handy.

However in the solution you suggested, I have to put all weapon functionalties in the statebase class, at least had them declared. And everytime I added a function in a concrete state class, I need to modify the statebase class, is that correct?

I used to be a unity and ue3 programmer, relatively new to c++, but I think to modify the base class frequently is usually not a good omen to a project, or do I miss something to coding this state method correctly?

Hi LonelySnake,

Not quite. The first part of your message is essentially what I described: get rid of the whole state-based system and use concrete weapon classes. You could have something like ASniperRifle inherit from AHitscanWeapon which would inherit from AWeaponBase. That is the typical object-oriented approach.

I personally have never used UnrealScript, but I think I may be beginning to understand your original question. In UE3, how would you have implemented each weapon type? As separate states?

In UE3 we also have concrete weapon classes, and the they will inherit the states by default(state blocks are cantained in the same uc file).

For example, a function called BeginFire() is ovrride in state Active and state Reloading, then whenever BeginFire() is called, the override version of this function will be called according to the currentstate of this weapon(class Rifle for example), and we dont have to check the state manually in or outside the function with tons of if/switch statement.

Then, say if we have a ChargeRifle inherit from Rifle, we can just override the BeginFire() the state Active and added a function Charge() in this state while other versions of BeginFire will be left intact.

Of course the example could be done with other approach but they might not be as clean as this uc one.

But since these cant be done in UE4, I think I’ll have to live with the typical object-oriented approach for now.

Hi LonelySnake,

Ahh, okay. The only way I personally have seen it done is with different functions being called based on some kind of state value (usually an enum), such as Tick_Active, Tick_Reloading, etc. In theory you could try duplicating a state system like in the code in your original post, but that sounds like it could cause unnecessary code duplication to me. You could also try looking at the ShooterGame example project to see how they handle different states for the weapons.

The problem is that c++ doesn’t have a state system in languague level so I can’t simply duplicating them and that’s why I post this question in the first place.

Fortunately I have some ideas now I think I will come up with an alternative solution eventually.

Thank you for the answers.

Hi LonelySnake,

I am going to mark this question as resolved for tracking purposes based on your comment “Fortunately I have some ideas now I think I will come up with an alternative solution eventually.”