Dialogue Variable Error with Ink

Hey, guys!

I’m new to Unity and trying to learn dialogue management for my new project. I was going pretty decent until I tried to make variables for each choice. I made another script called ‘DialogueVariables’ and tried to communicate with my ‘DialogueManager’. Yet, somehow my DialogueVariables script gives me an error which goes CS1061: Story’ does not contain a definition for ‘variableState’ and no accessible extension method ‘variableState’ accepting a first argument of type ‘Story’ could be found (are you missing a using directive or an assembly reference?). I don’t know what the problem is even though two scripts can communicate with each other. Here is my DialogueVariables script,

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Ink.Runtime;

public class DialogueVariables
{

public void StartListening(Story story)
{
    story.variableState.variableChangedEvent += VariableChanged;
}

public void StopListening(Story story)
{
    story.variableState.variableChangedEvent -= VariableChanged;
}

private void VariableChanged(string name, Ink.Runtime.Object value)
{
    Debug.Log("Variable changed " + name + " = " + value);
}

}

And here is the DialogueManager script (Sorry for the long script)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using Ink.Runtime;
using UnityEngine.EventSystems;

public class DialogueManager : MonoBehaviour
{
[Header(“Params”)]
[SerializeField] private float typingSpeed = 0.04f;

[Header("Dialogue UI")]
[SerializeField] private GameObject dialoguePanel;
[SerializeField] private GameObject continueIcon;
[SerializeField] private TextMeshProUGUI dialogueText;
[SerializeField] private TextMeshProUGUI displayNameText;
[SerializeField] private Animator portraitAnimator;
private Animator layoutAnimator;

[Header("Choices UI")]
[SerializeField] private GameObject[] choices;
private TextMeshProUGUI[] choicesText;

private Story currentStory;
public bool dialogueIsPlaying { get; private set; }

private bool canContinueToNextLine = false;

private Coroutine displayLineCoroutine;

private static DialogueManager instance;

private const string SPEAKER_TAG = "speaker";
private const string PORTRAIT_TAG = "portrait";

private DialogueVariables dialogueVariables;

private void Awake()
{
    if (instance != null)
    {
        Debug.LogWarning("Found more than one Dialogue Manager in the scene");
    }
    instance = this;

    dialogueVariables = new DialogueVariables();

}

public static DialogueManager GetInstance()
{
    return instance;
}

private void Start()
{
    dialogueIsPlaying = false;
    dialoguePanel.SetActive(false);

    layoutAnimator = dialoguePanel.GetComponent<Animator>();

    choicesText = new TextMeshProUGUI[choices.Length];
    int index = 0;
    foreach (GameObject choice in choices)
    {
        choicesText[index] = choice.GetComponentInChildren<TextMeshProUGUI>();
        index++;
    }
}

private void Update()
{
    if (!dialogueIsPlaying)
    {
        return;
    }

    if (canContinueToNextLine
        && currentStory.currentChoices.Count == 0
        && InputManager.GetInstance().GetSubmitPressed())
    {
        ContinueStory();
    }
}

public void EnterDialogueMode(TextAsset inkJSON)
{
    currentStory = new Story(inkJSON.text);
    dialogueIsPlaying = true;
    dialoguePanel.SetActive(true);

    dialogueVariables.StartListening(currentStory);

    displayNameText.text = "???";
    portraitAnimator.Play("default");

    ContinueStory();
}

private IEnumerator ExitDialogueMode()
{
    yield return new WaitForSeconds(0.2f);

    dialogueVariables.StopListening(currentStory);

    dialogueIsPlaying = false;
    dialoguePanel.SetActive(false);
    dialogueText.text = "";
}

private void ContinueStory()
{
    if (currentStory.canContinue)
    {
        if (displayLineCoroutine != null)
        {
            StopCoroutine(displayLineCoroutine);
        }
        displayLineCoroutine = StartCoroutine(DisplayLine(currentStory.Continue()));
        HandleTags(currentStory.currentTags);
    }
    else
    {
        StartCoroutine(ExitDialogueMode());
    }
}

private IEnumerator DisplayLine(string line)
{
    dialogueText.text = "";
    continueIcon.SetActive(false);
    HideChoices();

    canContinueToNextLine = false;

    bool isAddingRichTextTag = false;

    foreach (char letter in line.ToCharArray())
    {
        if (InputManager.GetInstance().GetSubmitPressed())
        {
            dialogueText.text = line;
            break;
        }

        if (letter == '<' || isAddingRichTextTag)
        {
            isAddingRichTextTag = true;
            dialogueText.text += letter;
            if (letter == '>')
            {
                isAddingRichTextTag = false;
            }
        }
        else
        {
            dialogueText.text += letter;
            yield return new WaitForSeconds(typingSpeed);
        }
    }

    continueIcon.SetActive(true);
    DisplayChoices();

    canContinueToNextLine = true;
}

private void HideChoices()
{
    foreach (GameObject choiceButton in choices)
    {
        choiceButton.SetActive(false);
    }
}

private void HandleTags(List<string> currentTags)
{
    foreach (string tag in currentTags)
    {
        string[] splitTag = tag.Split(':');
        if (splitTag.Length != 2)
        {
            Debug.LogError("Tag could not be appropriately parsed: " + tag);
        }
        string tagKey = splitTag[0].Trim();
        string tagValue = splitTag[1].Trim();

        switch (tagKey)
        {
            case SPEAKER_TAG:
                displayNameText.text = tagValue;
                break;
            case PORTRAIT_TAG:
                portraitAnimator.Play(tagValue);
                break;
            default:
                Debug.LogWarning("Tag came in but is not currently being handled: " + tag);
                break;
        }
    }
}

private void DisplayChoices()
{
    List<Choice> currentChoices = currentStory.currentChoices;

    if (currentChoices.Count > choices.Length)
    {
        Debug.LogError("More choices were given than the UI can support. Number of choices given: "
            + currentChoices.Count);
    }

    int index = 0;
    foreach (Choice choice in currentChoices)
    {
        choices[index].gameObject.SetActive(true);
        choicesText[index].text = choice.text;
        index++;
    }
    for (int i = index; i < choices.Length; i++)
    {
        choices*.gameObject.SetActive(false);*

}
StartCoroutine(SelectFirstChoice());
}
private IEnumerator SelectFirstChoice()
{
EventSystem.current.SetSelectedGameObject(null);
yield return new WaitForEndOfFrame();
EventSystem.current.SetSelectedGameObject(choices[0].gameObject);
}
public void MakeChoice(int choiceIndex)
{
if (canContinueToNextLine)
{
currentStory.ChooseChoiceIndex(choiceIndex);
InputManager.GetInstance().RegisterSubmitPressed();
ContinueStory();
}
}
}
Anyway, I really want to learn from my mistake so I can continue with my project. Thank you for your precious time.

It looks like you don’t have the assembly reference, as the error suggests. Did you check whether you have indeed any missing assembly references? I assume you created one that for the folder in which this script sits or in a parent folder and you didn’t include “Ink - Libraries”… Your DialogueManager is likely sitting in a different folder to the DialogueVariables, correct?

See Unity - Manual: Assembly definitions for more info.

Also, you’ve taken all of this code from Trevor Mock, so maybe watch his tutorial again and do it step by step before compiling for the first time?