简体   繁体   中英

gaze always execute even after PointExit

I have a problem about my gaze on VR . What I am trying to do is that gaze upon the button I want to select then hide the first gameobject parent then show the second gameobject parent . Now the second gameobject parent will be shown and when I try to gaze upon the back button it will show the first gameobject parent and hide the second gameobject parent . The problem occurs here, when I am trying to nothing and don't gaze on the buttons it automatically show my second gameobject parent and go back to first parent gameobject and hide and show and hide and show always.

public float gazeTime = 2f;
private float timer;
private bool gazedAt;

public Setting setting;

private void Start()
{

}

public void Update()
{
    if (gazedAt)
    {
        timer += Time.deltaTime;

        if (timer >= gazeTime)
        {
            // execute pointerdown handler
            ExecuteEvents.Execute(gameObject, new PointerEventData(EventSystem.current), ExecuteEvents.pointerDownHandler);
            timer = 0f;
        }
        else
        {
            return;
        }
    }
    else
    {
        return;
    }

}

public void PointerEnter()
{
    gazedAt = true;
    Debug.Log("PointerEnter");
}

public void PointerExit()
{
    gazedAt = false;
    Debug.Log("PointerExit");
}

//Method for going to setting
public void Setting()
{
    setting.ActivateSetting();
}
//Method for going back to main menu
public void GoBack()
{
    setting.GoBackToMainMenu();
}

Here's how my Setting code is setup

public GameObject setting;
public GameObject back; 

public void ActivateSetting()
{
    setting.SetActive(false);
    back.SetActive(true);
}

public void GoBackToMainMenu()
{
    back.SetActive(false);
    setting.SetActive(true);
}  

What I want is that it will only show the gameobject parent if I gaze upon it.

After calling the click once you reset the timer but you didn't reset gazedAt

=> the Update method did still run the timer and call the click again.

It seems that your PointerExit is not called at all and therefore the button never reset.


Instead of the EventTrigger I would strongly recommend to use the interfaces IPointerEnterHandler and IPointerExitHandler like

public class YourClass : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
    //...

    public void OnPointerEnter()
    {

    }

    public void OnPointerExit()
    {

    }

I would actually not use Update at all but prefer a Coroutine . Also don't use the complex call of ExecuteEvents.Execute(gameObject, new PointerEventData(EventSystem.current), ExecuteEvents.pointerDownHandler); instead use either Getcomponent<Button>().onClick.Invoke(); or call the method directly

private Button _button;

private void Awake()
{
    // Get the reference only once to avoid 
    // having to get it over and over again
    _button = GetComponent<Button>();
}

private IEnumerator Gaze()
{
    // wait for given time
    yield return new WaitForSeconds(gazeTime);

    // call the buttons onClick event
    _button.onClick.Invoke();

    // or as said alternatively directly use the methods e.g.
    setting.ActivateSetting();
}

public void OnPointerEnter()
{
    Debug.Log("PointerEnter");

    // start the coroutine
    StartCoroutine(Gaze());
}

public void OnPointerExit()
{
    Debug.Log("PointerExit");

    // stop/interrupt the coroutine
    StopCoroutine(Gaze());
}

As you can see there is no need at all for the timer and gazedAt values so you can't forget to reset them somewhere. It also avoids that the method is called repeatedly.


If you don't want to use a Button at all you could also add your ownUnityEvent like

// add callbacks e.g. in the Inspector or via script
public UnityEvent onGazedClick;

// ...

onGazedClick.Invoke();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM