Starting the dialog programatically

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
dkrusenstrahle
Posts: 39
Joined: Sat Apr 20, 2024 7:03 pm

Starting the dialog programatically

Post by dkrusenstrahle »

Hello,

How can I start a conversation by just standing next to the person and hitting "E". Not using the mouse to point.
Like I do for Quest machine where I have a script that detects if I am colliding with a Quest giver object and starting the conversation by hitting E. Is there something simular for Dialog System?

Thank you!
User avatar
Tony Li
Posts: 22108
Joined: Thu Jul 18, 2013 1:27 pm

Re: Starting the dialog programatically

Post by Tony Li »

Hi,

Here are two ways to do that:

Programmatically: Use DialogueManager.StartConversation()

Or use Proximity Selector.

BTW, you can also use Proximity Selector to start a Quest Machine QuestGiver's dialogue UI by configuring the QuestGiver's Usable component > OnUse() UnityEvent to call QuestGiver.StartDialogueWithPlayer().
dkrusenstrahle
Posts: 39
Joined: Sat Apr 20, 2024 7:03 pm

Re: Starting the dialog programatically

Post by dkrusenstrahle »

Nice which namespace should I use to access that?

I got this but it does not trigger the dialog.

Code: Select all

using UnityEngine;
using PixelCrushers.DialogueSystem;

namespace PixelCrushers.DialogueSystem
{
    public class CharacterDialogActivation : MonoBehaviour
    {
        private GameObject currentConversationist;

        private void Update()
        {
            if (currentConversationist != null && Input.GetKeyDown(KeyCode.E))
            {
                DialogueManager.StartConversation("WHAT TITLE?");
            }
        }

        private void OnTriggerEnter(Collider other)
        {
            Debug.Log(other);
            GameObject conversationist = other.GetComponent<GameObject>();
            if (conversationist != null)
            {
                currentConversationist = conversationist;
            }
        }

        private void OnTriggerExit(Collider other)
        {
            if (other.GetComponent<GameObject>() == currentConversationist)
            {
                currentConversationist = null;
            }
        }
    }
}

DialogueManager.StartConversation("WHAT TITLE?");

This method seem to need a title of the dialog but that should be up to the NPC not the player. Cannot hard code that.
User avatar
Tony Li
Posts: 22108
Joined: Thu Jul 18, 2013 1:27 pm

Re: Starting the dialog programatically

Post by Tony Li »

Hi,

You could put the script on the NPC, or put another script on the NPC that just has the NPC's conversation. However, in this case it might be simpler to just put a Dialogue System Trigger on the NPC and select the conversation in the Dialogue System Trigger:

Code: Select all

private void Update()
{
    if (currentConversationist != null && Input.GetKeyDown(KeyCode.E))
    {
        var dsTrigger = currentConversationist.GetComponent<DialogueSystemTrigger);
        if (dsTrigger != null) dsTrigger.OnUse(this.transform);
    }
}
Otherwise put a script on the NPC that has a conversation selection popup:

Code: Select all

public class NPCConversation : MonoBehaviour
{
    [ConversationPopup(true)] public string conversation;
}
and:

Code: Select all

private void Update()
{
    if (currentConversationist != null && Input.GetKeyDown(KeyCode.E))
    {
        DialogueManager.StartConversation(currentConversationist.GetComponent<NPCConversation>(), this.transform, currentConversationist.transform);
    }
}
dkrusenstrahle
Posts: 39
Joined: Sat Apr 20, 2024 7:03 pm

Re: Starting the dialog programatically

Post by dkrusenstrahle »

Thank you!

I ended up adding this script on the NPC:

Code: Select all

using UnityEngine;
using PixelCrushers.DialogueSystem;

public class CharacterDialogActivation : MonoBehaviour
    {
        private bool isPlayer = false;
        private GameObject indicator;

        private void Start()
        {
            Transform indicatorTransform = this.transform.Find("Indicator");

            if (indicatorTransform != null)
            {
                indicator = indicatorTransform.gameObject;
            }
        }

        private void Update()
        {
            if (isPlayer && Input.GetKeyDown(KeyCode.E))
            {
                var dsTrigger = GetComponent<DialogueSystemTrigger>();
                if (dsTrigger != null) dsTrigger.OnUse(this.transform);
            }
        }

        private void OnTriggerEnter(Collider other)
        {
            if (other.CompareTag("Player"))
            {
                isPlayer = true;
                indicator.SetActive(true);
            }
        }

        private void OnTriggerExit(Collider other)
        {
            isPlayer = false;
            if (indicator != null)
            {
                indicator.SetActive(false);
            }
        }
    }
And I make a simular script for the quest giver NPC:

Code: Select all

using UnityEngine;
using PixelCrushers.QuestMachine;

public class CharacterQuestGiverActivation : MonoBehaviour
    {
        private bool isPlayer = false;
        private QuestGiver currentQuestGiver;
        private GameObject indicator;

        private void Start()
        {
            Transform indicatorTransform = this.transform.Find("Indicator");

            if (indicatorTransform != null)
            {
                indicator = indicatorTransform.gameObject;
            }
        }
        private void Update()
        {
            if (currentQuestGiver != null && isPlayer && Input.GetKeyDown(KeyCode.E))
            {
                currentQuestGiver.StartDialogueWithPlayer();
            }
        }

        private void OnTriggerEnter(Collider other)
        {
            if (other.CompareTag("Player"))
            {
                currentQuestGiver = GetComponent<QuestGiver>();
                indicator.SetActive(true);
                isPlayer = true;
            }
        }

        private void OnTriggerExit(Collider other)
        {
            isPlayer = false;
            currentQuestGiver = null;
            if (indicator != null)
            {
                indicator.SetActive(false);
            }
        }
    }
I added a little ball (Indicator) object as a child to the character to show when in range for activation.
User avatar
Tony Li
Posts: 22108
Joined: Thu Jul 18, 2013 1:27 pm

Re: Starting the dialog programatically

Post by Tony Li »

Nice!
Whiclx
Posts: 1
Joined: Sat Jun 01, 2024 4:37 am

Re: Starting the dialog programatically

Post by Whiclx »

Hi, I'd just like to say thanks for the above answers.

As a non-coder, despite Dialogue System's great docs and a few hours of reading old forum posts, I'd been unable to figure out how to properly embed a DialogueSystemsTrigger.OnUse() into the Interaction system of the Cowsins systems "FPS Engine", as I didn't understand how to properly call the right object and its transform.

Code: Select all

                var dsTrigger = GetComponent<DialogueSystemTrigger>();
                if (dsTrigger != null) dsTrigger.OnUse(this.transform);
But the above snippet worked perfectly when placed into the "Interactable" script in the "Interact()" section.

After looking through a lot of old forum posts it shouldn't surprise me, but once again you've solved someone's problem before you even knew it existed, Tony. Cheers.
User avatar
Tony Li
Posts: 22108
Joined: Thu Jul 18, 2013 1:27 pm

Re: Starting the dialog programatically

Post by Tony Li »

Hi,

I'm glad that was helpful! :-)
Post Reply