De focus buiten het UI-object houden

Pagina bijgewerkt :
Aanmaakdatum van pagina :

Verificatie omgeving

Ramen
  • Vensters 11
Unity-editor
  • 2020.3.25f1

Vereisten voor deze tip

De volgende instellingen zijn vooraf gemaakt als voorwaarde voor de uitleg van deze tips.

Wat vond je nuttig in deze tip?

Het originele verhaal stond ergens, maar ik kon het niet vinden door op trefwoorden te zoeken.

Informatie over Focus

Unity UI-objecten kunnen, net als elke andere app, een focus hebben die aangeeft dat ze actief zijn als invoerdoelen. Als u echter op iets anders dan het object klikt of aanraakt, verdwijnt het object met focus. Het is mogelijk dat het niet mogelijk is om bewerkingen met een toetsenbord of gamepad te accepteren.

In dit gedeelte wordt beschreven hoe u scripts kunt gebruiken om de scherpstelling te regelen, zodat deze de scherpstelling niet verliest in een pseudo. Houd er rekening mee dat deze ondersteuning geen Unity-functie is en ervoor kan zorgen dat u even de focus verliest.

Plaatsing van objecten

Het type object doet er niet toe bij de scherpstelling, dus plaats het op de juiste manier.

Het is gekleurd zodat het gemakkelijk te zien is dat het scherp is.

Voorlopig, als je het in deze staat uitvoert, kun je zien dat als je op een lege plaats klikt nadat het object de focus heeft gekregen, het de focus verliest.

Controle zodat je de focus niet verliest

Maak hiervoor een script. De naam van het script kan van alles zijn, maar FocusRequired laat het staan als .

Voer de code als volgt in:

using System.Collections;
using System.Linq;                 // 追加
using UnityEngine;
using UnityEngine.EventSystems;    // 追加
using UnityEngine.UI;              // 追加

public class FocusRequired : MonoBehaviour
{
  /// <summary>
  /// <see cref="Selectable"/> をフックするクラスです。
  /// </summary>
  private class SelectionHooker : MonoBehaviour, IDeselectHandler
  {
    /// <summary>親コンポーネント。</summary>
    public FocusRequired Restrictor;

    /// <summary>
    /// 選択解除時にそれまで選択されていたオブジェクトを覚えておく。
    /// </summary>
    /// <param name="eventData"></param>
    public void OnDeselect(BaseEventData eventData)
    {
      Restrictor.PreviousSelection = eventData.selectedObject;
    }
  }

  /// <summary>選択させないオブジェクト一覧。</summary>
  [SerializeField] private GameObject[] NotSelectables;

  /// <summary>直前まで選択されていたオブジェクト。</summary>
  private GameObject PreviousSelection = null;

  /// <summary>
  /// 選択対象のオブジェクト一覧。
  /// </summary>
  private GameObject[] _selectables;

  private void Awake()
  {
    // すべての Selectable を取得する
    var selectableList = (FindObjectsOfType(typeof(Selectable)) as Selectable[]).ToList();

    // 選択除外がある場合は外す
    if (NotSelectables != null)
    {
      foreach (var item in NotSelectables)
      {
        var sel = item?.GetComponent<Selectable>();
        if (sel != null) selectableList.Remove(sel);
      }
    }

    _selectables = selectableList.Select(x => x.gameObject).ToArray();

    // フォーカス許可オブジェクトに SelectionHooker をアタッチ
    foreach (var selectable in this._selectables)
    {
      var hooker = selectable.AddComponent<SelectionHooker>();
      hooker.Restrictor = this;
    }

    // フォーカス制御用コルーチンをスタート
    StartCoroutine(RestrictSelection());
  }

  /// <summary>
  /// フォーカス制御処理。
  /// </summary>
  /// <returns></returns>
  private IEnumerator RestrictSelection()
  {
    while (true)
    {
      // 別なオブジェクトを選択するまで待機
      yield return new WaitUntil(
          () => (EventSystem.current != null) && (EventSystem.current.currentSelectedGameObject != PreviousSelection));

      // まだオブジェクトを未選択、または許可リストを選択しているなら何もしない
      if ((PreviousSelection == null) || _selectables.Contains(EventSystem.current.currentSelectedGameObject))
      {
        continue;
      }

      // 選択しているものがなくなった、または許可していない Selectable を選択した場合は前の選択に戻す
      EventSystem.current.SetSelectedGameObject(PreviousSelection);
    }
  }
}

Ik zal niet te veel in detail treden, maar Wat ik doe is het huidige selectieobject behouden, en als "het geselecteerde object is verdwenen" of "Ik heb een object geselecteerd dat ik niet wil selecteren", keer ik terug naar de vorige selectie.

Dit onderdeel kan worden bevestigd aan elk bestaand object, dus EventSystem bevestig het aan .

Aangezien het mogelijk is om het object dat u niet als eigenschap wilt selecteren op te geven, laten we proberen een knop te plaatsen die u niet wilt selecteren.

Not Selectables knop is ingesteld op .

Probeer het uit te voeren om te zien hoe het werkt. Klik eerst op een object om het te selecteren en klik vervolgens op een leeg gebied zodat het de focus niet verliest.

U kunt er ook voor zorgen dat de focus niet wordt verplaatst als u op een knop klikt die is ingesteld om niet te worden geselecteerd.