Как узнать, какая кнопка была нажата?(Единство / Hololens2 / MRTK) - PullRequest
0 голосов
/ 23 сентября 2019

У меня есть около 10 кнопок, каждая из которых добавляет уникальное значение через скрипт.Я хочу знать, какая кнопка была нажата при взаимодействии с кнопками с помощью MRTK.

Я попытался добавить метод updateField к кнопке, которая получает выбранный в данный момент объект с использованием EventSystem по умолчанию.Однако, когда я отлаживаю, значение равно нулю.

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

NullReferenceException: ссылка на объект не установлена ​​на экземпляр объекта UpdateInputField.UpdateField () (в Assets / Scripts / 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..SDK / Возможности / UX / Интерактивные / Сценарии / События / InteractableOnPressReceiver.cs: 71) Microsoft.MixedReality.Toolkit.UI.Interactable.InternalUpdate () (в Assets / MixedRealityToolkit.SDK / Features / UX / Interactable / Scripts.cs: 525) Microsoft.MixedReality.Toolkit.UI.Interactable.Update () (в разделе Активы / MixedRealityToolkit.SDK / Возможности / UX / Взаимодействующий / Scripts / Interactable.cs: 506)

Ответы [ 3 ]

2 голосов
/ 23 сентября 2019

Относительно исключения

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);
    }
}
0 голосов
/ 24 сентября 2019

решено !!Я добавил слушателя на каждую кнопку в методе запуска.Затем вызывается функция для получения компонентов этих объектов.

Вот как я это сделал ............

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);     
    }
}
0 голосов
/ 24 сентября 2019

Следующий код напечатает название каждой кнопки, которая была нажата в сцене.Обратите внимание, что вместо добавления прослушивателей событий при запуске вы можете просто добавить эти прослушиватели при создании кнопок из кода.

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"));
        }
    }
}
...