Kohdistuksen pitäminen poissa käyttöliittymäobjektista

Sivu päivitetty :
Sivun luontipäivämäärä :

Varmennusympäristö

Windows
  • Windows 11
Unity-editori
  • 2020.3.25F1

Tämän vinkin edellytykset

Seuraavat asetukset on tehty etukäteen edellytyksenä näiden vinkkien selittämiselle.

Mikä oli mielestäsi hyödyllistä tässä vinkissä?

Alkuperäinen tarina oli jossain, mutta en löytänyt sitä etsimällä avainsanoja.

Tietoja Focusista

Unity-käyttöliittymäobjekteilla, kuten kaikilla muillakin sovelluksilla, voi olla kohdistus, joka ilmaisee, että ne ovat aktiivisia syötekohteina. Jos kuitenkin napsautat tai kosketat jotain muuta kuin objektia, kohdistettu objekti katoaa. Toimintoja ei ehkä ole mahdollista hyväksyä näppäimistöllä tai peliohjaimella.

Tässä osassa kuvataan, miten komentosarjoja käytetään tarkennuksen hallintaan, jotta se ei menetä kohdistusta pseudoon. Huomaa, että tämä tuki ei ole Unity-ominaisuus, ja se voi aiheuttaa keskittymisen menettämisen hetkeksi.

Objektien sijoittelu

Kohteen tyypillä ei ole merkitystä tarkennuksen ohjauksessa, joten sijoita se asianmukaisesti.

Se on värillinen niin, että on helppo nähdä, että se on tarkennettu.

Toistaiseksi, jos suoritat sen tässä tilassa, näet, että jos napsautat tyhjää paikkaa sen jälkeen, kun objekti on saanut tarkennuksen, se menettää tarkennuksen.

Hallitse, jotta et menetä keskittymistä

Voit tehdä tämän luomalla komentosarjan. Komentosarjan nimi voi olla mikä tahansa, mutta FocusRequired jätä se muotoon .

Syötä koodi seuraavasti:

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

En mene liikaa yksityiskohtiin, mutta Säilytän nykyisen valintaobjektin, ja jos "valittu objekti on poissa" tai "olen valinnut objektin, jota en halua valita", palaan edelliseen valintaan.

Tämä komponentti voidaan liittää mihin tahansa olemassa olevaan objektiin, joten EventSystem liitä se .

Koska on mahdollista määrittää objekti, jota et halua valita ominaisuudeksi, yritetään sijoittaa painike, jota et halua valita.

Not Selectables -painikkeen arvoksi on asetettu .

Kokeile suorittaa se nähdäksesi, miten se toimii. Napsauta ensin objektia valitaksesi sen ja napsauta sitten tyhjää aluetta, jotta se ei menetä tarkennusta.

Voit myös varmistaa, että painikkeen napsauttaminen, jonka valinta on poistettu, ei siirrä kohdistusta.