예제 #1
0
        public void Next(string nodeId = null)
        {
            if (WaitingForChoices || !IsActive)
            {
                return;
            }

            if (ExitScheduled)
            {
                OnChatComplete();
                return;
            }

            ClearButtons();

            ChatNode node = chatIterator.GoToNext(nodeId);

            if (node == null)
            {
                Debug.LogError("Chat quit unexpectedly. Couldn't find a node to display.");
                OnChatComplete();
                return;
            }

            Debug.Log(node.Text);
            DialogueField.text = node.Text;

            ExitScheduled = node.IsLast;

            StopAllCoroutines();
            StartCoroutine(TypeSentence(node));
        }
예제 #2
0
        private ChatNode QueryNode(string query)
        {
            // This will never (at present) scan for choice nodes (may not ever need to).
            ChatNode nextNode = Collection.FirstOrDefault(node => node.Id == query);

            return(ValidateNode(nextNode) ? nextNode : null);
        }
예제 #3
0
        private IEnumerator TypeSentence(ChatNode node)
        {
            OnNext?.Invoke(node);

            NameField.text     = node.ActorName;
            DialogueField.text = "";

            foreach (char letter in node.Text.ToCharArray())
            {
                DialogueField.text += letter;
                yield return(null);
            }

            if (node.HasChoices)
            {
                WaitingForChoices = true;
                // Load choices available
                Debug.Log("Choices available: " + node.Choices.Count);

                // TODO: You'll have to somehow pass things with the nodes here. Perhaps make
                // a small class to pass, or, some sort of event listener?
                // Or however many you need...
                node.Choices.ForEach(choice =>
                {
                    GameObject ButtonObj = Instantiate(ChoiceButtonPrefab, ButtonContainer.transform.position, Quaternion.identity, ButtonContainer.transform);

                    ButtonObj.transform.Find("Text").GetComponent <Text>()
                    .text = choice.Text;

                    ButtonObj.GetComponent <Button>()
                    .onClick.AddListener(() =>
                    {
                        WaitingForChoices = false;
                        Next(choice.To);
                    });
                });
            }
            else if (NextButtonPrefab != null)
            {
                GameObject ButtonObj = Instantiate(NextButtonPrefab, ButtonContainer.transform.position, Quaternion.identity, ButtonContainer.transform);

                ButtonObj.transform.Find("Text").GetComponent <Text>()
                .text = "Next";

                ButtonObj.GetComponent <Button>()
                .onClick.AddListener(() => Next());
            }
        }
예제 #4
0
        public ChatNode GoToNext(string query = null)
        {
            if (ChatQueue.Count == 0 && query == null)
            {
                Log.Out("This seems to be the entry call for the conversation. You must pass a query to it.");
                return(null);
            }

            ChatNode CurrentNode = query != null?QueryNode(query) : ChatQueue.Dequeue();

            if (CurrentNode == null)
            {
                return(null);
            }

            if (CurrentNode.HasRoute)
            {
                ChatNode NextNode = QueryNode(CurrentNode.To);
                ChatQueue.Enqueue(NextNode);
            }

            if (CurrentNode.HasActions && CurrentNode.Actions.Any(action => action == EndConversationAction))
            {
                if (CurrentNode.Actions.Any(action => action == SaveConversationAction))
                {
                    // ... onSave, etc
                    ChainPosition = CurrentNode.Id;
                    Log.Out("Saved chain up to ID.");
                }

                if (CurrentNode.Actions.Any(action => action == CancelConversationAction))
                {
                    // ... onCancel, etc
                    Log.Out("Cancelled chain, nothing saved.");
                }

                CurrentNode.IsLast = true;
            }

            return(CurrentNode);
        }
예제 #5
0
        public void NextSentence(string specificPoint = null)
        {
            if (WaitingForChoices || !IsActive)
            {
                return;
            }

            if (ExitScheduled)
            {
                OnChatComplete();
                return;
            }

            NextButton.SetActive(false);

            if (ButtonContainer.transform.childCount > 0)
            {
                foreach (Transform child in ButtonContainer.transform)
                {
                    Destroy(child.gameObject);
                }
            }

            ChatNode node = chatIterator.GoToNext(specificPoint);

            if (node == null)
            {
                Debug.LogError("Chat quit unexpectedly.");
                OnChatComplete();
                return;
            }

            Debug.Log(node.Text);
            DialogueField.text = node.Text;

            ExitScheduled = node.IsLast;

            StopAllCoroutines();
            StartCoroutine(TypeSentence(node));
        }
예제 #6
0
        private bool ValidateNode(ChatNode node)
        {
            // TODO: Consts please for these errors.
            if (node == null)
            {
                Log.Out("There was a problem finding a node. Try running 'start' first.");
                return(false);
            }

            if (NodeDataNotValid(node))
            {
                Log.Out("The current node is invalid. It must have a 'to' OR 'choices', or, an 'endConversation' action if this was intended.");
                return(false);
            }

            if (NodeDataConflict(node))
            {
                Log.Out("The current node is invalid. It must have either 'to' OR 'choices', and not both.");
                return(false);
            }

            return(true);
        }
예제 #7
0
 private bool NodeDataConflict(ChatNode node) => node.To != null && node.HasChoices;
예제 #8
0
 private bool NodeDataNotValid(ChatNode node) => node.To == null &&
 !node.IsLast &&
 !node.HasChoices &&
 !node.HasActions;
예제 #9
0
 private bool NodeDataNotValid(ChatNode node) => node.To == null && !node.HasChoices && !node.Actions.Any(action => action == EndConversationAction);