Выполнение различных задач в зависимости от типа данных - PullRequest
0 голосов
/ 26 апреля 2020

Я пытаюсь создать игру с системой оружия, в которой будут такие типы оружия, как ближний бой, огнестрельное оружие и так далее. Я создал классы для данных, а затем я буду ссылаться на эти классы данных в другом классе и выполнять задачи (Fire, Reload и т. Д.) Соответственно.

public abstract class WeaponData {
      public int damage;

      public abstract void Fire();
}

Обратите внимание на абстрактное существо, я использую этот класс как база и для обычных вещей, которые будут иметь каждое оружие. Затем у нас будут классы для каждого типа оружия, которое наследует этот класс выше:

public class FirearmData : WeaponData {
     public SupplyData ammoTypeData;
     public int magazineSize;
     public AnimationClip reloadAnimation;

     public override void Fire() {
           // blablabla...
     }
}

Этот класс переопределяет метод Fire (), а также имеет некоторые другие отдельные поля. Вот еще один класс типа оружия:

public class MeleeWeaponData : WeaponData {
     public AnimationClip swingAnimation;

     public override void Fire() {
           // blablabla...
     }
}

Пока мне удалось создать эти классы, но это не значит, что я не буду создавать больше таких классов в будущем, я остановил их здесь потому что я понял, что эта система не будет работать ...

Так что у меня тоже есть класс Weapon, на который я буду ссылаться на WeaponData, и его методы будут выполнять разные задачи в соответствии с данными.

public class Weapon {
     public WeaponData data;

     void Fire() {
         data.Fire();
     }

     void Reload() {
        // the problem is here;
     }
}

Итак, проблема здесь, я включаю все возможные методы, которые понадобятся данным в этом классе, но это не элегантно, если вы спросите меня, потому что WeaponData будет MeleeWeaponData, и в этом случае это будет не нужен метод Reload () или целочисленное поле журнала. Я все еще могу заставить его работать, выполняя некоторые переключения, чтобы проверить тип данных. Но когда бы я ни создавал больше типов данных, мне приходилось бы go здесь и каждый раз добавлять еще один оператор к коммутатору. И я не хочу этого.

Поэтому я хотел бы посоветоваться с Дженерикс для этого, например:

public class Weapon<T> where T : WeaponData {

}

Но это не позволило бы мне получить поля дочерних классов WeaponData, как вы сказали мне ...

Ребята, можете ли вы найти систему, которая будет работать в моем случае? Я делаю свою игру на Unity и использую ScriptableObjects для данных, если это что-то значит.

Ответы [ 2 ]

0 голосов
/ 26 апреля 2020

Я бы предложил вам использовать интерфейс вместо: IFireable, IReloadable, например.

interface IWeapon
{
    void Fire();
}

interface IReloadable
{
    void Reload();
}

Реализация ваших WeaponData ase

class WeaponData: IWeapon
{
    public int damage;
    public abstract Fire();
}

Для огнестрельного оружия, производных от WeaponData и реализации IReloadable.

public class FirearmData : WeaponData, IReloadable
{
     public SupplyData ammoTypeData;
     public int magazineSize;
     public AnimationClip reloadAnimation;

     public override void Fire() 
     {
           // blablabla...
     }
     public void Reload() 
     {
           // Reload
     }
}

Fire MaleeData, производные только от WeaponData.

Чтобы в вашем классе оружия проверять тип оружия, если он поддерживает IReloadable, выполнить перезагрузку, в противном случае , ничего не делать.

public class Weapon {
     public WeaponData data;

     void Fire() {
         data.Fire();
     }

     void Reload() {
        if(data is IReloadable reloadableData)
        {
             reloadableData.Reload();
        }
        else
            // Do nothing.
     }
}


0 голосов
/ 26 апреля 2020

Простое решение будет выглядеть примерно так:

public abstract class WeaponData
{
    public int damage;

    public abstract void Fire();

    public virtual void Reload()
    {
        return;
    }
}

Затем переопределите Reload (), где это необходимо:

public class FirearmData : WeaponData {
     public SupplyData ammoTypeData;
     public int magazineSize;
     public AnimationClip reloadAnimation;

     public override void Fire() {
           // blablabla...
     }

     public override void Reload() {
           // blablabla...
     }
}

И игнорируйте его там, где его нет:

public class MeleeWeaponData : WeaponData {
     public AnimationClip swingAnimation;

     public override void Fire() {
           // blablabla...
     }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...