问题描述
您好,我是游戏开发专业的学生,正在制作一款游戏,玩家可以在每张地图上获取一定数量的硬币,每张地图都有不同类型的硬币数据,例如高分。但它只保存 1 个玩家偏好设置。为什么会这样?
这是我的场景管理脚本;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;
public class changeScene : MonoBehavIoUr
{
public TextMeshProUGUI desertCoinAmount;
public TextMeshProUGUI plainsCoinAmount;
void Update()
{
desertCoinAmount.text = PlayerPrefs.GetInt("DesertCoins").ToString();
plainsCoinAmount.text = PlayerPrefs.GetInt("PlainsCoins").ToString();
}
public void mainMenu()
{
SceneManager.LoadScene("mainMenu");
PlayerPrefs.Save();
}
public void desertLevel()
{
SceneManager.LoadScene("ancientDesertLEVEL");
Time.timeScale = 1f;
PlayerPrefs.Save();
}
public void plainsLevel()
{
SceneManager.LoadScene("Plain Biome");
Time.timeScale = 1f;
PlayerPrefs.Save();
}
public void jungleLevel()
{
SceneManager.LoadScene("Jungle Biome");
Time.timeScale = 1f;
}
}
这是我的 PlayerController;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class PlayerController : MonoBehavIoUr
{
public GameObject winPopup,losePopup;
public GameObject heart1,heart2,heart3;
public float gravityScale = 10f;
private Rigidbody rb;
public TextMeshProUGUI coinText;
public AudioSource coinSound;
int coin_sumDesert;
int coin_sumPlains;
int life_sum = 3;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
GetComponent<Rigidbody>().AddForce(Physics.gravity * gravityScale,ForceMode.Force);
}
void Update()
{
PlayerPrefs.SetInt("DesertCoins",coin_sumDesert);
PlayerPrefs.SetInt("PlainsCoins",coin_sumPlains);
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Coins")
{
coin_sumDesert++;
coinText.text = coin_sumDesert.ToString();
Destroy(other.gameObject);
coinSound.Play();
}
if (other.gameObject.tag == "PlainsCoins")
{
coin_sumPlains++;
coinText.text = coin_sumPlains.ToString();
Destroy(other.gameObject);
coinSound.Play();
}
if (other.gameObject.tag == "finishLine")
{
winPopup.SetActive(true);
}
if (other.gameObject.tag == "obstacles")
{
Debug.Log("Collide Detected");
life_sum--;
if (life_sum == 2)
{
heart1.SetActive(false);
}
else if (life_sum == 1)
{
heart2.SetActive(false);
}
else if (life_sum == 0)
{
heart3.SetActive(false);
losePopup.SetActive(true);
Time.timeScale = 0.0f;
}
}
}
}
感谢您的回复(这是我第一次使用 StackOverflow xD)
解决方法
如果您有多个 PlayerController
,那么显然它们会写入相同的 PlayerPrefs
键。
每当您保存玩家的数据时,请确保区分它们,例如分数 1、分数 2 等
这是实现它的许多其他方法之一:
播放器,非常简单,将索引附加到播放器首选项以区分多个:
public sealed class Player : MonoBehaviour
{
private const string ChocolateBarsKey = "ChocolateBars";
[SerializeField]
[HideInInspector]
private int Index;
private int ChocolateBars
{
get => GetInt(ChocolateBarsKey);
set => SetInt(ChocolateBarsKey,value);
}
private int GetInt([NotNull] string key,int defaultValue = default)
{
if (key == null)
throw new ArgumentNullException(nameof(key));
return PlayerPrefs.GetInt($"{key}{Index}",defaultValue);
}
private void SetInt([NotNull] string key,int value)
{
PlayerPrefs.SetInt($"{key}{Index}",value);
}
[NotNull]
internal static Player Create([NotNull] GameObject parent,int index)
{
if (parent == null)
throw new ArgumentNullException(nameof(parent));
var controller = parent.AddComponent<Player>();
controller.name = $"{nameof(Player)} {index}";
controller.Index = index;
return controller;
}
}
工厂、可编写脚本的单例不会在程序集重新加载时丢失状态,而如果您使用静态 int
来计算玩家数量,它会在程序集重新加载时将自身重置为零,因为静态字段不会被序列化团结。
public sealed class PlayerFactory : ScriptableSingleton<PlayerFactory>
{
[SerializeField]
private int PlayerCount;
[NotNull]
public Player Create(GameObject parent)
{
return Player.Create(parent,++PlayerCount);
}
}
现在,如果您不想将分数数据存储在 Player
中,那将是另一种模式。我把它留给你作为练习。