private void OnEnable() { questCache = Resources.LoadAll <Quest>("Configuration"); quest = target as Quest; talkerCache = Resources.LoadAll <TalkerInformation>("Configuration").Where(x => x.Enable).ToArray(); holder = talkerCache.FirstOrDefault(x => x.QuestsStored.Contains(quest)); itemCache = Resources.LoadAll <ItemBase>("Configuration"); lineHeight = EditorGUIUtility.singleLineHeight; lineHeightSpace = lineHeight + 2; _ID = serializedObject.FindProperty("_ID"); title = serializedObject.FindProperty("title"); description = serializedObject.FindProperty("description"); abandonable = serializedObject.FindProperty("abandonable"); group = serializedObject.FindProperty("group"); questType = serializedObject.FindProperty("questType"); repeatFrequancy = serializedObject.FindProperty("repeatFrequancy"); timeUnit = serializedObject.FindProperty("timeUnit"); acceptCondition = serializedObject.FindProperty("acceptCondition"); beginDialogue = serializedObject.FindProperty("beginDialogue"); ongoingDialogue = serializedObject.FindProperty("ongoingDialogue"); completeDialogue = serializedObject.FindProperty("completeDialogue"); rewardItems = serializedObject.FindProperty("rewardItems"); _NPCToSubmit = serializedObject.FindProperty("_NPCToSubmit"); cmpltObjctvInOrder = serializedObject.FindProperty("cmpltObjctvInOrder"); objectives = serializedObject.FindProperty("objectives"); groupSelector = new ObjectSelectionDrawer <QuestGroup>(group, "_name", "", "归属组", "无"); npcSelector = new ObjectSelectionDrawer <TalkerInformation>(_NPCToSubmit, "_name", talkerCache, "在此NPC处提交", "接取处NPC"); acceptConditionDrawer = new ConditionGroupDrawer(serializedObject, acceptCondition, lineHeight, lineHeightSpace, "接取条件列表"); rewardDrawer = new ItemAmountListDrawer(serializedObject, rewardItems, lineHeight, lineHeightSpace, "奖励列表"); HandlingObjectiveList(); showState = new AnimBool(objectives.isExpanded); AddAnimaListener(OnAnima); }
private void OnEnable() { globalVariables = serializedObject.FindProperty("globalVariables"); presetVariables = serializedObject.FindProperty("presetVariables"); globalDrawer = new ObjectSelectionDrawer <GlobalVariables>(globalVariables, string.Empty, string.Empty, "全局变量"); InitGlobal(); }
private void OnEnable() { behaviour = serializedObject.FindProperty("behaviour"); frequency = serializedObject.FindProperty("frequency"); interval = serializedObject.FindProperty("interval"); startOnStart = serializedObject.FindProperty("startOnStart"); restartOnComplete = serializedObject.FindProperty("restartOnComplete"); resetOnRestart = serializedObject.FindProperty("resetOnRestart"); gizmos = serializedObject.FindProperty("gizmos"); presetVariables = serializedObject.FindProperty("presetVariables"); treeDrawer = new ObjectSelectionDrawer <BehaviourTree>(behaviour, string.Empty, string.Empty, "行为树"); InitTree(); }
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 override void OnInspectorGUI() { if (target is RuntimeBehaviourExecutor exe) { if (PrefabUtility.IsPartOfAnyPrefab(exe)) { EditorGUILayout.HelpBox("不能在预制件使用RuntimeBehaviourExecutor", MessageType.Error); return; } else { EditorGUILayout.HelpBox("只在本场景生效,若要制作预制件,请使用BehaviourExecutor", MessageType.Info); } } serializedObject.UpdateIfRequiredOrScript(); EditorGUI.BeginChangeCheck(); var hasTreeBef = behaviour.objectReferenceValue; if (target is not RuntimeBehaviourExecutor) { bool shouldDisable = Application.isPlaying && !PrefabUtility.IsPartOfAnyPrefab(target); EditorGUI.BeginDisabledGroup(shouldDisable); if (shouldDisable) { EditorGUILayout.PropertyField(behaviour, new GUIContent("行为树")); } else { treeDrawer.DoLayoutDraw(); } EditorGUI.EndDisabledGroup(); } if (behaviour.objectReferenceValue != hasTreeBef) { InitTree(); } if (behaviour.objectReferenceValue) { if (GUILayout.Button("编辑")) { BehaviourTreeEditor.CreateWindow(target as BehaviourExecutor); } serializedTree.UpdateIfRequiredOrScript(); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(serializedTree.FindProperty("_name")); EditorGUILayout.PropertyField(serializedTree.FindProperty("description")); if (EditorGUI.EndChangeCheck()) { serializedTree.ApplyModifiedProperties(); } } else { if (GUILayout.Button("新建")) { BehaviourTree tree = ZetanUtility.Editor.SaveFilePanel(CreateInstance <BehaviourTree>, "new behaviour tree"); if (tree) { behaviour.objectReferenceValue = tree; InitTree(); treeDrawer = new ObjectSelectionDrawer <BehaviourTree>(behaviour, string.Empty, string.Empty, "行为树"); EditorApplication.delayCall += delegate { BehaviourTreeEditor.CreateWindow(target as BehaviourExecutor); }; } } } EditorGUILayout.PropertyField(frequency, new GUIContent("执行频率")); if (frequency.enumValueIndex == (int)BehaviourExecutor.Frequency.FixedTime) { EditorGUILayout.PropertyField(interval, new GUIContent("间隔(秒)")); } EditorGUILayout.BeginHorizontal(); EditorGUILayout.PropertyField(startOnStart, new GUIContent("开始时执行")); EditorGUILayout.PropertyField(restartOnComplete, new GUIContent("完成时重启")); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PropertyField(resetOnRestart, new GUIContent("重启时重置")); EditorGUILayout.PropertyField(gizmos, new GUIContent("显示Gizmos")); EditorGUILayout.EndHorizontal(); if (EditorGUI.EndChangeCheck()) { serializedObject.ApplyModifiedProperties(); } if (behaviour.objectReferenceValue) { serializedTree.UpdateIfRequiredOrScript(); showList.target = EditorGUILayout.Foldout(serializedVariables.isExpanded, "行为树共享变量", true); if (EditorGUILayout.BeginFadeGroup(showList.faded)) { variableList.DoLayoutList(); } EditorGUILayout.EndFadeGroup(); if (target is not RuntimeBehaviourExecutor && !Application.isPlaying && !ZetanUtility.IsPrefab((target as BehaviourExecutor).gameObject)) { showPreset.target = EditorGUILayout.Foldout(presetVariables.isExpanded, "变量预设列表", true); if (EditorGUILayout.BeginFadeGroup(showPreset.faded)) { presetVariableList.DoLayoutList(); } EditorGUILayout.EndFadeGroup(); } serializedTree.ApplyModifiedProperties(); } }