Mantenir el focus fora de l'objecte de la interfície d'usuari

Pàgina actualitzada :
Data de creació de la pàgina :

Entorn de verificació

Windows
  • Finestres 11
Editor d'unitat
  • 25.3.2020

Requisits previs per a aquest consell

Els següents paràmetres s'han fet amb antelació com a requisit previ per a l'explicació d'aquests consells.

Què t'ha semblat útil en aquest consell?

La història original estava en algun lloc, però no la trobava cercant paraules clau.

Sobre el focus

Els objectes Unity UI, com qualsevol altra aplicació, poden tenir un focus que indiqui que estan actius com a objectius d'entrada. No obstant això, si feu clic o toqueu qualsevol altra cosa que no sigui l'objecte, l'objecte enfocat desapareixerà. És possible que no sigui possible acceptar operacions amb teclat o gamepad.

Aquesta secció descriu com utilitzar scripts per controlar el focus de manera que no perdi el focus en un pseudo. Tingueu en compte que aquest suport no és una funció Unity i us pot fer perdre el focus per un moment.

Col·locació d'objectes

El tipus d'objecte no importa en el control del focus, així que col·loqueu-lo adequadament.

Està acolorit de manera que sigui fàcil veure que està enfocat.

De moment, si l'executeu en aquest estat, podeu veure que si feu clic en un lloc buit després que l'objecte rebi el focus, perdrà el focus.

Control per no perdre el focus

Per fer-ho, creeu un script. El nom de l'script pot ser qualsevol cosa, però FocusRequired deixeu-lo com .

Introdueix el codi de la següent manera:

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

No entraré en massa detalls, però El que faig és mantenir l'objecte de selecció actual, i si "l'objecte seleccionat ha desaparegut" o "he seleccionat un objecte que no vull que sigui seleccionat", estic revertint a la selecció anterior.

Aquest component es pot adjuntar a qualsevol objecte que existeixi, de manera EventSystem que adjunteu-lo a .

Com que és possible especificar l'objecte que no voleu que se seleccioni com a propietat, intentem col·locar un botó que no vulgueu seleccionar.

Not Selectables està definit com a .

Proveu d'executar-lo per veure com funciona. Primer, feu clic sobre un objecte per seleccionar-lo i, a continuació, feu clic a una àrea buida perquè no perdi el focus.

També podeu assegurar-vos que fer clic en un botó definit com a no seleccionat no mogui el focus.