【问题标题】:Saving PlayerPrefs for multiple instances为多个实例保存 PlayerPrefs
【发布时间】:2015-04-25 06:23:57
【问题描述】:

我设置了一个简单的商店,当玩家点击“购买”一个角色时,该物品会解锁并保持解锁状态。这是在一个场景中(商店场景)。

我有第二个场景,角色根据此次购买解锁,供玩家选择(角色场景)。

我将脚本放置在每个场景的空游戏对象上。只购买一个角色时效果很好。但是如何为多个字符复制它。

我可以将脚本放在单个按钮上,并将相应的游戏对象放在检查器下,但如果我有 100 个字符,这将不切实际。

请建议我如何在多个实例中进行这项工作。考虑标记,这似乎也不可行。如果有更好的方法,我愿意接受建议。谢谢。

//Class controlling Shop Scene via an empty Gameobject
 public class ShopManager : MonoBehaviour 
 {
     private bool unlocked;

     public GameObject greyImg;

     void Start()
     {
         unlocked = PlayerPrefs.GetInt("unlocked") == 1;
         greyImg.SetActive(unlocked);
     }

     public void Buy()
     {
         unlocked = true;
         PlayerPrefs.SetInt("unlocked", 1);
         PlayerPrefs.Save();
         greyImg.SetActive(true);
     }
 }

这就是统一设置在商店场景中的外观。如果该项目已经购买,则灰色图像设置为活动状态,因此不允许用户再单击绿色购买按钮。

角色解锁/购买时

 //Class controlling Character select scene via an empty Gameobject
 public class CharacterManager : MonoBehaviour 
 {
     private bool unlocked;
     public GameObject greySelect;

     void Start()
     {
         unlocked = PlayerPrefs.GetInt("unlocked") == 1;
     }

     void Update()
     {
         if (unlocked)
         {
             greySelect.SetActive(false);
         }
     }
 }

这就是 Unity 设置寻找角色选择场景的方式。如果角色已解锁,则灰色选择图像设置为非活动状态,橙色选择按钮将可见,从而允许选择角色。

角色解锁时

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    可能有很多方法可以解决这个问题。这是一个;

    每个角色都需要单独的玩家偏好条目。因此,您需要一种很好的方法来跟踪您拥有的角色及其解锁状态。与其在播放器首选项中保存“解锁”,为什么不创建一个包含解锁信息的类?

    class UnlockedCharacters
    {
        bool characterAUnlocked = false;
        bool characterBUnlocked = false;
        bool characterCUnlocked = true;
    }
    

    然后您可以序列化整个类并将整个类保存在播放器首选项中。然后,当你加载你的游戏时,你可以从玩家偏好中加载这个类来填充你的角色信息。这样,数据就得到了管理,并且在保存的状态下保持一致。

    您可以更进一步,将与您的角色相关的所有内容保存在 Dictionary 中,其中您的 int 是一个引用角色的枚举,而 bool 是它的解锁状态。然后,您可以使用播放器首选项再次保存/加载此字典。

    在类中,您可以使用通用游戏对象脚本调用的辅助方法来保持良好和封装。

    这样,您处理特定字符的单个游戏对象可以保存对此枚举的引用,您可以使用通用脚本根据您的枚举字段设置/修改数据内容,然后您可以通过检查器或在对象的初始化代码。

    编辑下面的评论 - 一个例子:

    您的通用角色控制器将处理单个对象,并且通过更改您的 CHAR_TYPE 相同的脚本将用于解锁多个角色。

    class CharacterManager
    {
        public enum CHAR_TYPE = { characterA, characterB, characterC }
        private Dictionary<CHAR_TYPE, bool> characterUnlockState;
    
        void Start()
        {
            // Seeding with some data for example purposes
            characterUnlockState = new Dictionary<CHAR_TYPE, bool>();
            characterUnlockState.Add(CHAR_TYPE.characterA, false);
            characterUnlockState.Add(CHAR_TYPE.characterB, false);
            characterUnlockState.Add(CHAR_TYPE.characterC, true);
        }
    
        public bool IsCharacterUnlocked(CHAR_TYPE character)
        {
            if (characterUnlockState.Contains(character)) return characterUnlockState[character];
    
            return false;
        }
    
        public void UnlockCharacter(CHAR_TYPE character)
        {
            if (characterUnlockState.Contains(character)) characterUnlockState[character] = true;
        }
    }
    
    class GenericCharacterController
    {
        public CHAR_TYPE character;
        public CharacterManager manager;
    
        public void UnlockButtonPressed()
        {
            manager.UnlockCharacter(character);
        }
    
    }
    

    【讨论】:

    • 各个按钮必须有自己的公共方法,在点击时激活。目前所有人都将使用相同的方法,因此最终会在解锁 1 时同时激活所有角色。除了一个单独的类来保存信息之外,我将如何处理这个。您的意思是 10 种不同的方法,每种方法都执行不同的动作来激活各个角色? (我假设这不是你的意思,但我无法理解我将如何使 1 种方法对不同的角色解锁有不同的工作方式)。能否举个例子。 Tnks。
    【解决方案2】:

    有很多方法可以解决这个问题。您将需要为商店中的每件商品提供某种 ID。因此,我会制作一个 StoreItem 脚本,将其放置在每件待售物品上。 StoreItem 脚本至少需要一个 ItemID 属性。然后您的 StoreManager 可以像这样检查它是否已解锁:

    PlayerPrefs.GetInt(selectedStoreItem.ItemID + "_unlocked");
    

    此外,虽然这种方法可行,但不推荐。 playerprefs 有可能被游戏之外的用户操作。所以他们可能会给自己免费物品。我不知道这对你有多重要。更好的方法是将此信息存储在某处的服务器上,并让游戏与之同步以确定玩家拥有哪些物品。

    【讨论】:

    • 假设我有 10 个字符,所以复制 10 个仅处理 Id 的项目脚本,并为商店提供一个处理其余部分的主脚本?因为我知道我最终仍然必须通过将每个角色声明为公共并单独分配来处理灰色/橙色绿色/灰色按钮的每个角色的开/关。你能给我一个粗略的例子吗?我无法理解它。 Tnks。
    • 您将创建一个 StoreItem 模板对象。模板对象将具有与商店项目(橙色按钮等)关联的所有 UI 元素的公共属性。在为模板构建预制件后,您将向商店经理添加模板属性并将刚刚制作的预制件与其关联。然后,您可以在运行时动态实例化所有商店项目,并可能在每个 StoreItem 上调用一个名为 SetCharacter(characterName); 的方法。在该方法中,您可以检查 playerprefs 中传入的名称,然后更改该项目的 UI 元素。
    • 您可以通过循环遍历您的角色列表并为每个角色创建一个新的 StoreItem 对象来动态完成这一切。然后,您只需将您的角色 ID 传递给 StoreItem,它就会根据它确定的所有权状态更新自己的 UI。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多