我想對應用程式中的所有按鈕使用顯式導航。但是對于某些按鈕,我想保留“選擇右側”以使用自動導航(例如:我知道左、上和下的下一個按鈕,但我不知道下一個右按鈕)。
uj5u.com熱心網友回復:
如果設定了值,您需要創建一個Selectable
可以使用顯式導航的自定義。您可以將此代碼用于您的案例,只需在需要使用自動導航的檢查器中留下空白欄位。
using UnityEngine;
using UnityEngine.UI;
namespace UI.CustomSelectable
{
public class CustomSelectable : Selectable
{
[SerializeField]
private Selectable upSelectable;
[SerializeField]
private Selectable downSelectable;
[SerializeField]
private Selectable leftSelectable;
[SerializeField]
private Selectable rightSelectable;
public override Selectable FindSelectableOnUp()
{
return upSelectable != null ? upSelectable : base.FindSelectableOnUp();
}
public override Selectable FindSelectableOnDown()
{
return downSelectable != null ? downSelectable : base.FindSelectableOnDown();
}
public override Selectable FindSelectableOnLeft()
{
return leftSelectable != null ? leftSelectable : base.FindSelectableOnLeft();
}
public override Selectable FindSelectableOnRight()
{
return rightSelectable != null ? rightSelectable : base.FindSelectableOnRight();
}
}
}
uj5u.com熱心網友回復:
我基于重寫的 Find...() 方法思想撰寫了一個自定義按鈕類。也許它對其他人有用。它為原始答案添加了一些便利功能,例如可能的候選候選串列和檢查器按鈕,以自動填充您的候選候選。
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace YourNameSpace
{
/// <summary>
/// Adds lists for each navigation direction.
/// The first valid selectable in each list will be used or (if none is valid)
/// then auto navigation will be used as fallback.
/// </summary>
public class ButtonSmartNavigation : Button
{
public List<Selectable> UpSelectables;
public List<Selectable> DownSelectables;
public List<Selectable> LeftSelectables;
public List<Selectable> RightSelectables;
public override Selectable FindSelectableOnUp()
{
var upSelectable = getFirstSelectable(UpSelectables, this.navigation.selectOnUp);
return upSelectable != null ? upSelectable : base.FindSelectableOnUp();
}
public override Selectable FindSelectableOnDown()
{
var downSelectable = getFirstSelectable(DownSelectables, this.navigation.selectOnDown);
return downSelectable != null ? downSelectable : base.FindSelectableOnDown();
}
public override Selectable FindSelectableOnLeft()
{
var leftSelectable = getFirstSelectable(LeftSelectables, this.navigation.selectOnLeft);
return leftSelectable != null ? leftSelectable : base.FindSelectableOnLeft();
}
public override Selectable FindSelectableOnRight()
{
var rightSelectable = getFirstSelectable(RightSelectables, this.navigation.selectOnRight);
return rightSelectable != null ? rightSelectable : base.FindSelectableOnRight();
}
protected Selectable getFirstSelectable(List<Selectable> list, Selectable defaultExplicit)
{
if (list == null)
return null;
for (int i = 0; i < list.Count; i )
{
if (list[i] != null && list[i].IsInteractable() && list[i].gameObject.activeInHierarchy)
{
return list[i];
}
}
return defaultExplicit;
}
public void AddUpSelectable(Selectable selectable, bool prioritize = false)
{
addSelectable(UpSelectables, selectable, prioritize);
}
public void AddDownSelectable(Selectable selectable, bool prioritize = false)
{
addSelectable(DownSelectables, selectable, prioritize);
}
public void AddLeftSelectable(Selectable selectable, bool prioritize = false)
{
addSelectable(LeftSelectables, selectable, prioritize);
}
public void AddRightSelectable(Selectable selectable, bool prioritize = false)
{
addSelectable(RightSelectables, selectable, prioritize);
}
protected void addSelectable(List<Selectable> list, Selectable selectable, bool prioritize)
{
if (list == null)
{
list = new List<Selectable>();
}
if (prioritize)
{
list.Insert(0, selectable);
}
else
{
list.Add(selectable);
}
}
public void Clear()
{
UpSelectables.Clear();
DownSelectables.Clear();
LeftSelectables.Clear();
RightSelectables.Clear();
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(ButtonSmartNavigation), true)]
[CanEditMultipleObjects]
public class ButtonSmartNavigationEditor : UnityEditor.UI.ButtonEditor
{
protected SerializedProperty upSelectables;
protected SerializedProperty downSelectables;
protected SerializedProperty leftSelectables;
protected SerializedProperty rightSelectables;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
var target = this.target as ButtonSmartNavigation;
if (upSelectables == null) upSelectables = serializedObject.FindProperty("UpSelectables");
if (downSelectables == null) downSelectables = serializedObject.FindProperty("DownSelectables");
if (leftSelectables == null) leftSelectables = serializedObject.FindProperty("LeftSelectables");
if (rightSelectables == null) rightSelectables = serializedObject.FindProperty("RightSelectables");
EditorGUILayout.LabelField("Smart Navigation", EditorStyles.boldLabel);
GUILayout.BeginHorizontal();
if (GUILayout.Button("Up"))
{
target.UpSelectables.Clear();
target.AddUpSelectable(target.FindSelectableOnUp());
EditorUtility.SetDirty(target);
}
if (GUILayout.Button("Down"))
{
target.DownSelectables.Clear();
target.AddDownSelectable(target.FindSelectableOnDown());
EditorUtility.SetDirty(target);
}
if (GUILayout.Button("Left"))
{
target.LeftSelectables.Clear();
target.AddLeftSelectable(target.FindSelectableOnLeft());
EditorUtility.SetDirty(target);
}
if (GUILayout.Button("Right"))
{
target.RightSelectables.Clear();
target.AddRightSelectable(target.FindSelectableOnRight());
EditorUtility.SetDirty(target);
}
if (GUILayout.Button("Clear"))
{
target.Clear();
EditorUtility.SetDirty(target);
}
GUILayout.EndHorizontal();
serializedObject.Update();
EditorGUILayout.PropertyField(upSelectables, new GUIContent("Up Selectables"));
EditorGUILayout.PropertyField(downSelectables, new GUIContent("Down Selectables"));
EditorGUILayout.PropertyField(leftSelectables, new GUIContent("Left Selectables"));
EditorGUILayout.PropertyField(rightSelectables, new GUIContent("Right Selectables"));
serializedObject.ApplyModifiedProperties();
}
}
#endif
}
uj5u.com熱心網友回復:
根據其他答案,我撰寫了自己的帶有混合導航的按鈕版本。為了避免重新定義欄位,我重用了selectOnXXX
Selectable 的欄位,但在對應的情況下,我避免呼叫base.FindSelectableOnXXX
方法,因為它們使用導航模式,并且為了設定selectOnXXX
欄位(至少在 Inspector Normal 模式下),您希望使用 Explicit 模式或欄位不會出現。
因此,我直接使用FindSelectable
(base.FindSelectableOnXXX
自動時由方法呼叫)。navigation.mode
因此被忽略(至少在涉及方向時)。
/// HybridNavigationButton mixes Explicit and Automatic navigation
/// It ignores navigation.mode for directions (if None, it will still disable selection
/// in Selectable.OnPointerDown).
/// It's not possible to force set no Selectable in a given direction, as null is
/// considered a no-override, but this should cover most cases of bad Automatic navigation.
public class HybridNavigationButton : Button
{
// In each directional method, use selectable set for navigation as an override
// If not set, fallback to Automatic navigation, calling FindSelectable directly
// to avoid depending on navigation.mode
public override Selectable FindSelectableOnLeft()
{
return navigation.selectOnLeft != null ? navigation.selectOnLeft
: FindSelectable(Vector3.left);
}
public override Selectable FindSelectableOnRight()
{
return navigation.selectOnRight != null ? navigation.selectOnRight
: FindSelectable(Vector3.right);
}
public override Selectable FindSelectableOnUp()
{
return navigation.selectOnUp != null ? navigation.selectOnUp
: FindSelectable(Vector3.up);
}
public override Selectable FindSelectableOnDown()
{
return navigation.selectOnDown != null ? navigation.selectOnDown
: FindSelectable(Vector3.down);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/506397.html
上一篇:父串列視圖中的兩個串列視圖構建器但不呈現。只有可見的,而不是一次渲染
下一篇:替換所有特殊字符,期望第一次出現