إبقاء التركيز خارج كائن واجهة المستخدم
بيئة التحقق
- نوافذ
-
- ويندوز ١١
- محرر الوحدة
-
- 2020.3.25f1
المتطلبات الأساسية لهذه النصيحة
تم إجراء الإعدادات التالية مسبقا كشرط أساسي لشرح هذه النصائح.
ما الذي وجدته مفيدا في هذه النصيحة؟
كانت القصة الأصلية في مكان ما ، لكنني لم أتمكن من العثور عليها من خلال البحث عن الكلمات الرئيسية.
عن فوكس
يمكن أن يكون لكائنات 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
تم تعيين الزر على .
حاول تشغيله لترى كيف يعمل. أولا ، انقر فوق كائن لتحديده ، ثم انقر فوق منطقة فارغة حتى لا يفقد التركيز.
يمكنك أيضا التأكد من أن النقر فوق زر تم تعيينه ليكون غير محدد لا يحرك التركيز.