So i'm attempting to make a village management type game with its own spin. I have a 'worker' entity that moves around and collects essence, and deposits that essence into the base. Now i want to implement different job types for the workers. So some would be farmers, some fighters, etc. I was wondering the base way to do this? Iv'e thought of a couple of ways i could possibly to this. The first would be to have different prefab variants for each worker, with a base script attached to the parent and different job scripts attached to each variant. So the farmer would inherit the base script and will have the farmer script attached as well. Another way i thought of was to have all the job scripts attached to each worker, and just enable/disable them when the workers change jobs. Is there another easier way i'm missing? Which method would be easier to work with and implement? Pros and cons of both? Thanks.
Don't have all the scripts on the unit and do the enable/disable thing, use a delegate/callback/event/we to switch out the logic for each job. Could have a Job master class / Interface (not a monobehaviour) and have inheriting classes from it called like Job_Farmer Job_Fighter / IFarmer IFighter, and on the master unit script just have a variable for the master Job class / interface and use that to call stuff like LookForJob() DoJob() or whatever.
Very much what @SparrowsNest said - my instinct would be to have a Job master class and sub-classes that set up and handle all logic associated with that specific job. Also, take a look at GOAP - while a bit advanced and performance-intensive (it generates a crazy amount of garbage every frame), I understand it is often used to manage decision-making / activity simulations (I think Crusader Kings 2 uses a form of it to drive the behaviors of all in-game agents). There are some paid tutorials you can find online that go into more information and use cases.
When deciding on a solution, I recommend using something that's: Fairly easy to implement Easy to understand when you dig into it months later Expandable without having to go back into old code Relatively efficient GOAP is cool, but it has a steep learning curve. Here's an idea: 1. Add a "blackboard" script to your worker. This script holds information that your worker's jobs can use. As a first pass, for simplicity just use explicit variables. Example: Code (csharp): [Serializable] // (So we can see it in the inspector) public class Blackboard { public GameObject currentTarget; public GameObject currentThreat; // etc. } 2. Create jobs as ScriptableObject assets. ScriptableObjects aren't anything magical; they're just plain old script instances that Unity can serialize. A ScriptableObject asset is a ScriptableObject that's been saved as an asset file in your project. Example base class: Code (csharp): public class Job : ScriptableObject { public virtual Job Process(Worker worker) { // This function should update the job and return the job that the worker... // ...should work on next, usually the same job unless something has changed. return this; } } Example job for defending oneself: Code (csharp): [CreateAssetMenu] public class DefendSelf : Job { public override void Process(Worker worker) { // Code here to attack worker.blackboard.currentThreat. // If currentThreat is gone, return a new job. } } 3. Add a class that ties the blackboard and jobs together. Example: Code (csharp): public class Worker : MonoBehaviour { public Blackboard blackboard; public Job currentJob; void Update() { currentJob = currentJob.Process(this); } }