统一定时器复位
Unity Timer Reset
我的游戏中有一个计时器,它会计算到游戏结束的时间。我不知道如何制作它,所以它只会在菜单场景处于活动状态时重置回 0(构建索引 0)。第二个问题是我不希望它在每次死亡(场景重新加载)后回到 0。你有什么建议吗?
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class Timer : MonoBehaviour {
public Text TimerText;
public bool shouldCountTime;
public float t;
private void Start()
{
if (SceneManager.GetActiveScene().buildIndex != 0)
{
shouldCountTime = true;
}
else
{
shouldCountTime = false;
t = 0;
}
t = Time.deltaTime;
}
void Update()
{
if (shouldCountTime) {
t += Time.deltaTime;
}
string minutes = ((int)t / 60).ToString();
string seconds = (t % 60).ToString("f2");
TimerText.text = minutes + ":" + seconds;
}
}
如前所述,您应该将其设置为单例(意味着一次只能存在一个实例 - 不是 谈论具有 [=24= 的一般(滥用)用途] 静态引用 ;) )
并使用 DontDestroyOnLoad
in order to keep your object also when the scene is changed and for the resetting use SceneManager.sceneLoaded
并检查新加载场景的索引,例如
public class Timer : MonoBehaviour
{
// Make sure this text is also not destroyed
// e.g. make its entire canvas a child of this object
public Text TimerText;
public bool shouldCountTime;
public float t;
// Singleton Pattern -> make sure only one instance exists in your scene
private static Timer _instance;
private void Awake()
{
// does another instance already exist?
if(_instance && _instance != this)
{
// if so detroy this one
Destroy(gameObject);
return;
}
// This is the active instance
_instance = this;
// Don't destroy this GameObject when a new scene is loaded
DontDestroyOnload(gameObject);
// Attach a callback for every new scene that is loaded
// It is fine to remove a callback that wasn't added so far
// This makes sure that this callback is definitely only added once
// usually I do this only as a kind of convention
SceneManager.sceneLoaded -= OnSceneLoaded;
SceneManager.sceneLoaded += OnSceneLoaded;
}
// Will be called every time a scene is loaded
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
// check the build index
shouldCountTime = scene.buildIndex != 0;
// Reset in the main menu
if(!shouldCountTime)
{
Debug.Log("Reset timer", this);
t = 0;
TimerText.text = "0:00";
}
}
private void OnDestroy()
{
// Even though your object most probably lives during the entire application lifetime
// again just as a convention always remove callbacks as soon as not needed anymore
SceneManager.sceneLoaded -= OnSceneLoaded;
}
void Update()
{
// do your calculations only while the value is actually changing
if (!shouldCountTime) return;
t += Time.deltaTime;
var minutes = ((int)t / 60).ToString();
var seconds = (t % 60).ToString("f2");
TimerText.text = minutes + ":" + seconds;
}
}
如果更改层次结构(例如关于文本)不是一种选择,而是参考 以获取关注值的替代解决方案。
我的游戏中有一个计时器,它会计算到游戏结束的时间。我不知道如何制作它,所以它只会在菜单场景处于活动状态时重置回 0(构建索引 0)。第二个问题是我不希望它在每次死亡(场景重新加载)后回到 0。你有什么建议吗?
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class Timer : MonoBehaviour {
public Text TimerText;
public bool shouldCountTime;
public float t;
private void Start()
{
if (SceneManager.GetActiveScene().buildIndex != 0)
{
shouldCountTime = true;
}
else
{
shouldCountTime = false;
t = 0;
}
t = Time.deltaTime;
}
void Update()
{
if (shouldCountTime) {
t += Time.deltaTime;
}
string minutes = ((int)t / 60).ToString();
string seconds = (t % 60).ToString("f2");
TimerText.text = minutes + ":" + seconds;
}
}
如前所述,您应该将其设置为单例(意味着一次只能存在一个实例 - 不是 谈论具有 [=24= 的一般(滥用)用途] 静态引用 ;) )
并使用 DontDestroyOnLoad
in order to keep your object also when the scene is changed and for the resetting use SceneManager.sceneLoaded
并检查新加载场景的索引,例如
public class Timer : MonoBehaviour
{
// Make sure this text is also not destroyed
// e.g. make its entire canvas a child of this object
public Text TimerText;
public bool shouldCountTime;
public float t;
// Singleton Pattern -> make sure only one instance exists in your scene
private static Timer _instance;
private void Awake()
{
// does another instance already exist?
if(_instance && _instance != this)
{
// if so detroy this one
Destroy(gameObject);
return;
}
// This is the active instance
_instance = this;
// Don't destroy this GameObject when a new scene is loaded
DontDestroyOnload(gameObject);
// Attach a callback for every new scene that is loaded
// It is fine to remove a callback that wasn't added so far
// This makes sure that this callback is definitely only added once
// usually I do this only as a kind of convention
SceneManager.sceneLoaded -= OnSceneLoaded;
SceneManager.sceneLoaded += OnSceneLoaded;
}
// Will be called every time a scene is loaded
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
// check the build index
shouldCountTime = scene.buildIndex != 0;
// Reset in the main menu
if(!shouldCountTime)
{
Debug.Log("Reset timer", this);
t = 0;
TimerText.text = "0:00";
}
}
private void OnDestroy()
{
// Even though your object most probably lives during the entire application lifetime
// again just as a convention always remove callbacks as soon as not needed anymore
SceneManager.sceneLoaded -= OnSceneLoaded;
}
void Update()
{
// do your calculations only while the value is actually changing
if (!shouldCountTime) return;
t += Time.deltaTime;
var minutes = ((int)t / 60).ToString();
var seconds = (t % 60).ToString("f2");
TimerText.text = minutes + ":" + seconds;
}
}
如果更改层次结构(例如关于文本)不是一种选择,而是参考