如何知道单击了哪个按钮? (Unity / Hololens2 / MRTK)

时间:2019-09-23 13:02:47

标签: unity3d hololens mrtk hololens-emulator

我大约有10个按钮,每个按钮都有一个通过脚本添加的唯一值。我想知道在使用MRTK手与按钮交互时单击了哪个按钮。

我尝试将updateField方法添加到按钮,该按钮使用默认的EventSystem获取当前选定的对象。但是,当我调试时,该值为null。

public void UpdateField()
{
      int dayNumb = EventSystem.current.currentSelectedGameObject.GetComponent<DayButton>().CurrentNumber();
}
  

NullReferenceException:对象引用未设置为的实例   对象UpdateInputField.UpdateField()(在   资产/脚本/UpdateInputField.cs:35)   UnityEngine.Events.InvokableCall.Invoke()(在   C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:166)   UnityEngine.Events.UnityEvent.Invoke()(在   C:/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:58)   Microsoft.MixedReality.Toolkit.UI.InteractableOnPressReceiver.OnUpdate   (Microsoft.MixedReality.Toolkit.UI.InteractableStates状态,   Microsoft.MixedReality.Toolkit.UI.Interactable源)(在   资产/MixedRealityToolkit.SDK/功能/ UX / Interactable /脚本/事件/InteractableOnPressReceiver.cs:71)   Microsoft.MixedReality.Toolkit.UI.Interactable.InternalUpdate()(在   资产/MixedRealityToolkit.SDK/功能/UX/Interactable/Scripts/Interactable.cs:525)   Microsoft.MixedReality.Toolkit.UI.Interactable.Update()(在   Assets / MixedRealityToolkit.SDK / Features / UX / Interactable / Scripts / Interactable.cs:506)

3 个答案:

答案 0 :(得分:2)

关于异常

EventSystem.current.currentSelectedGameObject.GetComponent<DayButton>().CurrentNumber();

提供了很多可能性。基本上,每个.之前的引用都可以由null引用。很可能是currentSelectedGameObject(当前仅未选择任何对象),或者是GetComponent<DayButton>()(当所选的对象仅没有这种成分时)。


我对您的课程一无所知,而对于MRTK则知之甚少,但是也许您可以使用事件系统模式,例如。

public class DayButton : WhateverType
{
    // public static event everyone can add listeners to 
    // in order to wait for any DayButton click
    public static event Action<DayButton> OnButtonClicked;

    // Just assuming for now this is the method called on click
    public void OnClick()
    {
        // Fire the static event and inform every listener
        // that this button was clicked by passing yourself in as parameter
        OnButtonClicked?.Invoke(this);
    }
}

然后,您可以有一个(或不同的)侦听器类来等待事件并检查像按下了哪个按钮

public class SomeListener : MonoBehaviour
{
    privtae void Awake()
    {
        // Add a listener to the global event
        DayButton.OnButtonClicked += HandleOnButtonClicked;
    }

    private void OnDestroy()
    {
        // Make sure to always remove listeners once not needed anymore
        // otherwise you get NullReferenceExceptions!
        DayButton.OnButtonClicked -= HandleOnButtonClicked;
    }

    // By passing the according DayButton reference in you have access
    // to all its public fields and methods
    private void HandleOnButtonClicked(DayButton button)
    {
        Debug.Log("The Button with the name {button.name} and number {button.CurrentNumber} was clicked!", this);
    }
}

答案 1 :(得分:1)

以下代码将打印场景中单击的每个按钮的名称。请注意,除了在启动时添加事件侦听器外,您还可以在通过代码创建按钮时添加这些侦听器。

using Microsoft.MixedReality.Toolkit.UI;
using UnityEngine;

/// <summary>
/// On startup, adds event handlers for every Interactable aka button
/// in the scene that logs the name of the button pressed.
/// You can similarly add such a listener when adding the buttons dynamically
/// </summary>
public class PrintWhichButtonPressed : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        var allInteractables = GameObject.FindObjectsOfType<Interactable>();
        foreach (var i in allInteractables)
        {
            i.OnClick.AddListener(() => Debug.Log(Time.time + ": " + i.gameObject.name + " was clicked"));
        }
    }
}

答案 2 :(得分:0)

解决了!! 我在start方法的每个按钮上添加了一个侦听器。然后调用该函数以获取那些对象的组件。

这是我的做法.........

using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEditor;
using Microsoft.MixedReality.Toolkit.UI;

public class UpdateInputField : MonoBehaviour {
    public InputField mainInputField;
    private Calendar calendar;
    private GameObject dateCanvas;
    public int dayNumb;

    void Start(){
        var allInteractables = GameObject.FindObjectsOfType<Interactable>();
        foreach (var i in allInteractables)
        {
            i.OnClick.AddListener(() => UpdateField(i));
        }
    }

    public void UpdateField(Microsoft.MixedReality.Toolkit.UI.Interactable index)
    {
        dayNumb = GameObject.Find(index.gameObject.name).GetComponent<DayButton>().CurrentNumber();
        calendar = GameObject.FindObjectOfType<Calendar>();
        mainInputField.text = calendar.ReturnDate(dayNumb);     
    }
}