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()); }
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, "空列表"); } }; }