Intro
So I thought I’d try a little experiment and make an Actor Component that could expose it’s BP defined Event Dispatchers to streamline “level scripting”. The idea being when an actor instance is dropped in the world (in editor), the user could click on this new Actor Component on this instanced actor, and assign functions to call from other actors for any given parent Actor’s Event Dispatchers. That was a mouthful, here is the workflow that I have in mind:
PROBLEM:
Imagine a level designer wants to hook up a light switch to a light bulb and have that light bulb turn on and off. Cool, I’ll use an interface and generalize the On and Off states on the light. But because I learn later that they want to be able to have that same switch in different circumstances do different things like
- When the switch is put into the off position it does the opposite for a particular light
- A particular switch closes a door, and turns on a light
- Another particular switch opens a door and turns on a light, and locks some other door
I also want designers on the team to be able to make new BPs without having to make a code class so they may prototype more quickly.
WORKFLOW:
Well what if we had something like this,
THE BELOW IS PLACEHOLDER, NON FUNCTIONAL
I would imagine that some of these fields would be auto populated. Things like the Event Dispatcher names could be auto populated and even once you reference a light or a door it could maybe have a drop down list of potential function you want to call when a particular event dispatcher is triggered.
CODE ATTEMPT
So I managed to make this somewhat work for functions. I learned that I could go through the functions available from a BP class in C++ and call any non native functions. Here is my (very incomplete) attempt at searching for/autopopulating a list of functions on any given actor.
void USomeComponent::ParentPostEditChangeProperty(UObject* ParentObject)
{
if (!IsValid(ParentObject))
{
return;
}
for (TFieldIterator<UFunction> func(ParentObject->GetClass()); func; ++func) {
if (func->GetName().Contains("ScriptAssist"))
{
UE_LOG(LogTemp, Warning, TEXT("Function found - %s"), *func->GetName());
//Use below when you want to call a function
//ParentObject->ProcessEvent(*func, nullptr);
}
}
}
Great I can find the names of the functions, and even apply a filter for functions that contain the words “ScriptAssist” in their name, and using the commented code, call them! But I’m really stuck with how to make this work for “Event Dispatchers” that are defined non natively.
Conclusion
Does anyone have any thoughts on if my approach here is a waste of time, or am I onto an interesting workflow paradigm. Or should I just take a different route that involves gameplaytags for actions that can occur or using an Interface with generic functions like: Activate, Deactivate, lock, unlock etc.
