【问题标题】:How to know which button was clicked ? (Unity/Hololens2/MRTK)如何知道点击了哪个按钮? (Unity/Hololens2/MRTK)
【发布时间】:2019-09-24 19:56:38
【问题描述】:

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

我尝试向使用默认 EventSystem 获取当前选定对象的按钮添加一个 updateField 方法。但是,当我调试时,该值为 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/Features/UX/Interactable/Scripts/Events/InteractableOnPressReceiver.cs:71) Microsoft.MixedReality.Toolkit.UI.Interactable.InternalUpdate () (在 资产/MixedRealityToolkit.SDK/Features/UX/Interactable/Scripts/Interactable.cs:525) Microsoft.MixedReality.Toolkit.UI.Interactable.Update () (在 Assets/MixedRealityToolkit.SDK/Features/UX/Interactable/Scripts/Interactable.cs:506)

【问题讨论】:

  • 基于documentation,您可以像在默认的uGUI按钮中一样订阅按钮事件。或者使用来自interactable 功能的事件。

标签: unity3d hololens mrtk hololens-emulator


【解决方案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"));
        }
    }
}

【讨论】:

  • 感谢@Julia Schwarz,您的解决方案运行良好。
  • 关于如何将“Button1 was clicked”等输出字符串存储到变量中的任何想法?我想要做的是试图获取被点击的按钮的组件。就像是 button1 那么 (GameObject.Find("button1").GetComponent().CurrentNumber();)
【解决方案2】:

关于异常

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

提供了很多可能性。基本上每个. 之前的引用都可能是null。最有可能的是currentSelectedGameObject(当当前根本没有选择对象时)或GetComponent&lt;DayButton&gt;()(当所选对象根本没有这样的组件时)。


我对你的课程一无所知,对 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);
    }
}

【讨论】:

    【解决方案3】:

    解决了!! 我在 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);     
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-31
      • 1970-01-01
      • 2017-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多