Unity:如何按时间延迟按钮调用
本文关键字:按钮 调用 时间延迟 何按 Unity | 更新日期: 2023-09-27 18:05:41
我希望每次用户点击UI按钮时增加一个浮动0.5,如果用户按下按钮超过2秒,想要持续增加浮动0.5,为此,我使用事件触发器(PointerDown, PointerUp)并调用更新中的函数。当我使用下面的代码时,它不能连续增加浮点值。
<<p> 更新代码/strong>void Update () {
transform.rotation = Quaternion.Lerp (qStart, qEnd, (Mathf.Sin(Time.time * speed) + 1.0f) / 2.0f);
if(Time.timeScale == 0)
transform.rotation = Quaternion.Euler(0,0,0);
clickCondition ();
}
<<p> PointerDown函数/strong> public void WhenIncreaseClicked()
{
if (timeDown < 2.0f)
IncreaseBPM ();
else
increase = true;
}
<<p> PinterUp函数/strong> public void WhenIncreaseNotClicked()
{
increase = false;
Time.timeScale = 1;
}
IncreaseBPM
public void IncreaseBPM()
{
if (speed < 12)
{
speed += 0.05f;
bpmText.GetComponent<BeatTextControl> ().beats += 1;
PlayerPrefs.SetFloat ("savedBPM", speed);
}
}
ClickCondition
public void clickCondition()
{
if(increase)
{
IncreaseBPM();
}
else if(decrease)
{
DecreaseBPM();
}
}
void Start () {
qStart = Quaternion.AngleAxis ( angle, Vector3.forward);
qEnd = Quaternion.AngleAxis (-angle, Vector3.forward);
timeDown = Time.deltaTime;
if (PlayerPrefs.HasKey ("savedBPM"))
speed = PlayerPrefs.GetFloat ("savedBPM");
else
speed = 1.5f;
}
我在Start()
中设置了timeDown = Time.deltaTime
假设没有其他代码改变您的increase
变量,您将无法连续增加它,因为它永远不会被设置为true
。
在Start()
中你有一行timeDown = Time.deltaTime;
,所以timeDown
将等于从上一帧开始的秒数。这不仅是一个问题,因为timeDown
永远不会改变(Start()
只被调用一次),但这是一个问题,因为它不可能超过2.0f
,因为一个帧极不可能花2秒来完成。它通常是一个非常小的数字,例如0.06f
。
因此,在WhenIncreaseClicked()
方法中,if (timeDown < 2.0f)
将始终等于true。因此,else子句永远不会被执行,increase
也永远不会被设置为true。
要解决这个问题,你可以创建一个新的布尔变量,例如clicked
,并在WhenIncreaseClicked()
开始时设置为true,在WhenIncreaseNotClicked()
开始时设置为false。然后在Update()
中,如果clicked
是true
,则可以将Time.deltaTime
添加到timeDown
。您还需要将if/else从WhenIncreaseClicked()
移到Update()
中,确保它仅在clicked
为true
时运行。
void Update () {
transform.rotation = Quaternion.Lerp (qStart, qEnd, (Mathf.Sin(Time.time * speed) + 1.0f) / 2.0f);
if(Time.timeScale == 0)
transform.rotation = Quaternion.Euler(0,0,0);
if(clicked) {
timeDown += Time.deltaTime;
if (timeDown >= 2.0f) // note the >= not <
increase = true;
}
clickCondition ();
}
and WhenIncreaseClicked()
:
public void WhenIncreaseClicked()
{
clicked = true;
IncreaseBPM();
}
and WhenIncreaseNotClicked()
:
public void WhenIncreaseNotClicked()
{
clicked = false;
increase = false;
Time.timeScale = 1;
}
你也可以在Start()
中删除对timeDown
的赋值,因为它没有用。
首先,Unity文档中提到了Time.deltaTime
以秒为单位完成最后一帧所需的时间。
设置timeDown = Time.deltaTime
时,timeDown变成一个微小的分数,例如0.01621689
。因此,timeDown < 2.0f
总是返回true
,你的代码永远不会到达increase = true;
行。
Time.time
帧开始的时间(只读)。这是以秒为单位的时间,从游戏开始。
你在Update()
方法中使用Time.time
作为Mathf.Sin(Time.time * speed)
。请记住,Time.time
可以是足够大的数字,表示从文件中提到的游戏开始的时间(以秒为单位)。当您执行Time.time * speed
时,输出数量可能会很大(假设是speed > 1
),从而导致一些问题。幸运的是,您在Mathf.Sin()
中使用它,您只获得[0,1]之间的数字。可能,您打算使用Time.deltaTime
代替。
让我们记住Time.time
:
游戏开始后的秒数
你可以用这个来检查时差
float lastDownTime;
bool isDown;
void OnPointerDown() // Method name itself says when it should be called
{
lastDownTime = Time.time;
isDown = true;
}
void OnPointerUp()
{
isDown = false;
}
void Update ()
{
if (isDown)
{
if (Time.time - lastDownTime > 2) // 2 seconds
{
IncreaseBPM ();
}
}
}
注意: Unity说关于Time.timeScale
:
除
realtimeSinceStartup
外,timeScale
影响time类的所有时间和增量时间度量变量。
所以如果你坚持使用Time.timeScale
,而不是使用时间。在上面的例子中,你应该使用Time.realtimeSinceStartup