There are lots of ways to structure an Unity project. There are no right or wrong ways, just ways which work or don't work for you.
But personally I am a fan of the single responsibility principle. This principle interpreted in the context of Unity scripting would mean that each MonoBehaviour should be responsible for one thing the object it's on does. Unity supports this pattern very well by its philosophy of composition over inheritance: A game object does not have a specific class. The properties and behaviors of each game object are the sum of its components.
A "Character" in a usual game does quite a lot of things. Attacking, walking, jumping, animating, taking damage and more. So each of these functionalities should be represented by a separate script. You often need to communicate between scripts (like temporarily disable movement while attacking or cancel an attack when taking damage). Such script-script communication can be realized with GetComponent<OtherClass>()
, Messages or Unity Events.
Controllers
(which I would call scripts which controlscontrol a different game object than the one it'sthey are attached to) or Managers
(which I would call scripts which orchestrates multiple game objects at once) do have their purposes. But in my opinion they should generally be avoided if the same feature can be feasibly implemented by a Component which acts on the object it's attached to.
Applying this philosophy to the topic of player input vs. ai input would be to create two different components AIInput
and PlayerInput
(when you are using the new input system, you might be able to use the PlayerInput component already provided). Those scripts should communicate with other classes in exactly the same way. This ensures that the AI can not accidentally cheat by doing things the player can not do. The difference is that one relays decisions made by the player through input, while the other relays decision made by code. And if you later want to add multiplayer, you can even create a 3rd component NetworkInput
which relays decisions communicated through network messages. Only one of these components would be attached to each character.