如何优化倒数计时器?
How to optimise countdown timer?
亲爱的 Whosebug 社区,
我有双倍加电倒数计时器,现在我遇到了问题,因为我的代码在游戏中运行良好,但是当计时器处于活动状态时,游戏会滞后,不会太多,但任何滞后对我的游戏都不利,因为播放器需要流畅播放,没有任何未优化的组件..
我有这段代码,我敢打赌游戏是滞后的,因为代码在更新方法中(我试图把它放在游戏管理器脚本中,但计时器不会倒计时,所以这不是解决方案)
这是代码(感谢 Whosebug 用户@siusiulala,他给我写了工作代码)
但似乎需要使用另一种方法或其他方法,因为更新方法 运行 性能在内部有倒计时。
private void Update(){
if (isDoublePoints)
{
// Countdown the timer with update time
powerUpTimer -= Time.deltaTime;
Debug.Log("TIMER ISS " + powerUpTimer);
if (powerUpTimer <= 0)
{
// End of power up time
isDoublePoints = false;
}
}
}
public void OnPickPowerUp(float buffTime)
{
powerUpTimer += buffTime;
}
我希望有人能解决 lagg 的问题,因为我看到很多游戏都有 power up 系统,里面没有任何 laggs...
谢谢Whosebug,没有你我的游戏永远不会结束:)
根据我的经验,Debug.Log()
是一种非常 昂贵的方法。它将在每帧调用时造成延迟。因此,我的 IDE 甚至将 Debug.Log()
在 Update()
中的用法突出显示为警告。此方法仅用于调试,然后删除。
如果您希望能够看到计时器值,请将 [SerializeField]
属性添加到您的字段,它会显示在检查器中。
您可以通过选择 Window-Analysis-Profiler 来使用分析器,假设您使用的是 Unity 2018.x。它记录了处理所花费的时间,并有助于定位瓶颈。
关于 Debug.Log
的说法是正确的。
使用 [SerializeField]
可能会被一些人认为是 肮脏和懒惰的 黑客行为。因为它有 side-effect 现在是 序列化 ,这意味着价值存储在资产中。这还不错,但如果你是准确的,那么无论如何都不应该使用将在 运行 时间更改的字段。
相反,您可以直接转到检查器,打开上下文菜单并将其设置为 Debug
模式
这使得 Inspector 不使用自定义 EditorScript,而是显示所有私有字段(Serializable
类型)。
例如 Transform
组件
然而,比使用带有标志 的 Update
方法更有效的方法 宁愿使用 Coroutines
.
协程可以启动 运行 并行(紧随其后的每一帧) Update
方法,但优点是:当协程完成时 - 它完成并且不会继续检查 bool
标记每一帧。
所以每当你拿起一个 PowerUp 而不是将标志设置为 true
而是使用
StartCoroutine(PowerUpRoutine());
并执行类似
的例程
private IEnumerator PowerUpRoutine()
{
isDoublePoints = true;
while(powerUpTimer > 0)
{
// Countdown the timer with update time
powerUpTimer -= Time.deltaTime;
//Debug.Log("TIMER ISS " + powerUpTimer);
// yield in simple words makes Unity "pause"
// the execution here, render this frame and continue from here
// in the next frame
yield return null;
}
// End of power up time
isDoublePoints = false;
}
public void OnPickPowerUp(float buffTime)
{
powerUpTimer += buffTime;
// avoid concurrent routines
if(!isDoublePoints) StartCoroutine(PowerUpRoutine());
}
为了在您的游戏中显示它,您可以使用 Text
or TextMeshPro
并设置文本,例如
[SerializeField] private Text _text;
private IEnumerator PowerUpRoutine()
{
isDoublePoints = true;
while(powerUpTimer > 0)
{
// Countdown the timer with update time
powerUpTimer -= Time.deltaTime;
//Debug.Log("TIMER ISS " + powerUpTimer);
// set the text of the Text component to display the value
// for the $ symbol google for "c# string interpolation"
_text.text = $"TIMER IS {powerUpTimer:00.00}";
// yield in simple words makes Unity "pause"
// the execution here, render this frame and continue from here
// in the next frame
yield return null;
}
// End of power up time
isDoublePoints = false;
}
亲爱的 Whosebug 社区,
我有双倍加电倒数计时器,现在我遇到了问题,因为我的代码在游戏中运行良好,但是当计时器处于活动状态时,游戏会滞后,不会太多,但任何滞后对我的游戏都不利,因为播放器需要流畅播放,没有任何未优化的组件..
我有这段代码,我敢打赌游戏是滞后的,因为代码在更新方法中(我试图把它放在游戏管理器脚本中,但计时器不会倒计时,所以这不是解决方案)
这是代码(感谢 Whosebug 用户@siusiulala,他给我写了工作代码) 但似乎需要使用另一种方法或其他方法,因为更新方法 运行 性能在内部有倒计时。
private void Update(){
if (isDoublePoints)
{
// Countdown the timer with update time
powerUpTimer -= Time.deltaTime;
Debug.Log("TIMER ISS " + powerUpTimer);
if (powerUpTimer <= 0)
{
// End of power up time
isDoublePoints = false;
}
}
}
public void OnPickPowerUp(float buffTime)
{
powerUpTimer += buffTime;
}
我希望有人能解决 lagg 的问题,因为我看到很多游戏都有 power up 系统,里面没有任何 laggs...
谢谢Whosebug,没有你我的游戏永远不会结束:)
根据我的经验,Debug.Log()
是一种非常 昂贵的方法。它将在每帧调用时造成延迟。因此,我的 IDE 甚至将 Debug.Log()
在 Update()
中的用法突出显示为警告。此方法仅用于调试,然后删除。
如果您希望能够看到计时器值,请将 [SerializeField]
属性添加到您的字段,它会显示在检查器中。
您可以通过选择 Window-Analysis-Profiler 来使用分析器,假设您使用的是 Unity 2018.x。它记录了处理所花费的时间,并有助于定位瓶颈。
Debug.Log
的说法是正确的。
使用 [SerializeField]
可能会被一些人认为是 肮脏和懒惰的 黑客行为。因为它有 side-effect 现在是 序列化 ,这意味着价值存储在资产中。这还不错,但如果你是准确的,那么无论如何都不应该使用将在 运行 时间更改的字段。
相反,您可以直接转到检查器,打开上下文菜单并将其设置为 Debug
模式
这使得 Inspector 不使用自定义 EditorScript,而是显示所有私有字段(Serializable
类型)。
例如 Transform
组件
然而,比使用带有标志 的 Update
方法更有效的方法 宁愿使用 Coroutines
.
协程可以启动 运行 并行(紧随其后的每一帧) Update
方法,但优点是:当协程完成时 - 它完成并且不会继续检查 bool
标记每一帧。
所以每当你拿起一个 PowerUp 而不是将标志设置为 true
而是使用
StartCoroutine(PowerUpRoutine());
并执行类似
的例程private IEnumerator PowerUpRoutine()
{
isDoublePoints = true;
while(powerUpTimer > 0)
{
// Countdown the timer with update time
powerUpTimer -= Time.deltaTime;
//Debug.Log("TIMER ISS " + powerUpTimer);
// yield in simple words makes Unity "pause"
// the execution here, render this frame and continue from here
// in the next frame
yield return null;
}
// End of power up time
isDoublePoints = false;
}
public void OnPickPowerUp(float buffTime)
{
powerUpTimer += buffTime;
// avoid concurrent routines
if(!isDoublePoints) StartCoroutine(PowerUpRoutine());
}
为了在您的游戏中显示它,您可以使用 Text
or TextMeshPro
并设置文本,例如
[SerializeField] private Text _text;
private IEnumerator PowerUpRoutine()
{
isDoublePoints = true;
while(powerUpTimer > 0)
{
// Countdown the timer with update time
powerUpTimer -= Time.deltaTime;
//Debug.Log("TIMER ISS " + powerUpTimer);
// set the text of the Text component to display the value
// for the $ symbol google for "c# string interpolation"
_text.text = $"TIMER IS {powerUpTimer:00.00}";
// yield in simple words makes Unity "pause"
// the execution here, render this frame and continue from here
// in the next frame
yield return null;
}
// End of power up time
isDoublePoints = false;
}