У меня есть эти классы в игре (упрощенно):
public class GameUnit
{
public enum UnitType
{
FighterUnit,
MageUnit,
Count,
}
public UnitType type;
public virtual void OnUnitSelected()
{
HighlightUnit();
}
}
public class FighterUnit : GameUnit
{
public FighterUnit()
{
type = UnitType.FighterUnit;
}
public override void OnUnitSelected()
{
PlayFighterSound();
base.OnUnitSelected();
}
public void Punch()
{
PunchInfrontOfMe();
}
}
public class MageUnit : GameUnit
{
public MageUnit()
{
type = UnitType.MageUnit;
}
public override void OnUnitSelected()
{
PlayMageSound();
base.OnUnitSelected();
}
public void CastSpell()
{
CreateSpellAtPosition();
}
}
Я сохраняю эти юниты в списке и могу создавать их и щелкать по ним следующим образом:
public class GameUnitController
{
public List<GameUnit> units;
public void SpawnUnit(GameUnit.UnitType type)
{
switch (type)
{
case GameUnit.UnitType.FighterUnit:
FighterUnit newFighterUnit = new FighterUnit();
units.Add(newFighterUnit);
break;
case GameUnit.UnitType.MageUnit:
MageUnit newMageUnit = new MageUnit();
units.Add(newMageUnit);
break;
}
}
public void UnitClicked(GameUnit unit)
{
unit.OnUnitSelected();
}
}
Когда мне нужно, я могу преобразовать их в их дочерний класс, когда это необходимо для спецификации c logi c, например:
public void PerformAction(GameUnit unit)
{
switch (unit.type)
{
case GameUnit.UnitType.FighterUnit:
((FighterUnit)unit).Punch();
break;
case GameUnit.UnitType.MageUnit:
((MageUnit)unit).CastSpell();
break;
}
}
Однако моя база кода уже начинает доходить до точка, где я добавляю множество операторов switch для типов классов, и мне нужен более простой способ обработки более общих c вызовов функций (см. проблему OnUnitSelected).
Текущая проблема с OnUnitSelected, это то, как это написано здесь, он вызывает OnUnitSelected родительского класса только тогда, когда я хочу, чтобы он go проходил через все из них.
Есть ли хороший способ использовать свое перечисление для создания чего-то общего c в базовом классе, который мог бы вернуть его как правильный класс и не должен go через множество операторов switch, которые будут становиться все больше и больше по мере добавления дополнительных единиц.
Любой совет - это много приблизительно ecated.
Спасибо!
РЕДАКТИРОВАТЬ: Решение, которое я выбрал в конце:
Отредактировал GameUnit как таковой:
public class GameUnit
{
public enum UnitType
{
FighterUnit,
MageUnit,
Count,
}
public UnitType type;
public virtual void OnUnitSelected()
{
HighlightUnit();
}
public virtual void RunMethod(Action method)
{
method();
}
public void DoAsChild(Action method)
{
switch (type)
{
case UnitType.FighterUnit:
FighterUnit fighterUnit = (FighterUnit)this;
fighterUnit.RunMethod(method);
break;
case UnitType.MageUnit:
MageUnit mageUnit = (MageUnit)this;
mageUnit.RunMethod(method);
break;
}
}
}
И отредактировал производные классы для переопределения метода:
public class FighterUnit : GameUnit
{
public FighterUnit()
{
type = UnitType.FighterUnit;
}
public override void OnUnitSelected()
{
PlayFighterSound();
base.OnUnitSelected();
}
public void Punch()
{
PunchInfrontOfMe();
}
public override void RunMethod(Action method)
{
method();
}
}
public class MageUnit : GameUnit
{
public MageUnit()
{
type = UnitType.MageUnit;
}
public override void OnUnitSelected()
{
PlayMageSound();
base.OnUnitSelected();
}
public void CastSpell()
{
CreateSpellAtPosition();
}
public override void RunMethod(Action method)
{
method();
}
}
Итак, теперь, когда у меня есть переопределяемая функция, такая как OnUnitSelected, я могу вызвать родительский элемент, который, в свою очередь, приведет себя к правильному дочернему элементу и вызовет метод из детский класс:
public void UnitClicked(GameUnit unit)
{
unit.DoAsChild(unit.OnUnitSelected);
}