You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#与Unity中扩展NPC基类遇问题:如何复用基类实现专属逻辑?

问题分析与解决方案

你的问题核心在于基类接口的参数类型无法直接访问派生类的专属方法,完全不需要拆分两套INPCState和StateManager,通过泛型改造基类就能复用现有架构。

1. 改造INPCState为泛型接口

将原非泛型接口改为带类型约束的泛型接口,约束类型必须是NPCController或其派生类:

namespace Myproject.NPC
{
    public interface INPCState<T> where T : NPCController
    {
        void Enter(T npc);
        void Execute(T npc);
        void Exit(T npc);
    }
}

2. 调整StateManager支持泛型状态

修改状态管理器,使其适配泛型状态类,同时保留对基类逻辑的复用:

namespace Myproject.NPC
{
    public class StateManager<T> where T : NPCController
    {
        private INPCState<T> _currentState;
        private readonly T _npc;

        public StateManager(T npc)
        {
            _npc = npc;
        }

        public void ChangeState(INPCState<T> newState)
        {
            _currentState?.Exit(_npc);
            _currentState = newState;
            _currentState.Enter(_npc);
        }

        public void UpdateState()
        {
            _currentState?.Execute(_npc);
        }
    }
}

3. 改造NPCController基类

让基类使用泛型状态管理器,派生类只需指定自身作为泛型参数:

namespace Myproject.NPC
{
    public class NPCController<T> : MonoBehaviour where T : NPCController<T>
    {
        protected StateManager<T> _stateManager;
        // 保留原有公共组件逻辑
        public NavMeshAgent NavMeshAgent;
        public Animator Animator;

        protected virtual void Awake()
        {
            _stateManager = new StateManager<T>((T)this);
        }
    }

    // 可选:保留非泛型基类兼容旧逻辑
    public class NPCController : MonoBehaviour { }
}

4. 适配NPCGuest相关类

现在派生类和状态类可以直接访问专属方法,无需类型转换:

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

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

        public void Execute(NPCGuestController npc)
        {
            // 实现Guest专属自由行走逻辑
        }

        public void Exit(NPCGuestController npc)
        {
            // 实现Guest状态退出逻辑
        }
    }
}

5. NPCWorker类改造同理

using Myproject.NPC;
namespace Myproject.NPCWorker
{
    public class NPCWorkerController : NPCController<NPCWorkerController>
    {
        public void WorkerSpecificMethod()
        {
            Debug.Log("specific method for Worker");
        }
    }

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

        public void Execute(NPCWorkerController npc)
        {
            // 实现Worker专属自由行走逻辑
        }

        public void Exit(NPCWorkerController npc)
        {
            // 实现Worker状态退出逻辑
        }
    }
}

临时替代方案:安全类型转换(不推荐)

如果不想修改基类架构,也可以在状态类中做类型校验转换,但这种方式易引发空引用风险,代码扩展性差:

public void Enter(NPCController npc)
{
    if (npc is NPCGuestController guestNpc)
    {
        guestNpc.GuestSpecificMethod();
    }
    else
    {
        Debug.LogWarning("Invalid NPC type for Guest state");
    }
}

内容的提问来源于stack exchange,提问作者anderlaini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 05:43:10