Manipulate object outline based on dialogue status

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
Trashrat
Posts: 33
Joined: Fri Oct 13, 2023 11:38 am

Manipulate object outline based on dialogue status

Post by Trashrat »

Hi there,

Hopefully you can help me. I have a stystem currently where on a button pressvarious objects that can be interacted with are highlighted in an outline. I would like to make it so that when there is a fresh dialogue interaction to be had the outline is one colour, and when it has been seen by the player it is another.

I have what I think is a good structure for this, but am now trying to think of the best way to get the dialogue status for each object. Would the best way to simply create a new bool variable for each individual object and get that?

I have attached two controllers I have set up for this. I also haev a script controlling the outline.

Thank you.

Code: Select all

public class EnableOutline : MonoBehaviour
{
    Outline outline;
    public DialogueOutlineStatus status;

    public Color newColour = Color.yellow;
    public Color talkedColour = Color.gray;

    public bool showOutline;
    
    private void Awake()
    {
        if (!TryGetComponent(out outline)) return;
        outline.enabled = false;

    }

    void Update()
    {
        if (!outline) return;
        outline.enabled = Input.GetKey(KeyCode.Tab);
    }

    private void OnEnable()
    {
        if (!TryGetComponent(out outline)) return;
        outline.OutlineColor = status.hasTalkedTo ? talkedColour : newColour;
    }
}

Code: Select all

public class DialogueOutlineStatus : MonoBehaviour
{
    public bool hasTalkedTo = false;
}
User avatar
Tony Li
Posts: 23238
Joined: Thu Jul 18, 2013 1:27 pm

Re: Manipulate object outline based on dialogue status

Post by Tony Li »

Hi,

A think a Dialogue System variable for each object would be a good approach. For example, "Adam.Seen", "Painting.Seen", etc.

Then you can change your EnableOutline.OnEnable() method to something like:

Code: Select all

private void OnEnable()
{
    if (!TryGetComponent(out outline)) return;
    outline.OutlineColor = status.HasTalkedTo() ? talkedColour : newColour;
}
and change your DialogueOutlineStatus method to:

Code: Select all

public class DialogueOutlineStatus : MonoBehaviour
{
    [VariablePopup(true)] public string variableName;
    
    private bool hasTalkedTo;
    private bool isVariableUpToDate = false;
    
    public void OnConversationStart(Transform actor)
    {
        // If we start a conversation involving this GameObject, mark it as Seen:
        DialogueLua.SetVariable(variableName, true);
        hasTalkedTo = true;
        isVariableUpToDate = true;
    }
    
    public bool HasTalkedTo()
    {
        if (!isVariableUpToDate)
        {
            hasTalkedTo = DialogueLua.GetVariable(variableName).asBool;
            isVariableUpToDate = true;
        }
        return hasTalkedTo;
    }
}
There are a lot of ways you could customize this script. Some ideas:
  • If you're adding Dialogue Actor components to each object, you can omit the variableName variable. Instead, get the variable name from the Dialogue Actor:

    Code: Select all

    string variableName = GetComponent<DialogueActor>().actor + ".Seen";
  • If you don't want to use a variable, you could use SimStatus. This is a bit more complicated, but it will allow you to check whether any of the currently-available dialogue lines for the object have never been shown to the player yet. To do this, instead of checking DialogueLua.GetVariable(variableName).asBool you'd create a ConversationModel and then check all of the entries that link from <START>. For example, this method below will tell you if the conversation has any new lines of dialogue that the player hasn't seen yet:

    Code: Select all

    public bool HasAnyNewLines()
    { 
        var model = new ConversationModel(DialogueManager.masterDatabase, "title", null, null, true, null);
        foreach (var response in model.firstState.npcResponses)
        {
            if (DialogueLua.GetSimStatus(response.destinationEntry) == DialogueLua.Untouched) return true;
        }
        return false;
    }
Trashrat
Posts: 33
Joined: Fri Oct 13, 2023 11:38 am

Re: Manipulate object outline based on dialogue status

Post by Trashrat »

Hi Tony,

Thank you for getting back to me. I have that working in a basic way now, and will have a look at expanding on it too, so thank you for your suggestions.

Thanks again.
User avatar
Tony Li
Posts: 23238
Joined: Thu Jul 18, 2013 1:27 pm

Re: Manipulate object outline based on dialogue status

Post by Tony Li »

Happy to help!
Post Reply