Hey, I’m trying to write a character controller that can be controlled either by a player using the input system or what I will just call an “AI Brain” component and I am having trouble trying to decide what goes where, and how to make my scripts follow the SOLID principals of coding. I have a list of concerns and a rough draft so far but I would really like to hear from somebody with more experience to help me clean up my act. My hope with this post is to come up with clearly defined jobs for my scripts, and a cleaner way to abstract my input from the character components, as if I change anything about input in one script, I have to change it in four others.
I’ll start by sharing my current draft:
This is what it looks like right now. Labeled elements are as follows:
- Is an object which houses an input singleton. It houses input actions and exposes variables that represent the values of the input actions. For example, a button input like Fire1 (left click) has a publicly accessible boolean that says if the button is down on the current frame.
- Is the root of the player, it houses all the logic for the character.
- Is the character’s “brain” and it uses an IEntityInput interface. There are currently two types. For any input action exposed in the singleton, an IEntityInput interface has an identical variable. In the Player version of the brain, it just exposes the value of the variable from the singleton to the components with a getter. The AI version of the brain has a simple state machine that manipulates the variables like “Fire1” or “InputDirection” based on the states. This is where I have the most trouble.
- A simple state machine that kinda does nothing for now, but like if it is in the main state then the character can move and act normally, but if it goes to the dead state then the player can no longer move or shoot. In the future this is where I would put a status effect like stunned or slowed.
- Inventory controls tools the character can hold and it has caused me a lot of headache with respect to handling inputs. I actually broke it just prior to this screenshot because I can’t figure out how I want to handle binding the “Use” function of an item to an input based on the slot that something goes in. Especially if say, I have a slot for the main hand, and maybe a specific tool has a special ability that has an additional binding beyond just using Fire1. Maybe I am overengineering this too early?
- A simple recreation of the locomotion behavior from Blockland (which is largely similar to quake, who knew?).
Was that confusing? I am confused too. I don’t know what I am doing and I feel like input handling has bled out into too many components. I want to simply expose the input actions themselves in the singleton, but if I do that, then I can’t make the AI brain work because I can’t make fake input actions for the ai state machine to control. Examples of scalable input system usages that I have found online seem to be a bit too advanced, like the FPS Sample, or they are too simple to answer my concerns. My long-term goal here is to make something like the bots in TF2. They are designed for players first, but then I can make a simple AI control a character that works just like a player in every other way.
Did my question make sense? This is kinda broad. I don’t quite know what I am asking because I don’t know what I need. Big thanks to anyone who made it this far.