Search code examples
c#unity-game-engine

C# and Unity - can't understand correct way to extend base classes


I have 2 types of NPC's (Guest and Worker) which will have different logic and behaviors. For example:

  • at GuestController I want to manage places the Guest joined.

  • at WorkerController I want to manage current job the Worker is doing.

So I created these base classes to be extended.

NPC.NPCController{} // navmesh, animator, statemanager...
NPC.INPCState{} // State's methods like Enter, Execute, Exit
NPC.StateManager{} // switch current State

Then I create NPCGuest classes:

NPCGuest.NPCGuestController : NPCController{}
NPCGuest.StateFreeWalk : NPC.INPCState{}

And then created NPCWorker classes:

NPCWorker.NPCWorkerController : NPCController{}
NPCWorker.StateFreeWalk : NPC.INPCState{}

The problem I'm having is to create and use each Controller's specific logic.

For example, specific method in GuestController:

using Myproject.NPC;
namespace Myproject.NPCGuest
{
    public class NPCGuestController : NPC.NPCController
    {
        public void guestSpecificMethod()
        {
            Debug.Log("specific method for Guest");
        }
    }
}

And then try to use this method from Guest State class:

using Myproject.NPC;
namespace Myproject.NPCGuest
{
    public class StateFreeWalk : NPC.INPCState
    {
        public void Enter(NPCController npc)
        {
            npc.guestSpecificMethod();
        }
    }
}

This causes error because Enter method expects an NPController instead NPCGuestController.

If I change it to expects NPCGuestController, it causes error at line public class StateFreeWalk : NPC.INPCState, because the INPCState also expects for the base class NPCController.

What am I doing wrong?

Is it possible to reuse base classes? Or should I create separated INPCState and StateManager class for Guest and Worker?


Solution

  • Do not inject the NPCGuestController through a parameter of the Enter() method, but through e.g. constructor of StateFreeWalk.

    This decouples the interface NPC.INPCState from the specific needs (dependencies) of the implementation StateFreeWalk.

    using Myproject.NPC;
    namespace Myproject.NPCGuest
    {
        private readonly NPCGuestController _controller;
    
        public class StateFreeWalk : NPC.INPCState
        {
            public StateFreeWalk(NPCGuestController npc)
            {
                _controller = npc;
            }
        
            public void Enter()
            {
                _controller.guestSpecificMethod();
            }
        }
    }