Left click mouse won't work for Choice buttons in the Dialogue

Hi, I have my project so I don’t have the logic to call:

  • public bool HandleRaycast(PlayerController callingController)
  • GetCursorType()

So I created my script, and everything works, except one thing: I can’t click on the Choice buttons with the left-click mouse. But I can click on the next or close icon.

If I set, it in the script, right-click mouse it is working. But I need it for the left click as well. I thought it is some problem with the player attack, yes attack is triggered by left click mouse. So I disabled the attack. Did not work. I have tried to freeze everything by WindowFreezer script, same problem.

The only thing which is helping is when a player goes away and then I can hit the choice button. But this is nonsense - in real games, players can’t move when dialogue is triggered.

Can you help me, please? Not sure what is going on.

Here are the scripts:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace RPG.Dialogue
{
    public class AIConversant : MonoBehaviour
    {
        private bool playerInRange = false;
        private PlayerConversant playerConversant = null;

        [SerializeField] Dialogue dialogue;

        private void OnTriggerEnter2D(Collider2D other)
        {
            if (other.CompareTag("Player"))
            {
                playerInRange = true;

                playerConversant = other.GetComponent<PlayerConversant>();
                Debug.Log("Player entered range");
            }
        }

        private void OnTriggerExit2D(Collider2D other)
        {
            if (other.CompareTag("Player"))
            {
                playerInRange = false;
                playerConversant = null;
                Debug.Log("Player exited range");
            }
        }

        private void Update()
        {
            if (playerInRange && Input.GetButtonDown("Fire1")) // GetMouseButtonDown(0) -> WON'T WORK
            {
                Debug.Log("Clicked Ally");
                playerConversant.StartDialogue(dialogue);
            }
        }
    }
}

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

namespace RPG.Dialogue
{
    public class PlayerConversant : MonoBehaviour
    {
        Dialogue currentDialogue;
        DialogueNode currentNode = null;
        bool isChoosing = false;

        // public listener
        public event Action onConversationUpdated;

        public void StartDialogue(Dialogue newDialogue)
        {
            currentDialogue = newDialogue;
            currentNode = currentDialogue.GetRootNode();
            onConversationUpdated();
        }

        public void Quit()
        {
            currentDialogue = null;
            currentNode = null;
            isChoosing = false;
            onConversationUpdated();
        }

        public bool IsActive()
        {
            return currentDialogue != null;
        }

        public bool IsChoosing()
        {
            return isChoosing;
        }

        public string GetText()
        {
            if (currentNode == null)
            {
                return "";
            }

            return currentNode.GetText();

        }

        public IEnumerable<DialogueNode> GetChoices()
        {
            return currentDialogue.GetPlayerChildren(currentNode);
        }

        public void SelectChoice(DialogueNode chosenNode)
        {
            currentNode = chosenNode;
            isChoosing = false;
            Next();
        }

        public void Next()
        {
            int numPlayerResponses = currentDialogue.GetPlayerChildren(currentNode).Count();
            if (numPlayerResponses > 0)
            {
                isChoosing = true;
                onConversationUpdated();
                return;
            }

            DialogueNode[] children = currentDialogue.GetAIChildren(currentNode).ToArray();
            int randomIndex = UnityEngine.Random.Range(0, children.Count());
            currentNode = children[randomIndex];
            onConversationUpdated();
        }

        public bool HasNext()
        {
            return currentDialogue.GetAllChildren(currentNode).Count() > 0;
        }
    }
}


The first thing that comes to mind is that the buttons are not being given their actions.
Paste in your DialogueUI.cs script and we’ll take a look.

DialogueUI.cs script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using RPG.Dialogue;
using TMPro;
using UnityEngine.UI;

namespace RPG.UI
{
    public class DialogueUI : MonoBehaviour
    {
        PlayerConversant playerConversant;
        [SerializeField] TextMeshProUGUI AIText;
        [SerializeField] Button nextButton;
        [SerializeField] GameObject AIresponse;
        [SerializeField] Transform choiceRoot;
        [SerializeField] GameObject choicePrefab;
        [SerializeField] Button quitButton;
        [SerializeField] TextMeshProUGUI conversantName;

