Dialogue System, Unity pausing if Dialogue node uses a Predicate

Thank you for the reply Brian, I should have posted that yes this same pause happens in a build, and also when testing on another machine.

In my early post: Improving Conditions: A Property Editor - #92 by LuDiChRiS

I was getting a pause in Edit mode whenever I clicked on a Node that had a predicate, and I resolved that by switching out Resources.LoadAll for: AssetDatabase.FindAssets(“t:Quest”). This sovled it, but could this be related?

private void BuildQuestList()
    {
        if (quests != null) return;
        quests = AssetDatabase.FindAssets("t:Quest")
            .Select(guid => AssetDatabase.LoadAssetAtPath<Quest>(AssetDatabase.GUIDToAssetPath(guid)))
            .ToDictionary(quest => quest.name, quest => quest);
    }

    private void BuildInventoryItemsList()
    {
        if (items != null) return;
        items = AssetDatabase.FindAssets("t:InventoryItem")
            .Select(guid => AssetDatabase.LoadAssetAtPath<InventoryItem>(AssetDatabase.GUIDToAssetPath(guid)))
            .ToDictionary(item => item.GetItemID(), item => item);
    }

That’s from the PredicatePropertyDrawer.cs Full script here:


using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using RPG.Quests;
using System.Linq;
using GameDevTV.Inventories;
using System;
using RPG.Stats;

namespace RPG.Core.Editor
{
    [CustomPropertyDrawer(typeof(Condition.Predicate))]
    public class PredicatePropertyDrawer : PropertyDrawer
    {
        private Dictionary<string, Quest> quests;
        private Dictionary<string, InventoryItem> items;

        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            SerializedProperty predicate = property.FindPropertyRelative("predicate");
            SerializedProperty parameters = property.FindPropertyRelative("parameters");
            SerializedProperty negate = property.FindPropertyRelative("negate");

            float propHeight = EditorGUI.GetPropertyHeight(predicate);
            position.height = propHeight;
            EditorGUI.PropertyField(position, predicate);
            //EditorGUI.PropertyField(negate.rectValue, predicate);

            PredicateType selectedPredicate = (PredicateType)predicate.enumValueIndex;

            if (selectedPredicate == PredicateType.Select) return; //Stop drawing if there's no predicate
            while (parameters.arraySize < 2)
            {
                parameters.InsertArrayElementAtIndex(0);
            }

            SerializedProperty parameterZero = parameters.GetArrayElementAtIndex(0);
            SerializedProperty parameterOne = parameters.GetArrayElementAtIndex(1); //Edit, was accidentally 0 in first draft

            if (selectedPredicate == PredicateType.HasQuest || selectedPredicate == PredicateType.CompletedQuest || selectedPredicate == PredicateType.CompletedObjective)
            {
                position.y += propHeight;
                DrawQuest(position, parameterZero);
                if (selectedPredicate == PredicateType.CompletedObjective)
                {
                    position.y += propHeight;
                    DrawObjective(position, parameterOne, parameterZero);
                }
            }

            if (selectedPredicate == PredicateType.PlayerHasItem || selectedPredicate == PredicateType.PlayerHasItems || selectedPredicate == PredicateType.PlayerHasItemEquipped)
            {
                position.y += propHeight;
                DrawInventoryItemList(position, parameterZero, selectedPredicate == PredicateType.PlayerHasItems, selectedPredicate == PredicateType.PlayerHasItemEquipped);
                if (selectedPredicate == PredicateType.PlayerHasItems)
                {
                    position.y += propHeight;
                    DrawIntSlider(position, "Qty Needed", parameterOne, 1, 100);
                }
            }

            if (selectedPredicate == PredicateType.HasLevel)
            {
                position.y += propHeight;
                DrawIntSlider(position, "Level Required", parameterZero, 1, 100);
            }

            if (selectedPredicate == PredicateType.MinimumTrait)
            {
                position.y += propHeight;
                DrawTrait(position, parameterZero);
                position.y += propHeight;
                DrawIntSlider(position, "Minimum", parameterOne, 1, 100);
            }

            if (selectedPredicate == PredicateType.NPCHasItem || selectedPredicate == PredicateType.NPCHasItems || selectedPredicate == PredicateType.NPCHasItemEquipped)
            {
                position.y += propHeight;
                DrawInventoryItemList(position, parameterZero, selectedPredicate == PredicateType.NPCHasItems, selectedPredicate == PredicateType.NPCHasItemEquipped);
                if (selectedPredicate == PredicateType.NPCHasItems)
                {
                    position.y += propHeight;
                    DrawIntSlider(position, "Qty Needed", parameterOne, 1, 100);
                }
            }

            position.y += propHeight;

            EditorGUI.PropertyField(position, negate);
        }

        private void DrawQuest(Rect position, SerializedProperty element)
        {
            BuildQuestList();
            var names = quests.Keys.ToList();

            int index = names.IndexOf(element.stringValue);

            EditorGUI.BeginProperty(position, new GUIContent("Quest:"), element);
            int newIndex = EditorGUI.Popup(position, "Quest:", index, names.ToArray());
            if (newIndex != index)
            {
                element.stringValue = names[newIndex];
            }

            EditorGUI.EndProperty();
        }

