Unity中如何通过ObstacleController父类引用调用子类UpdateData方法?
解决方案:统一敌人生成系统的Controller数据更新
针对父类无法统一调用子类UpdateData、嵌套泛型导致代码冗余的问题,以下是几种适配Unity安卓游戏场景的实用方案:
1. 抽象统一的ControllerData基类+非泛型入口方法
核心思路是将所有敌人的数据类抽象到一个基类,给父类控制器添加非泛型的UpdateData入口,内部完成类型校验与转换,既保留子类的强类型数据处理,又支持父类统一调用。
步骤代码:
1.1 定义统一的数据基类
public abstract class BaseObstacleData { // 所有敌人共有的基础字段,比如生成权重、ID等 public int ObstacleId; public float SpawnPriority; } // EnemyA专属数据 public class EnemyAData : BaseObstacleData { public int AttackDamage; public float MoveSpeed; } // EnemyB专属数据 public class EnemyBData : BaseObstacleData { public float ExplosionRadius; public int MaxHealth; }
1.2 重构控制器抽象层
调整接口与抽象父类,添加非泛型统一调用入口:
// 非泛型接口,用于父类统一调用 public interface IObstacleController { void UpdateData(BaseObstacleData data); } // 泛型抽象父类,保留子类强类型处理 public abstract class ObstacleController<TData> : IObstacleController where TData : BaseObstacleData { // 子类实现强类型数据更新 public abstract void UpdateData(TData data); // 非泛型入口,内部完成类型转换 public void UpdateData(BaseObstacleData data) { if (data is TData typedData) { UpdateData(typedData); } else { Debug.LogError($"数据类型不匹配:{GetType().Name} 无法处理 {data.GetType().Name}"); } } } // EnemyA控制器子类 public class EnemyAController : ObstacleController<EnemyAData> { public override void UpdateData(EnemyAData data) { // 强类型处理EnemyA数据更新 Debug.Log($"更新EnemyA:伤害={data.AttackDamage},移速={data.MoveSpeed}"); } }
1.3 统一调用示例
// 用非泛型接口存储所有控制器 List<IObstacleController> _allControllers = new List<IObstacleController>(); _allControllers.Add(new EnemyAController()); _allControllers.Add(new EnemyBController()); // 遍历统一执行数据更新 foreach (var controller in _allControllers) { BaseObstacleData enemyData = GetRandomEnemyData(); // 自定义获取随机敌人数据的方法 controller.UpdateData(enemyData); }
2. 工厂模式优化控制器创建与数据绑定
如果需要批量生成控制器并绑定数据,用工厂模式封装类型映射逻辑,避免手动处理类型匹配的重复代码:
public static class ObstacleControllerFactory { // 缓存数据类型与控制器创建器的映射 private static readonly Dictionary<Type, Func<IObstacleController>> _controllerMap = new(); static ObstacleControllerFactory() { // 注册所有敌人数据与对应控制器的创建逻辑 _controllerMap.Add(typeof(EnemyAData), () => new EnemyAController()); _controllerMap.Add(typeof(EnemyBData), () => new EnemyBController()); } // 根据数据实例创建并初始化控制器 public static IObstacleController CreateAndInitController(BaseObstacleData data) { if (_controllerMap.TryGetValue(data.GetType(), out var creator)) { var controller = creator(); controller.UpdateData(data); return controller; } Debug.LogError($"未找到对应的数据类型:{data.GetType().Name}"); return null; } }
使用示例:
var enemyAData = new EnemyAData { AttackDamage = 10, MoveSpeed = 3f }; var enemyAController = ObstacleControllerFactory.CreateAndInitController(enemyAData);
3. 简化泛型接口(可选)
如果原有的IObstacleController带5个泛型参数过于复杂,考虑将部分泛型参数合并到BaseObstacleData中,或者用组合类代替多层泛型,减少嵌套复杂度。比如将敌人的行为配置、资源引用等合并到数据基类的子类中,避免接口泛型参数过多导致的维护问题。
内容的提问来源于stack exchange,提问作者Džoni
相关产品推荐
相关产品推荐

