我開始在 Unity 中使用 PlayerPrefs,一切運行良好。然后我嘗試構建游戲以將其發送給朋友。但是當我再次測驗它時(構建版本)。PlayerPrefs 停止作業。只是,就像他們從未存在過一樣。場景之間的保存不起作用。回到 Unity 編輯器,一切正常。但為什么?
希望有人可以幫助我,這樣我就可以在編輯器之外玩我的游戲??。
親切的問候。
好的,重新啟動了 Unity,現在我收到一個錯誤,Unity 內外的游戲故障現在相同。但是為什么(以及為什么 tf 在我重新啟動并且 Unity 識別出錯誤之前它就像一個魅力一樣作業)?請幫忙。
FormatException:輸入字串的格式不正確。System.Number.StringToNumber (System.String str, System.Globalization.NumberStyles options, System.Number NumberBuffer& number, System.Globalization.NumberFormatInfo info, System.Boolean parseDecimal) (at <695d1cc93cca45069c528c15c9fdd749>:0) System.Number.ParseInt32 (System.String s, System.Globalization.NumberStyles 樣式, System.Globalization.NumberFormatInfo 資訊) (at <695d1cc93cca45069c528c15c9fdd749>:0) System.Int32.Parse (System.String s) (at <695d1cc93cca45069c528c15c9fdd749>:0) UI_Inventory.RefreshInventoryItems () (在 Assets/SinglePlayer/Scripts/Inventory/UI_Inventory.cs:123) UI_Inventory.Start () (在 Assets/SinglePlayer/Scripts/Inventory/UI_Inventory.cs:24)
這是我保存的腳本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using CodeMonkey.Utils;
using TMPro;
public class UI_Inventory : MonoBehaviour
{
private Inventory inventory;
private Transform itemSlotContainer;
private Transform itemSlotTemplate;
private PlayerController player;
private void Awake() {
itemSlotContainer = transform.Find("itemSlotContainer");
itemSlotTemplate = itemSlotContainer.Find("itemSlotTemplate");
}
private void Start()
{
RefreshInventoryItemsNewWorld();
}
public void SetPlayer(PlayerController player)
{
this.player = player;
}
public void SetInventory(Inventory inventory)
{
this.inventory = inventory;
inventory.OnItemListChanged = Inventory_OnItemListChanged;
RefreshInventoryItems();
}
private void Inventory_OnItemListChanged(object sender, System.EventArgs e)
{
RefreshInventoryItems();
}
private void RefreshInventoryItems()
{
foreach (Transform child in itemSlotContainer)
{
if (child == itemSlotTemplate) continue;
Destroy(child.gameObject);
}
int x = 0;
int y = 0;
float itemSlotCellSize = 90f;
foreach (Item item in inventory.GetItemList())
{
RectTransform itemSlotRectTransform = Instantiate(itemSlotTemplate, itemSlotContainer).GetComponent<RectTransform>();
itemSlotRectTransform.gameObject.SetActive(true);
itemSlotRectTransform.GetComponent<Button_UI>().ClickFunc = () =>
{
inventory.UseItem(item);
};
itemSlotRectTransform.GetComponent<Button_UI>().MouseRightClickFunc = () =>
{
Item duplicateItem = new Item { itemType = item.itemType, amount = item.amount };
inventory.RemoveItem(item);
ItemWorld.DropItem(player.GetPosition(), duplicateItem);
};
itemSlotRectTransform.anchoredPosition = new Vector2(x * itemSlotCellSize, y * itemSlotCellSize);
Image image = itemSlotRectTransform.Find("image").GetComponent<Image>();
image.sprite = item.GetSprite();
TextMeshProUGUI uiText = itemSlotRectTransform.Find("text").GetComponent<TextMeshProUGUI>();
if (item.amount > 1)
{
uiText.SetText(item.amount.ToString());
// sets player pref
PlayerPrefs.SetString(item.itemType.ToString(), item.amount.ToString());
PlayerPrefs.Save();
} else {
uiText.SetText("");
}
x ;
if (x > 4) {
x = 0;
y ;
}
}
}
private void RefreshInventoryItemsNewWorld()
{
foreach (Transform child in itemSlotContainer)
{
if (child == itemSlotTemplate) continue;
Destroy(child.gameObject);
}
int x = 0;
int y = 0;
float itemSlotCellSize = 90f;
foreach (Item item in inventory.GetItemList())
{
item.amount = int.Parse(PlayerPrefs.GetString(item.itemType.ToString()));
RectTransform itemSlotRectTransform = Instantiate(itemSlotTemplate, itemSlotContainer).GetComponent<RectTransform>();
itemSlotRectTransform.gameObject.SetActive(true);
itemSlotRectTransform.GetComponent<Button_UI>().ClickFunc = () =>
{
inventory.UseItem(item);
};
itemSlotRectTransform.GetComponent<Button_UI>().MouseRightClickFunc = () =>
{
Item duplicateItem = new Item { itemType = item.itemType, amount = item.amount };
inventory.RemoveItem(item);
ItemWorld.DropItem(player.GetPosition(), duplicateItem);
};
itemSlotRectTransform.anchoredPosition = new Vector2(x * itemSlotCellSize, y * itemSlotCellSize);
Image image = itemSlotRectTransform.Find("image").GetComponent<Image>();
image.sprite = item.GetSprite();
TextMeshProUGUI uiText = itemSlotRectTransform.Find("text").GetComponent<TextMeshProUGUI>();
if (item.amount > 1)
{
uiText.SetText(item.amount.ToString());
// sets player pref
PlayerPrefs.SetString(item.itemType.ToString(), item.amount.ToString());
PlayerPrefs.Save();
} else {
uiText.SetText("");
}
x ;
if (x > 4) {
x = 0;
y ;
}
}
}
}
uj5u.com熱心網友回復:
只是,就像他們從未存在過一樣。
好吧,他們沒有。PlayerPrefs 是特定于設備的,并且在編輯器和專案的構建版本之間也以不同的方式存盤。
你在做
item.amount = int.Parse(PlayerPrefs.GetString(item.itemType.ToString()));
但是,如果它是一個新版本/PlayerPrefs
無論出于何種原因您都不存在,那么
PlayerPrefs.GetString(item.itemType.ToString())
將回傳""
這使得
int.Parse("")
拋出例外。
一般來說,你寧愿
要么提供一個后備值
PlayerPrefs.GetString(item.itemType.ToString(), "0")
這意味著如果相應的鍵不存在,
PlayerPrefs
它將"0"
用作后備而不是回傳默認值""
使用
int.TryParse
而不是獲得例外,但使用后備值,例如if(!int.TryParse(PlayerPrefs.GetString(item.itemType.ToString()), out item.amount) { item.amount = 0; }
將以上兩者結合起來只是為了100%確定
或者實際上寧愿使用PlayerPrefs.SetInt
andPlayerPrefs.GetInt
開始,以便完全不必擔心上述問題。!
無論如何,它默認為0
并確保您在那里存盤和檢索的內容已經是int
.
item.amount = PlayerPrefs.GetInt(item.itemType.ToString());
當然也相應地做
PlayerPrefs.SetInt(item.itemType.ToString(), item.amount);
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/524057.html
標籤:C#unity3d