Assign Image on dialogueNode to UI

Hey There,

I am currently working on a dialogue System with Character Images. Currently what I am trying to implement is on every dialogue in the scriptable object is to have Character Image of the Ai that is speaking. Currently I added in the dialogueNode (see screenshot).

        [SerializeField]
        Sprite charImage = null;

public Sprite GetImage()
        {
            return charImage;
        }

Currently this had been set to sprite, but in the dialogue UI it needs to change the current sprite Image on the image the assaignd sprite in the scriptable object. This is the code in the player conversant and DialogueUI. Any idea on how I can convert the sprite to change the image source?

PlayerConversant:
public Sprite GetCharacterImage()

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

            return currentNode.GetImage();
        }

DialogueUI:

private void BuildChoiceList()
        {
            foreach (Transform item in choiceRoot)
            {
                Destroy(item.gameObject);
            }
            choiceRoot.DetachChildren();
            foreach (DialogueNode choice in playerConversant.GetChoices())
            {
                GameObject choiceInstance = Instantiate(choicePrefab, choiceRoot);
                var textComp = choiceInstance.GetComponentInChildren<TextMeshProUGUI>();
                textComp.text = choice.GetText();

                //CharSpeaker Image
                Sprite choiceImage = choiceInstance.GetComponent<Image>().sprite = AiImage;
                choiceImage = choice.GetImage();

                Button button = choiceInstance.GetComponentInChildren<Button>();
                button.onClick.AddListener(() =>
                {
                    playerConversant.SelectChoice(choice);
                });
            }
        }

I don’t quite understand what the problem is. From context I am assuming you want to change the image.

This line sets the sprite to AiImage and also sets choiceImage to AiImage and then you just change the variable.

I’m not sure what AiImage is, but you probably just want something like

choiceInstance.GetComponent<Image>().sprite = choice.GetImage();

Sorry that is my fault that i forgot to mention the AiImage is the Serialize field.
[SerializeField] Image AiImage;

What I added is an sprite on my node. The the sprite that I selected on the current node needs to popup in the UI Image. So If a player sad something mean, the image would change from a smiling person to a sad person.

The struggle that I have is to connect the sprite in the DialogueNode with the image in my DialogueUI.

OK. So, I think I understand. Is the mouse the AI character? And you want to change that image depending on the choice?

I see in your inspector nothing is assigned to it

If my understanding is correct and I have all the objects correct, I think all you’d have to do is assign the image when the player makes a choice

Button button = choiceInstance.GetComponentInChildren<Button>();
button.onClick.AddListener(() =>
{
    AiImage.sprite = choice.GetImage();
    playerConversant.SelectChoice(choice);
});

Okay kind of worked. I added I added the code you send, But i moved it out of the button and it changes the image. But also the image source of the button

private void BuildChoiceList()
        {
            foreach (Transform item in choiceRoot)
            {
                Destroy(item.gameObject);
            }
            choiceRoot.DetachChildren();
            foreach (DialogueNode choice in playerConversant.GetChoices())
            {
                GameObject choiceInstance = Instantiate(choicePrefab, choiceRoot);
                var textComp = choiceInstance.GetComponentInChildren<TextMeshProUGUI>();
                textComp.text = choice.GetText();
                
                choiceInstance.GetComponent<Image>().sprite = choice.GetImage();
                AiImage.sprite = choice.GetImage();

                Button button = choiceInstance.GetComponentInChildren<Button>();
                button.onClick.AddListener(() =>
                {
                    playerConversant.SelectChoice(choice);
                });
            }
        }

now only it does not need to change the buttons. And update the image of the mouse back, when the mouse is speaking and not the player. Now it only change while the lion speaks, but does not change back.


I assume this is your button’s image. You shouldn’t have this line. This changes the button’s image

Okay thnx it workes. Sorry to bother you but I have one last question. Now that it changes the image when the lion is speaking, it won’t revert back to when the mouse is speaking. Link video: Expetion Wildlands Plein Android Unity 2020 3 31f1 Personal DX11 2022 08 11 21 51 18 - YouTube

The AiImage.sprite = choice.GetImage(); needs to get somehow updated.

public class DialogueUI : MonoBehaviour
    {
        PlayerConversant playerConversant;
        [SerializeField] TextMeshProUGUI AIText;
        [SerializeField] Button nextButton;
        [SerializeField] GameObject AIResponse;
        [SerializeField] Transform choiceRoot;
        [SerializeField] GameObject choicePrefab;
        [SerializeField] Image AiImage;
        [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());


            UpdateUI();
        }
        void UpdateUI()
        {
            gameObject.SetActive(playerConversant.IsActive());
            if (!playerConversant.IsActive())
            {
                return;
            }
            conversantName.text = playerConversant.GetCurrentConverstantName();
            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);
            }
            choiceRoot.DetachChildren();
            foreach (DialogueNode choice in playerConversant.GetChoices())
            {
                GameObject choiceInstance = Instantiate(choicePrefab, choiceRoot);
                var textComp = choiceInstance.GetComponentInChildren<TextMeshProUGUI>();
                textComp.text = choice.GetText();
                
                AiImage.sprite = choice.GetImage();

                Button button = choiceInstance.GetComponentInChildren<Button>();
                button.onClick.AddListener(() =>
                {
                    playerConversant.SelectChoice(choice);
                });
            }
        }
    }

Add the line AIImage.sprite = Choice.GetImage() to this else clause.

2 Likes

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms