Mantenir el focus fora de l'objecte de la interfície d'usuari
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.