我对VR的凝视有一个问题。我想做的是凝视我要选择的按钮,然后隐藏第一个游戏对象父对象,然后显示第二个游戏对象父对象。现在将显示第二个游戏对象父对象,当我尝试凝视后退按钮时,它将显示第一个游戏对象父对象并隐藏第二个游戏对象父对象。问题出现在这里,当我什么都不做并且不注视按钮时,它会自动显示我的第二个游戏对象父对象,然后返回第一个父游戏对象并隐藏并显示并始终隐藏并显示。
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();
}
这是我的Setting
代码的设置方式
public GameObject setting;
public GameObject back;
public void ActivateSetting()
{
setting.SetActive(false);
back.SetActive(true);
}
public void GoBackToMainMenu()
{
back.SetActive(false);
setting.SetActive(true);
}
我想要的是,如果我凝视它,它只会显示游戏对象的父对象。
答案 0 :(得分:1)
点击一次后,您重置了timer
,但没有重置gazedAt
=> Update
方法仍在运行计时器并再次调用该点击。
您的PointerExit
似乎根本没有被调用,因此该按钮永远不会重置。
我强烈建议使用IPointerEnterHandler
和EventTrigger
这样的接口,而不是IPointerExitHandler
public class YourClass : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
//...
public void OnPointerEnter()
{
}
public void OnPointerExit()
{
}
我实际上根本不会使用Update
,而是更喜欢Coroutine。另外,请勿使用ExecuteEvents.Execute(gameObject, new PointerEventData(EventSystem.current), ExecuteEvents.pointerDownHandler);
的复杂调用,而应使用Getcomponent<Button>().onClick.Invoke();
或直接调用该方法
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());
}
如您所见,timer
和gazedAt
值根本不需要,因此您不能忘记将它们重置在某个地方。它还避免了重复调用该方法。
如果您根本不想使用Button
,也可以添加自己的UnityEvent
,例如
// add callbacks e.g. in the Inspector or via script
public UnityEvent onGazedClick;
// ...
onGazedClick.Invoke();