        void DrawObjective(Rect position, SerializedProperty element, SerializedProperty selectedQuest)
        {
            string questName = selectedQuest.stringValue;
            if (!quests.ContainsKey(questName))
            {
                EditorGUI.HelpBox(position, "Please Select A Quest", MessageType.Error);
                return;
            }

            List<string> references = new List<string>();
            List<string> descriptions = new List<string>();
            foreach (Quest.Objective objective in quests[questName].GetObjectives())
            {
                references.Add(objective.reference);
                descriptions.Add(objective.description);
            }
            int index = references.IndexOf(element.stringValue);
            EditorGUI.BeginProperty(position, new GUIContent("objective"), element);
            int newIndex = EditorGUI.Popup(position, "Objective:", index, descriptions.ToArray());
            if (newIndex != index)
            {
                element.stringValue = references[newIndex];
            }
            EditorGUI.EndProperty();
        }

        void DrawInventoryItemList(Rect position, SerializedProperty element, bool stackable = false, bool equipment = false)
        {
            BuildInventoryItemsList();
            var filteredItems = items.Where(pair =>
                (!stackable || pair.Value.IsStackable()) &&
                (!equipment || pair.Value is EquipableItem))
                .ToList();

            var displayNames = filteredItems.Select(pair => pair.Value.GetDisplayName()).ToArray();
            var ids = filteredItems.Select(pair => pair.Key).ToArray();

            int index = Array.IndexOf(ids, element.stringValue);
            EditorGUI.BeginProperty(position, new GUIContent("Item"), element);
            int newIndex = EditorGUI.Popup(position, "Item", index, displayNames);
            if (newIndex != index) element.stringValue = ids[newIndex];
            EditorGUI.EndProperty();
        }


        void DrawTrait(Rect position, SerializedProperty element)
        {
            if (!Enum.TryParse(element.stringValue, out Trait trait))
            {
                trait = Trait.Strength;
            }
            EditorGUI.BeginProperty(position, new GUIContent("Trait"), element);
            Trait newTrait = (Trait)EditorGUI.EnumPopup(position, "Trait:", trait);
            if (newTrait != trait)
            {
                element.stringValue = $"{newTrait}";
            }
            EditorGUI.EndProperty();
        }

        private void BuildQuestList()
        {
            if (quests != null) return;
            quests = AssetDatabase.FindAssets("t:Quest")
                .Select(guid => AssetDatabase.LoadAssetAtPath<Quest>(AssetDatabase.GUIDToAssetPath(guid)))
                .ToDictionary(quest => quest.name, quest => quest);
        }

        private void BuildInventoryItemsList()
        {
            if (items != null) return;
            items = AssetDatabase.FindAssets("t:InventoryItem")
                .Select(guid => AssetDatabase.LoadAssetAtPath<InventoryItem>(AssetDatabase.GUIDToAssetPath(guid)))
                .ToDictionary(item => item.GetItemID(), item => item);
        }


        public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
        {
            SerializedProperty predicate = property.FindPropertyRelative("predicate");
            float propHeight = EditorGUI.GetPropertyHeight(predicate);
            PredicateType selectedPredicate = (PredicateType)predicate.enumValueIndex;
            switch (selectedPredicate)
            {
                case PredicateType.Select: //No parameters, we only want the bare enum. 
                    return propHeight;
                case PredicateType.HasLevel:       //All of these take 1 parameter
                case PredicateType.CompletedQuest:
                case PredicateType.HasQuest:
                case PredicateType.PlayerHasItem:
                case PredicateType.PlayerHasItems:
                case PredicateType.PlayerHasItemEquipped:
                case PredicateType.NPCHasItem:
                case PredicateType.NPCHasItems:
                case PredicateType.NPCHasItemEquipped:
                    return propHeight * 3.0f; //Predicate + one parameter + negate
                case PredicateType.CompletedObjective: //All of these take 2 parameters
                case PredicateType.MinimumTrait:
                    return propHeight * 4.0f; //Predicate + 2 parameters + negate;
            }
            return propHeight * 2.0f;
        }

        private static void DrawIntSlider(Rect position, string caption, SerializedProperty intParameter, int minLevel = 1, int maxLevel = 100)
        {
            EditorGUI.BeginProperty(position, new GUIContent(caption), intParameter);
            if (!int.TryParse(intParameter.stringValue, out int value))
            {
                value = 1;
            }
            EditorGUI.BeginChangeCheck();
            int result = EditorGUI.IntSlider(position, caption, value, minLevel, maxLevel);
            if (EditorGUI.EndChangeCheck())
            {
                intParameter.stringValue = $"{result}";
            }
            EditorGUI.EndProperty();
        }
    }
}


Also I was curious how you could tell from the Profiler image that it is the Quest and Inventory GetFromID methods that are the cause. Thanks for your help