使用布尔切换隐藏 ReorderableList 项目

Hiding ReorderableList Items With Boolean Toggle

我试图根据布尔切换的状态隐藏某些 ReorderableList 项。我目前得到的是一个空白项目,而不是根本没有项目。没有隐藏项目:

隐藏项目 1(点击切换):

代码如下:

Items.cs

using System;
using System.Collections.Generic;
using UnityEngine;
 
[CreateAssetMenu(fileName = "Items", menuName = "Items")]
public class Items : ScriptableObject
{
  public List<Item> itemList = new List<Item>();
}
 
[Serializable]
public class Item
{
  public bool isHidden = false;
  public string description;
}

Editor/ItemsEditorWindow.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
 
public class ItemsEditorWindow : EditorWindow
{
  private SerializedObject itemsSerializedObject;
  private SerializedProperty itemList;
  private ReorderableList reorderableItemList;
 
  [MenuItem("Tools/Items Editor Window")]
  private static void OpenWindow()
  {
    GetWindow<ItemsEditorWindow>("Items");
  }
 
  private void OnEnable()
  {
    string[] itemsGUIDS = AssetDatabase.FindAssets("t:Items");
 
    if (itemsGUIDS.Length == 0) return;
 
    string path = AssetDatabase.GUIDToAssetPath(itemsGUIDS[0]);
    var itemList = AssetDatabase.LoadAssetAtPath<Items>(path);
 
    this.itemsSerializedObject = new SerializedObject(itemList);
 
    InitializeItemList();
  }
 
  private void InitializeItemList()
  {
    this.itemList = this.itemsSerializedObject.FindProperty("itemList");
 
    this.reorderableItemList =
      new ReorderableList(
        this.itemsSerializedObject,
        this.itemList,
        draggable: true,
        displayHeader: true,
        displayAddButton: true,
        displayRemoveButton: true
      );
 
    this.reorderableItemList.drawElementCallback = DrawTaskListItem;
  }
 
  public void OnGUI()
  {
    this.itemsSerializedObject.Update();
 
    this.reorderableItemList.DoLayoutList();
 
    this.itemsSerializedObject.ApplyModifiedProperties();
  }
 
  private void DrawTaskListItem(Rect rect, int index, bool isActive, bool isFocused)
  {
    SerializedProperty item = this.reorderableItemList.serializedProperty.GetArrayElementAtIndex(index);
 
    SerializedProperty isHidden = item.FindPropertyRelative("isHidden");
    SerializedProperty description = item.FindPropertyRelative("description");
 
    if (isHidden.boolValue) return;
 
    float x = rect.x;
    float y = rect.y;
 
    y += EditorGUIUtility.standardVerticalSpacing;
 
    EditorGUI.PropertyField(
      new Rect(x, y, 17f, EditorGUIUtility.singleLineHeight),
      isHidden,
      GUIContent.none
    );
 
    x += 17f;
 
    EditorGUI.PropertyField(
      new Rect(x, y, 100f, EditorGUIUtility.singleLineHeight),
      description,
      GUIContent.none
    );
  }
}

尝试隐藏的代码是 DrawTaskListItem 中的 if (isHidden.boolValue) return;。由于这不起作用,我想知道是否有人可以告诉我正确的方法。谢谢!

编辑: 这非常接近,但我发现如果我最后一次隐藏,渲染就会搞砸。如果我隐藏其他任何一个,它似乎工作正常。 这是我在添加@derHugo 的代码并隐藏最后一项后看到的内容。

您还可以覆盖

reorderableItemList.elementHeightCallback = GetElementHeight;

然后

private void GetElementHeight(int index)
{
    SerializedProperty item = this.reorderableItemList.serializedProperty.GetArrayElementAtIndex(index);

    SerializedProperty isHidden = item.FindPropertyRelative("isHidden");
    SerializedProperty description = item.FindPropertyRelative("description");

    if (isHidden.boolValue) return 0;

    return EditorGUIUtility.singleLineHeight;
}

但是,如果您完全隐藏它们..那么您打算如何再次取消隐藏它们?

我没有找到解决渲染问题的方法。我没有尝试隐藏 ReorderableList 项目,而是最终将项目移动到另一个列表以“隐藏”它们,然后将它们移回以“显示”它们。这不是我希望的解决方案,但它确实有效。