Есть ли лучший способ написать мою систему разблокировки предметов / оружия? - PullRequest
0 голосов
/ 27 мая 2019

Я действительно борюсь с созданием системы разблокировки оружия / предметов через игровой магазин. Игрок должен иметь возможность выбирать оружие только по индексам, которые были разблокированы или куплены.

Я потратил два дня на лучший способ добиться этого, и я все еще не нахожу подходящего решения.

В настоящее время это то, что у меня есть:

У меня есть сценарий WeaponUnlock, который обрабатывает dictionary оружия, и другой сценарий WeaponSwitcher, который обращается к вейлам из этого сценария, чтобы проверить, разблокирован он или нет.

public class WeaponUnlockSystem : MonoBehaviour
{

    private Dictionary<string, bool> weaponUnlockState;    

    void Start()
    {
        // Seeding with some data for example purposes
        weaponUnlockState = new Dictionary<string, bool>();
        weaponUnlockState.Add("Shotgun", true);              
        weaponUnlockState.Add("Rifle", true);
        weaponUnlockState.Add("FireballGun", false);
        weaponUnlockState.Add("LaserGun", false);
        weaponUnlockState.Add("FlamethrowerGun", false);
        weaponUnlockState.Add("SuperGun", false);
    }

    public bool IsWeaponUnlocked(string weapon_)
    {
        if (weaponUnlockState.ContainsKey(weapon_))
            return weaponUnlockState[weapon_];              // this will return either true or false if the weapon is unlocked or not
        else
            return false;
    }

    public void UnlockWeapon(string weapon_)            //this will be called by the button..
    {
        if (weaponUnlockState.ContainsKey(weapon_))
            weaponUnlockState[weapon_] = true;
    }
}

WeaponSwitcher получает имя оружия от вложенных детей при каждом нажатии кнопки nextWeapon:

weaponName = this.gameObject.transform.GetChild(weaponIdx).name.ToString();     //get the name of the child at current index

        if (weaponUnlock.IsWeaponUnlocked(weaponName))      //ask weaponUnlockSystem if this name weapon is unlocked or not, only enable the transform if true is returned
            selectedWeapon = weaponIdx;

Это ...... работает ..... но я знаю, что это не практично. Поскольку скрипт находится на игровом объекте и при каждом его вызове вызывается Start(), который сбрасывает все разблокированные значения. Также я должен сделать это постоянным через DontDestroyOnLOad() через сцены?

Я могу использовать PlayerPrefs и установить значение для каждого оружия, но это также не идеально, а также чтобы избежать его сброса каждый раз, когда кто-то открывает мою игру, я должен был бы выполнить проверки PlayerPrefs.HasKey() для каждого оружие. Также не практично.

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

Спасибо

Ответы [ 2 ]

1 голос
/ 28 мая 2019

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

Поскольку я не знаю, как выглядит ваша архитектура остальной части кода, я пойду дальше и предположу, чтоу вас какая-то постоянная модель игрока.

Вы можете просто добавить WeaponUnlockSystem к вашему игроку GameObject и управлять разблокировками оттуда.Для меня это было бы наиболее разумно, так как игрок, вероятно, тот, кто разблокирует оружие, поэтому к нему должна быть прикреплена система WeaponUnlockSystem.

Вот действительно простой пример кода:

public class WeaponUnlockSystem {

    private Dictionary<string, bool> weaponUnlockState;

    public WeaponUnlockSystem() 
    {
        weaponUnlockState = new Dictionary<string, bool>();
        weaponUnlockState.Add("Shotgun", true);              
        weaponUnlockState.Add("Rifle", true);
        weaponUnlockState.Add("FireballGun", false);
        weaponUnlockState.Add("LaserGun", false);
        weaponUnlockState.Add("FlamethrowerGun", false);
        weaponUnlockState.Add("SuperGun", false);
    }

    public bool IsWeaponUnlocked(string weapon)
    {
        if (weaponUnlockState.ContainsKey(weapon))
            return weaponUnlockState[weapon];         
        else
            return false;
    }

    public void UnlockWeapon(string weapon) 
    {
        if (weaponUnlockState.ContainsKey(weapon))
            weaponUnlockState[weapon] = true;
    }
}

public class Player : MonoBehaviour {

    private WeaponUnlockSystem weaponUnlockSystem;

    void Start()
    {
        weaponUnlockSystem = new WeaponUnlockSystem();
        ...
    }

    public void NextWeapon(string weapon) 
    {
        ...
    }
}

Я бы также посоветовал не использовать статический класс для удобства.Статика должна использоваться только, если вы не хотите изменять состояние объекта или вам не нужно создавать экземпляр объекта.

1 голос
/ 28 мая 2019

Недавно у меня был проект Unity, в котором нам нужно было хранить некоторые простые данные между сценами и манипулировать ими.Мы только что создали статический класс, который не расширяет монобихи поведение.Кроме того, если вы ищете эффективность, почему бы просто не поддерживать массив разблокированного оружия?

В общем, почему бы не попробовать что-то вроде этого:

public static class WeaponUnlockSystem
{

    private static string[] unlockedWeapons = InitialWeapons();

    private static string[] InitialWeapons(){
        string w = new string[]{
            "Shotgun",
            "Rifle",
        }
    }

    public static bool IsWeaponUnlocked(string name)
    {
        int i = 0;
        bool found = false;
        while(i < unlockedWeapons.Length && !found){
            if (string.Equals(unlockedWeapons[i],name)){
                found = true;
            }
            i++;
        }
        return found;
    }

    public static void UnlockWeapon(string name)
    {
        string[] weapons = new string[unlockedWeapons.Length+1];
        int i = 0;
        bool found = false;
        while(i < unlockedWeapons.Length && !found){
            if (string.Equals(unlockedWeapons[i],name)){
                found = true;
            } else {
                weapons[i] = unlockedWeapons[i];
            }
        }
        if(!found){
            weapons[unlockedWeapons.Length] = name;
            unlockedWeapons = weapons;
        }
}

Я неработает моя c # IDE, поэтому я прошу прощения, если есть какие-либо синтаксические ошибки.Он должен быть эффективным, простым и - поскольку он статичен - вам не нужно помещать его в пустой GameObject, чтобы он работал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...