有没有更好的方法来编写我的物品/武器解锁系统?

时间:2019-05-27 11:38:30

标签: c# unity3d

我真的很想通过一个游戏商店来创建武器/物品解锁系统。玩家只能选择已解锁或购买索引的武器。

我已经花了两天时间来实现这一目标的最佳方法,但我仍然找不到解决方案。

目前这是我所拥有的:

我有一个WeaponUnlock脚本可以处理dictionary的武器,还有另一个WeaponSwitcher脚本可以访问该脚本中的vales以检查其是否已解锁。

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并为每种武器设置一个值,但这也不是很理想,并且为了避免每次有人打开我的游戏时重置它,我都必须执行{{1 }}。也不切实际。

必须有一种更好的方法。有趣的是,我无法在网上找到很多帮助,也不知道每个人如何解决这个问题。

谢谢

2 个答案:

答案 0 :(得分:1)

我最近有一个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上即可发挥作用。

答案 1 :(得分:1)

您创建的类不是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) 
    {
        ...
    }
}

为了方便起见,我也建议不要使用静态类。仅当您不想更改对象的状态或不需要创建对象的实例时,才应使用静态。