Fokusa noturēšana ārpus UI objekta

Lapa atjaunota :
Lapas izveides datums :

Verifikācijas vide

Windows
  • Operētājsistēmā Windows 11
Vienotības redaktors
  • 2020.3.25f1

Priekšnoteikumi šim padomam

Tālāk norādītie iestatījumi ir veikti iepriekš kā priekšnoteikums šo padomu izskaidrošanai.

Kas jums šķita noderīgs šajā padomā?

Sākotnējais stāsts bija kaut kur, bet es to nevarēju atrast, meklējot atslēgvārdus.

Par fokusu

Unity UI objektiem, tāpat kā jebkurai citai programmai, var būt fokuss, kas norāda, ka tie ir aktīvi kā ievades mērķi. Tomēr, ja noklikšķināt vai pieskaraties kaut kam citam, nevis objektam, objekts ar fokusu pazudīs. Iespējams, nebūs iespējams pieņemt darbības ar tastatūru vai spēļu paneli.

Šajā sadaļā aprakstīts, kā izmantot skriptus, lai kontrolētu fokusu tā, lai tas nezaudētu fokusu pseido. Ņemiet vērā, ka šis atbalsts nav unity līdzeklis un var izraisīt to, ka uz brīdi zaudējat uzmanību.

Objektu izvietojums

Fokusa kontrolē objekta veidam nav nozīmes, tāpēc novietojiet to atbilstoši.

Tas ir krāsains tā, ka ir viegli redzēt, ka tas ir fokusā.

Pagaidām, ja jūs to palaižat šādā stāvoklī, jūs varat redzēt, ka, noklikšķinot uz tukšas vietas pēc tam, kad objekts saņem fokusu, tas zaudēs fokusu.

Kontrolējiet, lai nezaudētu fokusu

Lai to izdarītu, izveidojiet skriptu. Skripta nosaukums var būt jebkas, bet FocusRequired atstājiet to kā .

Ievadiet kodu šādi:

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

Es neiedziļināšos pārāk daudz detaļās, bet Tas, ko es daru, ir pašreizējā atlases objekta saglabāšana, un, ja "atlasītais objekts vairs nav" vai "Esmu atlasījis objektu, kuru nevēlos atlasīt", es atgriežos pie iepriekšējās atlases.

Šo komponentu var pievienot jebkuram esošam objektam, tāpēc EventSystem pievienojiet to .

Tā kā ir iespējams norādīt objektu, kuru nevēlaties atlasīt kā rekvizītu, mēģināsim ievietot pogu, kuru nevēlaties atlasīt.

Not Selectables Poga ir iestatīta uz .

Mēģiniet to palaist, lai redzētu, kā tas darbojas. Vispirms noklikšķiniet uz objekta, lai to atlasītu, un pēc tam noklikšķiniet uz tukša apgabala, lai tas nezaudētu fokusu.

Varat arī pārliecināties, ka, noklikšķinot uz pogas, kas ir iestatīta kā neatlasīta, fokuss netiek pārvietots.