UI ऑब्जेक्ट से फ़ोकस को बाहर रखना

पेज अद्यतन :
पेज निर्माण की तारीख :

सत्यापन परिवेश

विंडोज़
  • विंडोज 11
एकता संपादक
  • 2020.3.25एफ1

इस टिप के लिए आवश्यक शर्तें

इन युक्तियों के स्पष्टीकरण के लिए एक शर्त के रूप में निम्नलिखित सेटिंग्स अग्रिम रूप से बनाई गई हैं।

आपको इस टिप में क्या मददगार लगा?

मूल कहानी कहीं थी, लेकिन मैं इसे कीवर्ड खोजकर नहीं ढूंढ सका।

फोकस के बारे में

यूनिटी यूआई ऑब्जेक्ट्स, किसी भी अन्य ऐप की तरह, एक फोकस हो सकता है जो इंगित करता है कि वे इनपुट लक्ष्य के रूप में सक्रिय हैं। हालाँकि, यदि आप ऑब्जेक्ट के अलावा किसी अन्य चीज़ को क्लिक या स्पर्श करते हैं, तो फ़ोकस वाली वस्तु गायब हो जाएगी। कीबोर्ड या गेमपैड के साथ संचालन स्वीकार करना संभव नहीं हो सकता है।

यह खंड वर्णन करता है कि फ़ोकस को नियंत्रित करने के लिए स्क्रिप्टिंग का उपयोग कैसे करें ताकि यह छद्म में फ़ोकस न खोए। ध्यान दें कि यह समर्थन एकता सुविधा नहीं है और इससे आप एक पल के लिए फ़ोकस खो सकते हैं।

ऑब्जेक्ट प्लेसमेंट

फोकस नियंत्रण में ऑब्जेक्ट का प्रकार मायने नहीं रखता है, इसलिए इसे उचित रूप से रखें।

यह रंगीन है ताकि यह देखना आसान हो कि यह फोकस में है।

कुछ समय के लिए, यदि आप इसे इस स्थिति में चलाते हैं, तो आप देख सकते हैं कि यदि आप ऑब्जेक्ट को फ़ोकस प्राप्त करने के बाद खाली जगह पर क्लिक करते हैं, तो यह फ़ोकस खो देगा।

नियंत्रण करें ताकि आप फोकस न खोएं

ऐसा करने के लिए, एक स्क्रिप्ट बनाएँ। स्क्रिप्ट का नाम कुछ भी हो सकता है, लेकिन FocusRequired इसे .

कोड निम्नानुसार दर्ज करें:

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

मैं बहुत अधिक विस्तार में नहीं जाऊंगा, लेकिन मैं जो कर रहा हूं वह वर्तमान चयन ऑब्जेक्ट को रख रहा है, और यदि "चयनित ऑब्जेक्ट चला गया है" या "मैंने एक ऑब्जेक्ट चुना है जिसे मैं चयनित नहीं करना चाहता", तो मैं पिछले चयन पर वापस आ रहा हूं।

यह घटक मौजूद किसी भी वस्तु से जुड़ा हो सकता है, इसलिए EventSystem इसे .

चूंकि उस ऑब्जेक्ट को निर्दिष्ट करना संभव है जिसे आप संपत्ति के रूप में नहीं चुनना चाहते हैं, आइए एक बटन रखने का प्रयास करें जिसे आप चुनना नहीं चाहते हैं।

Not Selectables बटन पर सेट है।

यह देखने के लिए इसे चलाने का प्रयास करें कि यह कैसे काम करता है। सबसे पहले, इसे चुनने के लिए किसी ऑब्जेक्ट पर क्लिक करें, और फिर एक खाली क्षेत्र पर क्लिक करें ताकि यह फोकस न खोए।

आप यह भी सुनिश्चित कर सकते हैं कि अचयनित होने के लिए सेट किए गए बटन पर क्लिक करने से फ़ोकस नहीं चलता है.