我正在做一个游戏,我试图在场景之间传递数据(分数)。问题在于当我再次统一比赛时,得分保持4-5,10分取决于最后一个环节,并且从第一个场景开始时不能从0开始正常。 (我仍然希望在场景之间保存数据,但是当我单击“统一运行”时要重置分数) 我有2个脚本,应该更改什么?
得分
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class Score : MonoBehaviour
{
public Text scoreText;
public int score;
public Button button;
// Use this for initialization
void Start()
{
score = PlayerPrefs.GetInt("score", 0);
GameObject.DontDestroyOnLoad(this.gameObject);
Debug.LogFormat("Current Score: {0}", score);
Button btn = GetComponent<Button>();
button.onClick.AddListener(TaskOnClick);
}
void Update()
{
scoreText.text = "Score: " + score;
}
void OnDestroy()
{
PlayerPrefs.SetInt("score", score);
}
public void AddScore(int s)
{
score += s;
}
public int GetScore()
{
return score;
}
void TaskOnClick()
{
score++;
}
}
ScorePanelUpdater
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ScorePanelUpdater : MonoBehaviour
{
void Update()
{
GameObject go = GameObject.Find("Score");
if(go == null)
{
Debug.LogError("Failed");
this.enabled = false;
return;
}
Score gs = go.GetComponent<Score>();
GetComponent<Text>().text = " Score: " + gs.GetScore();
}
}
答案 0 :(得分:2)
您正在使用DontDestroyOnLoad
,因此您的实例和相应的值无论如何也将在每个场景中维护。 您完全不需要/根本不使用PlayerPrefs
。
要回答您的问题:您有
void OnDestroy()
{
PlayerPrefs.SetInt("score", score);
}
因此,一旦此实例销毁,最后的值将始终存储..什么时候发生?由于您正在使用DontDestroyOnLoad
,因此除非您关闭游戏,否则它不会发生从未发生,退出游戏模式=>由于
void Start()
{
score = PlayerPrefs.GetInt("score", 0);
...
}
解决方案:在0
(OnDestroy
)中将其重置为PlayerPrefs.SetInt("score", 0);
,或者从脚本中完全删除PlayerPrefs
!您不需要它。
this answer已经提到了更简单的方法:您可以简单地使用static
字段。同样,由于您正在使用DontDestroyOnLoad
,因此实际上并不需要这样做,因为它仍然可以在所有场景中使用。
但是您的代码中还有其他一些问题:
不要重复使用Find
和GetComponent
,如果在Update
中使用..更糟糕的是,这些效率很低!同样,对于Update
的值实际上发生更改之后,只需要更改事件驱动的事情,就根本不需要使用score
。
由于效率方面还有很多其他问题,因此我会对此加以扩展,并且不会在MonoBehaviour
内使用它,而在static class
中将其完全分开,例如
public static class GameInformation
{
private static int _score = 0;
// have an event to register listeners
public static event Action<int> OnScoreChanged;
// public property
public static int Score
{
get { return _score;}
set
{
_score = value;
// invoke an event to inform all registered listeners
OnScoreChanged?.Invoke(_score);
}
}
}
此类不需要实例,但可以在运行时从任何地方进行访问。
现在您可以在Score
中
public class Score : MonoBehaviour
{
public Text scoreText;
public Button button;
// Use this for initialization
void Start()
{
DontDestroyOnLoad(gameObject);
if(!button) button = GetComponent<Button>();
button.onClick.AddListener(() => { GameInformation.Score++; });
GameInformation.OnScoreChanged -= OnScoreChanged;
GameInformation.OnScoreChanged += OnScoreChanged;
// invoke once now with current value
Debug.LogFormat("Current Score: {0}", GameInformation.Score);
OnScoreChanged(GameInformation.Score);
}
private void OnDestroy()
{
GameInformation.OnScoreChanged -= OnScoreChanged;
}
private void OnScoreChanged(int newValue)
{
scoreText.text = "Score: " + newValue;
}
// These two make not much sense .. since the value already was public
// you wouldn't need methods for this
// anyway now you could directly do it on GameInformation instead
public void AddScore(int s)
{
GameInformation.Score += s;
}
public int GetScore()
{
return GameInformation.Score;
}
}
并且在ScorePanelUpdater
中也只需添加回调
public class ScorePanelUpdater : MonoBehaviour
{
// better if you can already reference this via Inspector
[SerializeField] Text text;
void Awake()
{
if(!text) text = GetComponent<Text>();
// it's always save to remove listeners before adding them
// makes sure it is added only once
GameInformation.OnScoreChanged -= OnScoreChanged;
GameInformation.OnScoreChanged += OnScoreChanged;
// invoke once now with current value
OnScoreChanged(GameInformation.Score);
}
private void OnDestroy()
{
GameInformation.OnScoreChanged -= OnScoreChanged;
}
private void OnScoreChanged(int newValue)
{
text.text = "Score: " + newValue;
}
}
答案 1 :(得分:1)
您可以做的另一件事是将得分保存为静态变量。这样,您可以从每个场景访问它,但是一旦重新启动游戏,该值将被重置。
public static int score = 0;
答案 2 :(得分:0)
尝试将以下内容添加到"2019-08-15T15:58:14.597Z"
(第一个场景)或<template>
<v-content class="mt-12 ml-12">
<h1 class="font-weight-black display-3">Servers</h1>
<v-data-table
class="elevation-1"
:headers="headers"
:items="columns"
:items-per-page="15"
>
</v-data-table>
<ul id="example-1">
<li v-for="(data, index) in columns.data" :key="index">
{{ data.attributes }}
</li>
</ul>
</v-content>
</template>
<script>
import instances from '../services/instances';
export default {
data() {
return {
columns: [],
headers: [
{ text: 'Server Name', value: 'attributes.name' },
{ text: 'Spieler', value: 'attributes.playerCount' },
{ text: 'Avg. FPS', value: 'attributes.details.rust_fps_avg' },
{ text: 'Wiped', value: 'attributes.details.rust_last_wipe' },
],
};
},
async created() {
const { data } = await instances.createInstance();
this.columns = data.data;
this.columns.forEach((entry) => {
const { players, maxPlayers } = entry.attributes;
entry.attributes.playerCount = `${players} / ${maxPlayers}`;
const { rust_last_wipe } = entry.attributes.details;
const mmmm = new Date(entry.attributes.details.rust_last_wipe);
entry.attributes.details.rust_last_wipe = `${mmmm.getDate()}.${mmmm.getMonth() + 1}.${mmmm.getFullYear()}`;
});
console.log(this.columns);
},
};
</script>
(最后一个场景):
Start()
对于OnApplicationQuit()
:
PlayerPrefs.SetInt("score", 0);