Beispiel #1
0
 public override string ToString()
 {
     System.Text.StringBuilder sb = new System.Text.StringBuilder();
     foreach (var material in materials)
     {
         if (material && material.IsValid)
         {
             if (material.MakingType == MakingType.SingleItem)
             {
                 sb.Append("[");
                 sb.Append(material.ItemName);
                 sb.Append("] × ");
                 sb.Append(material.Amount);
             }
             else
             {
                 sb.Append("<");
                 sb.Append(ZetanUtility.GetInspectorName(material.MaterialType));
                 sb.Append("> × ");
                 sb.Append(material.Amount);
             }
             if (materials.IndexOf(material) != materials.Count - 1)
             {
                 sb.Append("\n");
             }
         }
     }
     return(sb.ToString());
 }
Beispiel #2
0
    protected override void DrawAdditionalProperty(SerializedProperty objective, Rect rect, ref int lineCount)
    {
        SerializedProperty canNavigate  = objective.FindPropertyRelative("canNavigate");
        SerializedProperty showMapIcon  = objective.FindPropertyRelative("showMapIcon");
        SerializedProperty auxiliaryPos = objective.FindPropertyRelative("auxiliaryPos");

        EditorGUI.PropertyField(new Rect(rect.x, rect.y + lineHeightSpace * lineCount, rect.width * 0.5f, lineHeight), showMapIcon, new GUIContent("显示地图图标"));
        lineCount++;
        if (showMapIcon.boolValue)
        {
            EditorGUI.PropertyField(new Rect(rect.x + rect.width * 0.5f, rect.y + lineHeightSpace * (lineCount - 1), rect.width * 0.5f, lineHeight),
                                    canNavigate, new GUIContent("可导航"));
            auxiliaryPos.objectReferenceValue = EditorGUI.ObjectField(new Rect(rect.x, rect.y + lineHeightSpace * lineCount, rect.width, lineHeight),
                                                                      "检查点", auxiliaryPos.objectReferenceValue, typeof(CheckPointInformation), false);
            lineCount++;
        }
        SerializedProperty itemToUseHere = objective.FindPropertyRelative("itemToUseHere");

        new ObjectSelectionDrawer <ItemBase>(itemToUseHere, "_name", i => ZetanUtility.GetInspectorName(i.ItemType), itemCache,
                                             "需在此处使用的道具").DoDraw(new Rect(rect.x, rect.y + lineHeightSpace * lineCount, rect.width, lineHeight));
        lineCount++;
    }
 public static ItemSearchProvider Create(IEnumerable <ItemBase> objects, Action <ItemBase> selectCallback)
 {
     return(Create <ItemSearchProvider>(objects, selectCallback, "选择道具", i => i.Name, i => ZetanUtility.GetInspectorName(i.ItemType), i => i.Icon ? i.Icon.texture : null, ItemComparer.Default.Compare));
 }
 public static void OpenWindow(SearchWindowContext context, IEnumerable <ItemBase> objects, Action <ItemBase> selectCallback)
 {
     OpenWindow <ItemSearchProvider>(context, objects, selectCallback, "选择道具", i => i.Name, i => ZetanUtility.GetInspectorName(i.ItemType), i => i.Icon ? i.Icon.texture : null, ItemComparer.Default.Compare);
 }
    public override void OnInspectorGUI()
    {
        serializedObject.UpdateIfRequiredOrScript();
        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(normalizedTime, new GUIContent("进入时间"));
        EditorGUILayout.PropertyField(state, new GUIContent("主状态"));
        DrawSubState(state.enumValueIndex, subState);
        EditorGUILayout.PropertyField(exitNormalizedTime, new GUIContent("退出时间"));
        EditorGUILayout.PropertyField(exitState, new GUIContent("主状态"));
        DrawSubState(exitState.enumValueIndex, exitSubState);
        if (EditorGUI.EndChangeCheck())
        {
            serializedObject.ApplyModifiedProperties();
        }

        void DrawSubState(int enumValueIndex, SerializedProperty subState)
        {
            switch ((CharacterStates)enumValueIndex)
            {
            case CharacterStates.Normal:
                DrawField(typeof(CharacterNormalStates));
                break;

            case CharacterStates.Abnormal:
                DrawField(typeof(CharacterAbnormalStates));
                break;

            case CharacterStates.Gather:
                DrawField(typeof(CharacterGatherStates));
                break;

            case CharacterStates.Attack:
                DrawField(typeof(CharacterAttackStates));
                break;

            case CharacterStates.Busy:
                DrawField(typeof(CharacterBusyStates));
                break;

            default:
                break;
            }

            void DrawField(Type enumType)
            {
                List <int>    values = new List <int>();
                List <string> names  = new List <string>();

                foreach (var value in Enum.GetValues(enumType))
                {
                    values.Add((int)value);
                    names.Add(ZetanUtility.GetInspectorName((Enum)value));
                }
                int min = values.Min();

                if (subState.intValue < min)
                {
                    subState.intValue = min;
                }
                int max = values.Max();

                if (subState.intValue > max)
                {
                    subState.intValue = max;
                }
                subState.intValue = EditorGUILayout.IntPopup("子状态", subState.intValue, names.ToArray(), values.ToArray());
            }
        }
    }
    public ConditionGroupDrawer(SerializedObject owner, SerializedProperty property, float lineHeight, float lineHeightSpace, string listTitle = "条件列表")
    {
        this.owner           = owner;
        this.property        = property;
        this.lineHeightSpace = lineHeightSpace;
        SerializedProperty conditions = property.FindPropertyRelative("conditions");

        npcSelectors = new Dictionary <int, ObjectSelectionDrawer <TalkerInformation> >();
        var talkers = Resources.LoadAll <TalkerInformation>("").Where(x => x.Enable).ToArray();
        var quests  = Resources.LoadAll <Quest>("").Where(x => x != (owner.targetObject as Quest)).ToArray();

        List = new ReorderableList(property.serializedObject, conditions, true, true, true, true)
        {
            drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
            {
                owner.UpdateIfRequiredOrScript();
                SerializedProperty condition     = conditions.GetArrayElementAtIndex(index);
                SerializedProperty type          = condition.FindPropertyRelative("type");
                ConditionType      conditionType = (ConditionType)type.enumValueIndex;
                EditorGUI.PropertyField(new Rect(rect.x + 8, rect.y, rect.width * 0.2f, lineHeight), condition, new GUIContent("条件[" + index + "]"), false);
                EditorGUI.BeginChangeCheck();
                EditorGUI.PropertyField(new Rect(rect.x + rect.width * 0.2f + 8, rect.y, rect.width * 0.8f - 8, lineHeight),
                                        type, new GUIContent(string.Empty), true);
                if (condition.isExpanded)
                {
                    switch (conditionType)
                    {
                    case ConditionType.CompleteQuest:
                    case ConditionType.AcceptQuest:
                        SerializedProperty day          = condition.FindPropertyRelative("intValue");
                        SerializedProperty relatedQuest = condition.FindPropertyRelative("relatedQuest");
                        new ObjectSelectionDrawer <Quest>(relatedQuest, "title", quests, "对应任务").DoDraw(new Rect(rect.x, rect.y + lineHeightSpace * 1, rect.width, lineHeight));
                        if (relatedQuest.objectReferenceValue == owner.targetObject as Quest)
                        {
                            relatedQuest.objectReferenceValue = null;
                        }
                        day.intValue = EditorGUI.IntSlider(new Rect(rect.x, rect.y + lineHeightSpace * 2, rect.width, lineHeight), "后第几天", day.intValue, 0, 30);
                        break;

                    case ConditionType.HasItem:
                        SerializedProperty relatedItem = condition.FindPropertyRelative("relatedItem");
                        new ObjectSelectionDrawer <ItemBase>(relatedItem, "_name", i => ZetanUtility.GetInspectorName(i.ItemType), "",
                                                             "对应道具").DoDraw(new Rect(new Rect(rect.x, rect.y + lineHeightSpace, rect.width, lineHeight)));
                        break;

                    case ConditionType.Level:
                        SerializedProperty level       = condition.FindPropertyRelative("intValue");
                        SerializedProperty compareType = condition.FindPropertyRelative("compareType");
                        EditorGUI.PropertyField(new Rect(rect.x, rect.y + lineHeightSpace * 1, rect.width, lineHeight), compareType, new GUIContent("比较方式"));
                        EditorGUI.PropertyField(new Rect(rect.x, rect.y + lineHeightSpace * 2, rect.width, lineHeight), level, new GUIContent("对应等级"));
                        if (level.intValue < 1)
                        {
                            level.intValue = 1;
                        }
                        break;

                    case ConditionType.TriggerSet:
                    case ConditionType.TriggerReset:
                        EditorGUI.PropertyField(new Rect(rect.x, rect.y + lineHeightSpace, rect.width, lineHeight),
                                                condition.FindPropertyRelative("triggerName"), new GUIContent("触发器名称"));
                        break;

                    case ConditionType.NPCIntimacy:
                        int lineCount               = 1;
                        SerializedProperty npc      = condition.FindPropertyRelative("relatedCharInfo");
                        SerializedProperty intimacy = condition.FindPropertyRelative("intValue");
                        compareType = condition.FindPropertyRelative("compareType");
                        if (!npcSelectors.TryGetValue(index, out var selector))
                        {
                            selector = new ObjectSelectionDrawer <TalkerInformation>(npc, "_name", talkers, "条件对象");
                            npcSelectors.Add(index, selector);
                        }
                        selector.DoDraw(new Rect(rect.x, rect.y + lineHeightSpace * lineCount, rect.width, lineHeight));
                        lineCount++;
                        EditorGUI.PropertyField(new Rect(rect.x, rect.y + lineHeightSpace * lineCount, rect.width, lineHeight), npc, new GUIContent("对象引用"), false);
                        lineCount++;
                        EditorGUI.PropertyField(new Rect(rect.x, rect.y + lineHeightSpace * lineCount, rect.width, lineHeight), intimacy, new GUIContent("亲密度"));
                        lineCount++;
                        EditorGUI.PropertyField(new Rect(rect.x, rect.y + lineHeightSpace * lineCount, rect.width, lineHeight), compareType, new GUIContent("比较方式"));
                        lineCount++;
                        break;

                    default: break;
                    }
                }
                if (EditorGUI.EndChangeCheck())
                {
                    owner.ApplyModifiedProperties();
                }
            },

            elementHeightCallback = (int index) =>
            {
                if (index < 0 || index > conditions.arraySize - 1)
                {
                    return(0);
                }
                SerializedProperty condition     = conditions.GetArrayElementAtIndex(index);
                SerializedProperty type          = condition.FindPropertyRelative("type");
                ConditionType      conditionType = (ConditionType)type.enumValueIndex;
                if (condition.isExpanded)
                {
                    switch (conditionType)
                    {
                    case ConditionType.CompleteQuest:
                    case ConditionType.AcceptQuest:
                    case ConditionType.Level:
                        return(3 * lineHeightSpace);

                    case ConditionType.NPCIntimacy:
                        return(5 * lineHeightSpace);

                    case ConditionType.HasItem:
                    case ConditionType.TriggerSet:
                    case ConditionType.TriggerReset:
                        return(2 * lineHeightSpace);

                    default: return(lineHeightSpace);
                    }
                }
                else
                {
                    return(lineHeightSpace);
                }
            },

            onRemoveCallback = (list) =>
            {
                owner.UpdateIfRequiredOrScript();
                EditorGUI.BeginChangeCheck();
                if (EditorUtility.DisplayDialog("删除", "确定删除这个条件吗?", "确定", "取消"))
                {
                    list.Deselect(list.index);
                    conditions.DeleteArrayElementAtIndex(list.index);
                    npcSelectors.Clear();
                }
                if (EditorGUI.EndChangeCheck())
                {
                    owner.ApplyModifiedProperties();
                }
            },

            onCanRemoveCallback = (list) =>
            {
                return(list.IsSelected(list.index));
            },

            drawHeaderCallback = (rect) =>
            {
                int notCmpltCount = 0;
                for (int i = 0; i < conditions.arraySize; i++)
                {
                    SerializedProperty condition     = conditions.GetArrayElementAtIndex(i);
                    SerializedProperty type          = condition.FindPropertyRelative("type");
                    ConditionType      conditionType = (ConditionType)type.enumValueIndex;
                    switch (conditionType)
                    {
                    case ConditionType.CompleteQuest:
                    case ConditionType.AcceptQuest:
                        if (condition.FindPropertyRelative("relatedQuest").objectReferenceValue == null)
                        {
                            notCmpltCount++;
                        }
                        break;

                    case ConditionType.HasItem:
                        if (condition.FindPropertyRelative("relatedItem").objectReferenceValue == null)
                        {
                            notCmpltCount++;
                        }
                        break;

                    case ConditionType.Level:
                        if (condition.FindPropertyRelative("intValue").intValue < 1)
                        {
                            notCmpltCount++;
                        }
                        break;

                    case ConditionType.TriggerSet:
                    case ConditionType.TriggerReset:
                        if (!string.IsNullOrEmpty(condition.FindPropertyRelative("triggerName").stringValue))
                        {
                            notCmpltCount++;
                        }
                        break;

                    default: break;
                    }
                }
                EditorGUI.LabelField(rect, listTitle, "数量:" + conditions.arraySize + (notCmpltCount > 0 ? "\t未补全:" + notCmpltCount : string.Empty));
            },

            drawNoneElementCallback = (rect) =>
            {
                EditorGUI.LabelField(rect, "空列表");
            }
        };
    }
    public MaterialListDrawer(SerializedObject owner, SerializedProperty property, float lineHeight, float lineHeightSpace, string listTitle = "材料列表")
    {
        this.owner = owner;
        List       = new ReorderableList(owner, property, true, true, true, true)
        {
            drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
            {
                SerializedProperty material     = property.GetArrayElementAtIndex(index);
                SerializedProperty materialType = material.FindPropertyRelative("materialType");
                SerializedProperty makingType   = material.FindPropertyRelative("makingType");
                SerializedProperty item         = material.FindPropertyRelative("item");
                SerializedProperty amount       = material.FindPropertyRelative("amount");

                string headLabel = $"[{index}] (空)";
                if (item.objectReferenceValue && (MakingType)makingType.enumValueIndex == MakingType.SingleItem)
                {
                    headLabel = $"[{index}] {(item.objectReferenceValue as ItemBase).Name}";
                }
                else if ((MakingType)makingType.enumValueIndex == MakingType.SameType)
                {
                    headLabel = $"[{index}] {ZetanUtility.GetInspectorName((MaterialType)materialType.enumValueIndex)}";
                }
                EditorGUI.LabelField(new Rect(rect.x, rect.y, rect.width, lineHeight), headLabel);
                EditorGUI.PropertyField(new Rect(rect.x + rect.width / 2f, rect.y, rect.width / 2f, lineHeight), makingType, new GUIContent(string.Empty));
                if (makingType.enumValueIndex == (int)MakingType.SameType)
                {
                    var typeBef = materialType.enumValueIndex;
                    EditorGUI.PropertyField(new Rect(rect.x, rect.y + lineHeightSpace, rect.width, lineHeight), materialType, new GUIContent("所需种类"));
                    if (typeBef != materialType.enumValueIndex)
                    {
                        for (int i = 0; i < property.arraySize; i++)
                        {
                            if (i != index)
                            {
                                SerializedProperty element       = property.GetArrayElementAtIndex(i);
                                SerializedProperty eMaterialType = element.FindPropertyRelative("materialType");
                                SerializedProperty eMakingType   = element.FindPropertyRelative("makingType");
                                SerializedProperty eItem         = element.FindPropertyRelative("item");
                                if (eMakingType.enumValueIndex == (int)MakingType.SingleItem)
                                {
                                    if (eItem.objectReferenceValue is ItemBase ei)
                                    {
                                        if (ei.MaterialType == (MaterialType)materialType.enumValueIndex)
                                        {
                                            EditorUtility.DisplayDialog("错误", $"与第 {i + 1} 个材料的道具类型冲突", "确定");
                                            materialType.enumValueIndex = typeBef;
                                        }
                                    }
                                }
                                else
                                {
                                    if ((MaterialType)materialType.enumValueIndex != MaterialType.None && eMaterialType.enumValueIndex == materialType.enumValueIndex)
                                    {
                                        EditorUtility.DisplayDialog("错误", $"第 {i + 1} 个材料已使用该类型", "确定");
                                        materialType.enumValueIndex = typeBef;
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    var itemBef = item.objectReferenceValue;
                    EditorGUI.PropertyField(new Rect(rect.x, rect.y + lineHeightSpace, rect.width, lineHeight), item, new GUIContent("所需材料"));
                    if (itemBef != item.objectReferenceValue && item.objectReferenceValue is ItemBase itemNow)
                    {
                        for (int i = 0; i < property.arraySize; i++)
                        {
                            if (i != index)
                            {
                                SerializedProperty element       = property.GetArrayElementAtIndex(i);
                                SerializedProperty eMaterialType = element.FindPropertyRelative("materialType");
                                SerializedProperty eMakingType   = element.FindPropertyRelative("makingType");
                                if (eMakingType.enumValueIndex == (int)MakingType.SameType)
                                {
                                    if (itemNow.MaterialType == (MaterialType)eMaterialType.enumValueIndex)
                                    {
                                        EditorUtility.DisplayDialog("错误", $"第 {i + 1} 个材料的类型 [{ZetanUtility.GetInspectorName((MaterialType)eMaterialType.enumValueIndex)}] 已包括这个道具", "确定");
                                        item.objectReferenceValue = itemBef;
                                    }
                                }
                            }
                        }
                    }
                }
                EditorGUI.PropertyField(new Rect(rect.x, rect.y + lineHeightSpace * 2, rect.width, lineHeight),
                                        amount, new GUIContent("所需数量"));
                if (amount.intValue < 1)
                {
                    amount.intValue = 1;
                }
            },

            elementHeightCallback = (int index) =>
            {
                return(3 * lineHeightSpace);
            },

            onAddCallback = (list) =>
            {
                property.InsertArrayElementAtIndex(property.arraySize);
                SerializedProperty material = property.GetArrayElementAtIndex(property.arraySize - 1);
                list.Select(property.arraySize - 1);
                SerializedProperty materialType = material.FindPropertyRelative("materialType");
                materialType.enumValueIndex = (int)MaterialType.None;
                SerializedProperty makingType = material.FindPropertyRelative("makingType");
                makingType.enumValueIndex = (int)MakingType.SingleItem;
                SerializedProperty item = material.FindPropertyRelative("item");
                item.objectReferenceValue = null;
                SerializedProperty amount = material.FindPropertyRelative("amount");
                amount.intValue = 1;
            },

            onRemoveCallback = (list) =>
            {
                if (EditorUtility.DisplayDialog("删除", "确定删除这个道具吗?", "确定", "取消"))
                {
                    ReorderableList.defaultBehaviours.DoRemoveButton(list);
                }
            },

            onCanRemoveCallback = (list) =>
            {
                return(list.IsSelected(list.index));
            },

            drawHeaderCallback = (rect) =>
            {
                int notCmpltCount = 0;
                SerializedProperty material;
                for (int i = 0; i < property.arraySize; i++)
                {
                    material = property.GetArrayElementAtIndex(i);
                    if (material.FindPropertyRelative("makingType").enumValueIndex == (int)MakingType.SingleItem && !material.FindPropertyRelative("item").objectReferenceValue)
                    {
                        notCmpltCount++;
                    }
                }
                EditorGUI.LabelField(rect, listTitle, notCmpltCount > 0 ? "未补全:" + notCmpltCount : string.Empty);
            },

            drawNoneElementCallback = (rect) =>
            {
                EditorGUI.LabelField(rect, "空列表");
            }
        };
    }