การกันโฟกัสออกจากวัตถุ 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
ปุ่มถูกตั้งค่าเป็น
ลองเรียกใช้เพื่อดูว่ามันทํางานอย่างไร ขั้นแรกให้คลิกที่วัตถุเพื่อเลือกจากนั้นคลิกที่พื้นที่ว่างเพื่อไม่ให้เสียโฟกัส
คุณยังสามารถตรวจสอบให้แน่ใจว่าการคลิกปุ่มที่ตั้งค่าให้ยกเลิกการเลือกจะไม่ย้ายโฟกัส