A fókusz távoltartása a felhasználói felületi objektumtól

Oldal frissítve :
Oldal létrehozásának dátuma :

Ellenőrzési környezet

Windows
  • Windows 11 esetén
Unity-szerkesztő
  • 2020.3.25f1

A tipp előfeltételei

A következő beállításokat előre elvégeztük a tippek magyarázatának előfeltételeként.

Mit talált hasznosnak ebben a tippben?

Az eredeti történet valahol volt, de kulcsszavakra keresve nem találtam meg.

A Fókuszról

A Unity felhasználói felületi objektumai, mint bármely más alkalmazás, rendelkezhetnek olyan fókuszsal, amely azt jelzi, hogy bemeneti célként aktívak. Ha azonban az objektumon kívül bármi másra kattint vagy koppint, a fókuszban lévő objektum eltűnik. Előfordulhat, hogy billentyűzettel vagy játékvezérlővel nem lehet műveleteket fogadni.

Ez a szakasz leírja, hogyan lehet szkriptekkel vezérelni a fókuszt, hogy ne veszítse el a fókuszt egy pszeudo-ban. Vegye figyelembe, hogy ez a támogatás nem Unity-funkció, és egy pillanatra elveszítheti a fókuszt.

Objektum elhelyezése

Az objektum típusa nem számít a fókuszvezérlésben, ezért helyezze el megfelelően.

Színes, hogy könnyen látható legyen, hogy fókuszban van.

Egyelőre, ha ebben az állapotban futtatja, láthatja, hogy ha egy üres helyre kattint, miután az objektum fókuszba került, elveszíti a fókuszt.

Irányítsa a fókuszt, hogy ne veszítse el a fókuszt

Ehhez hozzon létre egy szkriptet. A szkript neve bármi lehet, de FocusRequired hagyja meg a következőként: .

Írja be a kódot az alábbiak szerint:

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

Nem megyek bele túl sok részletbe, de Megtartom az aktuális kijelölési objektumot, és ha "a kijelölt objektum eltűnt" vagy "Kijelöltem egy objektumot, amelyet nem szeretnék kijelölni", akkor visszatérek az előző kijelöléshez.

Ez az összetevő bármely létező objektumhoz csatolható, ezért EventSystem csatolja a következőhöz: .

Mivel meg lehet adni azt az objektumot, amelyet nem szeretne tulajdonságként kiválasztani, próbáljunk meg elhelyezni egy gombot, amelyet nem szeretne kijelölni.

Not Selectables gomb értéke .

Próbálja meg futtatni, hogy lássa, hogyan működik. Először kattintson egy objektumra annak kiválasztásához, majd kattintson egy üres területre, hogy ne veszítse el a fókuszt.

Arról is gondoskodhat, hogy a ki nem jelölt gombra kattintva ne mozdítsa el a fókuszt.