- Home /
Stacking Coroutines with Mouseover
I want an event to trigger after a certain amount of hover time (3 s) has elapsed, and I'm using StartCoroutine
coupled with a function returning an IEnumerator
with yield return new WaitForSeconds(3.0f)
. However, I want to avoid the trigger if the user moves the cursor away from the triggering surface before the required time has passed.
There are two Button
objects with the MouseHandler
script attached to them, and with the GameManagerScript
script referred to by gm
.
What I have done is the following:
public class MouseHandler : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
public GameManagerScript gm;
public void OnPointerEnter(PointerEventData eventData)
{
GameManagerScript.dateOffset = DateTimeOffset.UtcNow;
GameManagerScript.outside = false;
StartCoroutine(CallFunction(eventData));
}
public void OnPointerExit(PointerEventData eventData)
{
GameManagerScript.dateOffset = DateTimeOffset.UtcNow;
GameManagerScript.outside = true;
gm.ButtonClick("out");
}
IEnumerator CallFunction(PointerEventData ed)
{
yield return new WaitForSeconds(3.0f);
gm.ButtonClick(ed.pointerEnter.ToString());
}
}
Next, in my GameManagerScript
I have the following, with a Text
object that displays a certain string of characters, such as the name of the Text
objects in both Button
hierarchies, being referred to by t
:
public class GameManagerScript : MonoBehaviour
{
public Text t;
public static bool outside = true; // in case entering and exiting occurs simultaneously
public static DateTimeOffset dateOffset;
// Start is called before the first frame update
void Start()
{
t.text = "still nothing";
}
public void ButtonClick(string s)
{
long diff = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() -
dateOffset.ToUnixTimeMilliseconds();
Debug.Log(diff);
if (outside == false && diff >= 3000L) {
t.text = s;
}
}
}
This code and everything works fine, sort of. Whenever I load the executable for the first time, however, and hover my cursor over one of the buttons for 3 or more seconds, the label field will continue to show the predefined string still nothing. When I remove the cursor and try again, it works, and everything works fine then.
I'd like to get rid of this initial failure at the beginning of my program.
Second of all, I occasionally get this mysterious error in the console which doesn't seem to cause any trouble (although I can't pinpoint when it happens exactly): UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)
.
I can't really reproduce it, but it originates on this line in the CallFunction
function:
gm.ButtonClick(ed.pointerEnter.ToString());
Third of all, I'd like it if someone could comment on this particular solution of this problem. Is there a potential problem with it? I've tried quickly moving the cursor between the two buttons, thus causing the frequent function calls and such, but I haven't noticed any real issues. It's definitely a lazy solution, but I figured it can't be that bad.
Thanks for any help in advance.