Unity:如何按时间延迟按钮调用?
Unity: How to Delay button call by time?
我希望每次用户单击 UI 按钮时将浮点数递增 0.5,如果用户按下按钮超过 2 秒,我希望将浮点数连续递增 0.5,为此我使用事件触发器(PointerDown、PointerUp)并调用更新中的函数。当我使用下面的代码时,我无法连续增加浮点值。
更新代码
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 ();
}
PointerDown 函数
public void WhenIncreaseClicked()
{
if (timeDown < 2.0f)
IncreaseBPM ();
else
increase = true;
}
PinterUp 函数
public void WhenIncreaseNotClicked()
{
increase = false;
Time.timeScale = 1;
}
增加BPM
public void IncreaseBPM()
{
if (speed < 12)
{
speed += 0.05f;
bpmText.GetComponent<BeatTextControl> ().beats += 1;
PlayerPrefs.SetFloat ("savedBPM", speed);
}
}
点击条件
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
是 [=14= 时它只是 运行 ].
例如:
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 ();
}
和WhenIncreaseClicked()
:
public void WhenIncreaseClicked()
{
clicked = true;
IncreaseBPM();
}
和WhenIncreaseNotClicked()
:
public void WhenIncreaseNotClicked()
{
clicked = false;
increase = false;
Time.timeScale = 1;
}
您还可以在 Start()
中删除对 timeDown
的分配,因为它没有用。
首先,Unity 文档说 Time.deltaTime
The time in seconds it took to complete the last frame.
当您设置 timeDown = Time.deltaTime
时,timeDown 变为 微小的 分数,例如 0.01621689
。因此,timeDown < 2.0f
总是 returns true
并且您的代码永远不会到达 increase = true;
行。
你应该知道的第二点是Time.time
The time at the beginning of this frame (Read Only). This is the time in seconds since the start of the game.
您在 Update()
方法中使用 Time.time
作为 Mathf.Sin(Time.time * speed)
。请记住,Time.time
可以是足够大的数字,表示文档中提到的自游戏开始以来的秒数。当您执行 Time.time * speed
时,输出数字可能会很大(假设 speed > 1
),从而导致一些问题。幸运的是,您在 Mathf.Sin()
中使用它,您只能在 [0, 1] 之间获得数字。可能,您打算改用 Time.deltaTime
。
让我们记住Time.time
:
The time in seconds since the start of the game
您可以使用它来检查时差。
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
:
Except for realtimeSinceStartup
, timeScale
affects all the time and delta time measuring variables of the Time class.
因此,如果您坚持使用 Time.timeScale
,而不是使用 Time.time,您应该在上面的示例中使用 Time.realtimeSinceStartup
。
我希望每次用户单击 UI 按钮时将浮点数递增 0.5,如果用户按下按钮超过 2 秒,我希望将浮点数连续递增 0.5,为此我使用事件触发器(PointerDown、PointerUp)并调用更新中的函数。当我使用下面的代码时,我无法连续增加浮点值。
更新代码
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 ();
}
PointerDown 函数
public void WhenIncreaseClicked()
{
if (timeDown < 2.0f)
IncreaseBPM ();
else
increase = true;
}
PinterUp 函数
public void WhenIncreaseNotClicked()
{
increase = false;
Time.timeScale = 1;
}
增加BPM
public void IncreaseBPM()
{
if (speed < 12)
{
speed += 0.05f;
bpmText.GetComponent<BeatTextControl> ().beats += 1;
PlayerPrefs.SetFloat ("savedBPM", speed);
}
}
点击条件
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
是 [=14= 时它只是 运行 ].
例如:
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 ();
}
和WhenIncreaseClicked()
:
public void WhenIncreaseClicked()
{
clicked = true;
IncreaseBPM();
}
和WhenIncreaseNotClicked()
:
public void WhenIncreaseNotClicked()
{
clicked = false;
increase = false;
Time.timeScale = 1;
}
您还可以在 Start()
中删除对 timeDown
的分配,因为它没有用。
首先,Unity 文档说 Time.deltaTime
The time in seconds it took to complete the last frame.
当您设置 timeDown = Time.deltaTime
时,timeDown 变为 微小的 分数,例如 0.01621689
。因此,timeDown < 2.0f
总是 returns true
并且您的代码永远不会到达 increase = true;
行。
你应该知道的第二点是Time.time
The time at the beginning of this frame (Read Only). This is the time in seconds since the start of the game.
您在 Update()
方法中使用 Time.time
作为 Mathf.Sin(Time.time * speed)
。请记住,Time.time
可以是足够大的数字,表示文档中提到的自游戏开始以来的秒数。当您执行 Time.time * speed
时,输出数字可能会很大(假设 speed > 1
),从而导致一些问题。幸运的是,您在 Mathf.Sin()
中使用它,您只能在 [0, 1] 之间获得数字。可能,您打算改用 Time.deltaTime
。
让我们记住Time.time
:
The time in seconds since the start of the game
您可以使用它来检查时差。
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
:
Except for
realtimeSinceStartup
,timeScale
affects all the time and delta time measuring variables of the Time class.
因此,如果您坚持使用 Time.timeScale
,而不是使用 Time.time,您应该在上面的示例中使用 Time.realtimeSinceStartup
。