        // Start is called before the first frame update
        void Start()
        {
            playerConversant = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerConversant>();
            playerConversant.onConversationUpdated += UpdateUI;
            nextButton.onClick.AddListener(() => playerConversant.Next());
            quitButton.onClick.AddListener(() => playerConversant.Quit());
            
            UpdateUI();
        }

        // Update is called once per frame
        void UpdateUI()
        {
            gameObject.SetActive(playerConversant.IsActive());
            if (!playerConversant.IsActive())
            {
                return;
            }
            conversantName.text = playerConversant.GetCurrentConversantName();
            
            AIresponse.SetActive(!playerConversant.IsChoosing());
            choiceRoot.gameObject.SetActive(playerConversant.IsChoosing());

            if (playerConversant.IsChoosing())
            {
                BuildChoiceList();
            }
            else
            {
                AIText.text = playerConversant.GetText();
                nextButton.gameObject.SetActive(playerConversant.HasNext());
            }

        }

        private void BuildChoiceList()
        {
            foreach (Transform item in choiceRoot)
            {
                Destroy(item.gameObject);
            }

            foreach (DialogueNode choice in playerConversant.GetChoices())
            {
                GameObject choiceInstance = Instantiate(choicePrefab, choiceRoot);
                var textComp = choiceInstance.GetComponentInChildren<TextMeshProUGUI>();
                textComp.text = choice.GetText();
                Button button = choiceInstance.GetComponentInChildren<Button>();
                button.onClick.AddListener(() =>
                {
                    playerConversant.SelectChoice(choice);
                });
            }
        }
    }
}

Ok, so this looks correct.

So when you click on a the Next or close icon, things work as normal, but clicking on a choice doesn’t work.
What does happen when you click on a choice?

  • Nothing, you can’t even tell I’m clicking
  • The character swings it’s weapon
  • The dialogue starts over
  • Other, describe in detail.

When I disable the WindowFreezer (it was on the dialogue object) and click on a choice the character swings it’s weapon. Also I can assign no weapon to the player - so it means character cannot swing any weapon. Even with that it is impossible to click on choice button.

Next or Close works properly. Also when I click on the next button I can see short pressed effect. This effect is not visible on the option button. Seems the choice button is disabled. Is there some setup of the button in unity maybe that is the problem? But anyway, both of them (next, option button) are textMeshPro buttons from my point of view there is no reason why it is not working for a left click mouse.

Make sure that the prefab for the Choice buttons have the Button enabled and interactible. In fact, It couldn’t hurt to add

button.interactable=true;

to the foreach loopin BuildChoiceList immediately after instantiating it.

In terms of other things occurring when the click is pressed, that’s actually best handled in whatever code is responding to the click…
For example: If you have code like this

if(Input.GetMouseButtonDown(0)) Attack();

Put some code before it that prevents that attack if the mouse is over the Dialogue

if(EventSystem.current.IsPointerOverGameObject()) return;
if(Input.GetMouseButtondown(0)) Attack();

Thank you Brian.

I tried but it has’t worked. I investigated little bit and I found out this:

  1. When I click on choice button, event listener: Selected:null
  2. When I am clicking on choice button e.g. 35times, Console: Clicked character (35)
  3. When I click anywhere in unity (project window, scene window…) and click back on the choice button it works. event listener: ChoiceButton(Clone) (UnityEngine.GameObject). Console: no Clicked character

The problem was this if statement in AI conversant: if (playerInRange && Input.GetButtonDown(“Fire1”))
Statement was still true after dialogue was opened. So a added at the end of the if : playerInRange = false;
And it is working.

Code snippet:

 private void Update()
        {
            if (playerInRange && Input.GetButtonDown("Fire1")) // GetMouseButtonDown(0) -> WON'T WORK
            {
                Debug.Log("Clicked character");
                playerConversant.StartDialogue(this, dialogue);
                playerInRange = false;
            }
        }

Still not clear why I was able to click on next/close button. Or why I was able to click on choice button after I click somewhere else. If you have any thoughts let me know.

Privacy & Terms