Halten des Fokus außerhalb des UI-Objekts

Diese Seite wurde aktualisiert :
Erstellungsdatum der Seite :

Verifikations-Umgebung

Fenster
  • Windows 11
Unity-Editor
  • 2020.3.25f1

Voraussetzungen für diesen Tipp

Die folgenden Einstellungen wurden im Vorfeld als Voraussetzung für die Erklärung dieser Tipps vorgenommen.

Was fanden Sie an diesem Tipp hilfreich?

Die ursprüngliche Geschichte war irgendwo, aber ich konnte sie nicht finden, indem ich nach Schlüsselwörtern suchte.

Über Focus

Unity-UI-Objekte können wie jede andere App einen Fokus haben, der angibt, dass sie als Eingabeziele aktiv sind. Wenn Sie jedoch auf etwas anderes als das Objekt klicken oder es berühren, wird das Objekt mit dem Fokus ausgeblendet. Es ist möglicherweise nicht möglich, Vorgänge mit einer Tastatur oder einem Gamepad zu akzeptieren.

In diesem Abschnitt wird beschrieben, wie Sie mithilfe von Skripts den Fokus steuern, damit er in einem Pseudo nicht den Fokus verliert. Beachten Sie, dass es sich bei dieser Unterstützung nicht um eine Unity-Funktion handelt, die dazu führen kann, dass Sie für einen Moment den Fokus verlieren.

Objekt-Platzierung

Die Art des Objekts spielt bei der Fokussteuerung keine Rolle, also platzieren Sie es entsprechend.

Es ist so eingefärbt, dass man leicht erkennen kann, dass es scharf ist.

Wenn Sie es in diesem Zustand ausführen, können Sie sehen, dass es den Fokus verliert, wenn Sie auf eine leere Stelle klicken, nachdem das Objekt den Fokus erhalten hat.

Kontrolle, damit Sie den Fokus nicht verlieren

Erstellen Sie dazu ein Skript. Der Name des Skripts kann beliebig sein, aber FocusRequired belassen Sie es bei .

Geben Sie den Code wie folgt ein:

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

Ich werde nicht zu sehr ins Detail gehen, aber Was ich tue, ist, das aktuelle Auswahlobjekt beizubehalten, und wenn "das ausgewählte Objekt verschwunden ist" oder "Ich habe ein Objekt ausgewählt, das nicht ausgewählt werden soll", kehre ich zur vorherigen Auswahl zurück.

Diese Komponente kann an jedes vorhandene Objekt angehängt werden.EventSystem

Da es möglich ist, das Objekt anzugeben, das nicht als Eigenschaft ausgewählt werden soll, versuchen wir, eine Schaltfläche zu platzieren, die Sie nicht auswählen möchten.

Not Selectables ist auf festgelegt.

Versuchen Sie, es auszuführen, um zu sehen, wie es funktioniert. Klicken Sie zunächst auf ein Objekt, um es auszuwählen, und klicken Sie dann auf einen leeren Bereich, damit es den Fokus nicht verliert.

Sie können auch sicherstellen, dass durch Klicken auf eine Schaltfläche, deren Auswahl aufgehoben werden soll, der Fokus nicht verschoben wird.