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

admin2025-05-01  1

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?

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?

Share Improve this question asked Jan 2 at 21:11 anderlainianderlaini 1,8233 gold badges28 silver badges48 bronze badges 0
Add a comment  | 

2 Answers 2

Reset to default 2

One of the options I see here is to use generics, it might be a good case for that but it depends on your vision of future functionality and general architecture.
You can make your interface NPC.INPCState to be generic, something like this:

public interface INPCState<T> where T : NPCController

this way you can clarify the exact type you need in particular states:

public class StateFreeWalk : INPCState<NPCGuestController>   
{         
    public void Enter(NPCGuestController npc)         
    {             
        npc.guestSpecificMethod();         
    }     
}

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();
        }
    }
}
转载请注明原文地址:http://anycun.com/QandA/1746096487a91616.html