การกันโฟกัสออกจากวัตถุ UI

ปรับปรุงหน้า :
วันที่สร้างเพจ :

สภาพแวดล้อมการตรวจสอบ

หน้าต่าง
  • หน้าต่าง 11
ตัวแก้ไขความสามัคคี
  • 2020.3.25f1

ข้อกําหนดเบื้องต้นสําหรับเคล็ดลับนี้

มีการตั้งค่าต่อไปนี้ล่วงหน้าเป็นข้อกําหนดเบื้องต้นสําหรับคําอธิบายของเคล็ดลับเหล่านี้

ท่านพบว่าอะไรมีประโยชน์ในเคล็ดลับนี้

เรื่องราวดั้งเดิมอยู่ที่ไหนสักแห่ง แต่ฉันไม่พบโดยการค้นหาคําหลัก

เกี่ยวกับ Focus

วัตถุ Unity UI เช่นเดียวกับแอปอื่นๆ สามารถมีโฟกัสที่ระบุว่าออบเจ็กต์เหล่านั้นทํางานเป็นเป้าหมายอินพุต อย่างไรก็ตามหากคุณคลิกหรือสัมผัสสิ่งอื่นนอกเหนือจากวัตถุวัตถุที่มีโฟกัสจะหายไป อาจไม่สามารถรับการทํางานกับแป้นพิมพ์หรือแป้นเกมได้

ส่วนนี้อธิบายวิธีใช้การเขียนสคริปต์เพื่อควบคุมโฟกัสเพื่อไม่ให้สูญเสียโฟกัสในหลอก โปรดทราบว่าการสนับสนุนนี้ไม่ใช่คุณสมบัติ Unity และอาจทําให้คุณสูญเสียโฟกัสไปชั่วขณะ

การจัดวางวัตถุ

ประเภทของวัตถุไม่สําคัญในการควบคุมโฟกัส ดังนั้นควรจัดวางอย่างเหมาะสม

มีสีเพื่อให้มองเห็นได้ง่ายว่าอยู่ในโฟกัส

ในขณะนี้หากคุณเรียกใช้ในสถานะนี้คุณจะเห็นว่าหากคุณคลิกที่พื้นที่ว่างหลังจากที่วัตถุได้รับโฟกัสวัตถุจะสูญเสียโฟกัส

ควบคุมเพื่อไม่ให้เสียโฟกัส

เมื่อต้องการทําสิ่งนี้ให้สร้างสคริปต์ ชื่อสคริปต์สามารถเป็นอะไรก็ได้ แต่ 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 ปุ่มถูกตั้งค่าเป็น

ลองเรียกใช้เพื่อดูว่ามันทํางานอย่างไร ขั้นแรกให้คลิกที่วัตถุเพื่อเลือกจากนั้นคลิกที่พื้นที่ว่างเพื่อไม่ให้เสียโฟกัส

คุณยังสามารถตรวจสอบให้แน่ใจว่าการคลิกปุ่มที่ตั้งค่าให้ยกเลิกการเลือกจะไม่ย้ายโฟกัส