Function Pointers
Contents
Overview
Dear Community,
When you have a whole bunch of functions that you want to call, that are all related in some way,
you can make a function pointer array to quickly access and call a specific function by index!
My Example: 30 Behavior Functions
In my example, I have 30 behaviors that are all virtual functions as part of an AI system.
Each creature needs to implement the behavior in its own way, so the functions are virtual.
But in the AI class, I need to be able to say "run this behavior function" quickly and easily.
That's what function pointers enable you to do!
Special Thanks and C++ Note
You can easily find info on function pointers on the internet, but in UE4 classes you need to also specify the namespace, and I was having trouble with that part
Special thanks go to Steve Allison and other Epic Devs for offering the correct syntax!
C++ Code for UCLASS() Function Pointers
YourClass.h
#include "YourClass.generated.h"
#define BEHAVIORS_MAX 30
UCLASS()
class AYourClass : AActor //or any other class setup
{
GENERATED_UCLASS_BODY()
public:
//The Function Pointer Variable Type
//Functions take in 0 parameters and return void
typedef void (AYourClass::*FunctionPtrType)(void);
//A static array of 30 Function Pointers
FunctionPtrType BehaviorFunctions[BEHAVIORS_MAX];
//Play a Behavior from the Function Pointer Array
// implementation does not vary in subclasses, so not virtual
void PlayBehavior(int32 BehaviorIndex );
//Initialize the array
void InitBehaviors();
//The actual functions which are implemented in subclasses
//or this class itself
virtual void PlayBehavior_Idle_LookLeftToRight();
virtual void PlayBehavior_Idle_LookFullCircle();
virtual void PlayBehavior_Idle_ScanUpDown();
//...more functions
}
YourClass.cpp
#define LOOK_FULL_CIRCLE 0
#define SCAN_LEFT_TO_RIGHT 1
#define SCAN_UP_DOWN 2
//... more function index defines to 29
void AYourClass::InitBehaviors()
{
BehaviorFunctions[LOOK_FULL_CIRCLE] = &AYourClass::PlayBehavior_Idle_LookFullCircle;
BehaviorFunctions[SCAN_LEFT_TO_RIGHT] = &AYourClass::PlayBehavior_Idle_LookLeftToRight;
BehaviorFunctions[SCAN_UP_DOWN] = &AYourClass::PlayBehavior_Idle_ScanUpDown;
//...more functions
}
void AYourClass::PlayBehavior_Idle_LookLeftToRight(){}
void AYourClass::PlayBehavior_Idle_LookFullCircle(){}
void AYourClass::PlayBehavior_Idle_ScanUpDown(){}
//...rest of functions
void AYourClass::PlayBehavior(int32 BehaviorIndex )
{
//valid range check
if (BehaviorIndex >= BEHAVIORS_MAX || BehaviorIndex < 0) return;
//~~
//Special Thanks to Epic for this Syntax
(this->* (BehaviorFunctions[BehaviorIndex]))();
//the above line plays the appropriate function based on the passed in index!
}
Syntax Complexity Comparison
this same sort of setup, without function pointers, would either have been a switch statement, or a series of if elses.
Supposing there were actually 30 entries you can see why a function pointer array simplifies all this!
this
//Without function pointers
if(BehaviorIndex == SCAN_LEFT_TO_RIGHT)
PlayBehavior_Idle_LookLeftToRight();
else if (BehaviorIndex == LOOK_FULL_CIRCLE)
PlayBehavior_Idle_LookFullCircle();
else if (BehaviorIndex == SCAN_UP_DOWN)
PlayBehavior_Idle_ScanUpDown();
//...
//...
//and much much more ...
becomes this!
//With Function Pointers
//Special Thanks to Epic for this Syntax
(this->* (BehaviorFunctions[BehaviorIndex]))();
//that's it! nothing else!!!!
Summary
Thanks to Epic I can now present to you the correct C++ syntax for using UCLASS-specific function pointers!