Page 1 of 2

Need some help with clearing database values & understanding UI text elements.

Posted: Sun Jan 09, 2022 9:18 pm
by PolarJam
Greetings,

I've recently picked up Unity and grabbed the Dialogue System from the store to test out some ideas.

I am having two issues that are giving me a bit of a headache and wondered if somebody would be able to point me in the right direction.

I am using a combination of InventoryEngine, TopDownEngine and Dialogue System.

I have followed the tutorials on asset integration for boht but am not entirely sure if I have implemented things correctly.

Currently, when I start playing in editor - the journal and quest logs are stuck displaying data from a scene change save.

I would like to know how I can reset the database on start or even in a dialogue with an actor if possible - so that I can quickly reset all variables back to their inital state.

Additionally, if at all possible - would somebody be able to explain how I can quickly pull a variable from the stored database and display it as text on screen?

The tutorials I found for Unity UI seem to use scripting and custom classes to assign the relevant text but I am not sure how to go about creating a script that will allow me to access the variables in the database and display them as a text output.

Thanks for any help you can offer and sorry for the newbie questions.

My Dialogue managaer has the following attachments:

DialogueSystem TopDown Event Listener - Handle MM Save Load Events - Enabled.
Pause TopDown during conversations.
Inventory Engine Lua (Ondialoguemanager)
Inventory Script - Persistent - Enabled
DialogueSystem Inventory Event Listener - Update Quest Tracker - Enabled

For TopDownEngine Mangers > Inventories both are also set with Persistence Enabled.

in summary:

I can move between scene and using luacode to get items from inventory engine - carry my items and quest progress across.

I would like to be able to on this first 'testing stage' - quickly reset all saved dialogue system database variables and quest related entries to their default states.

I would like some tips on how to access my database text variables and display them using a Unity UI Text Component.

Thanks again.

Re: Need some help with clearing database values & understanding UI text elements.

Posted: Sun Jan 09, 2022 9:43 pm
by Tony Li
Hi,

Thanks for using the Dialogue System!
PolarJam wrote: Sun Jan 09, 2022 9:18 pmI would like to be able to on this first 'testing stage' - quickly reset all saved dialogue system database variables and quest related entries to their default states.
In C# code, use: Alternatively, you can hook up a UnityEvent to SaveSystemMethods.ResetGameState or RestartGAme. For example, you can add a SaveSystemMethods component to a UI Button GameObject and configure the Button's OnClick() event to call SaveSystemMethods.ResetGameState. This way you don't have to write or maintain any extra code.
PolarJam wrote: Sun Jan 09, 2022 9:18 pmI would like some tips on how to access my database text variables and display them using a Unity UI Text Component.
In C# code, use DialogueLua.GetVariable(). Example:

Code: Select all

using PixelCrushers.DialogueSystem; // (Include at top of your script)
...
GetComponent<Text>().text = DialogueLua.GetVariable("Your Variable").asString;

Re: Need some help with clearing database values & understanding UI text elements.

Posted: Sun Jan 16, 2022 5:59 pm
by PolarJam
Hi,

Thanks for your speedy response.

I managed to add the button and set up the reset button and it's working as intended.

I'm struggling with getting text and variables to work as intended.

Basically, what I am trying to achieve is as follows:

I would like to have a CanvasPanel with Text objects that displays variables from the database as Unity.UI text elements.

I would like to be able to update the variables during conversations and have the current result displayed in the text field of my canvas.

I would like to be able to link the variables in the database to other scripts.

I am struggling to understand the best way to set this up.

Here is how I approach it when I am not using the dialogue system.

I use two custom c# scripts.

A StatManager script:

Code: Select all

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

// Using Create Asset Menu - define the file name and menu name for the class being created //

[CreateAssetMenu(fileName = "New Stat", menuName ="Stat")]

// Create a new public class called Statmanager and derive from ScriptableObject unity class - allowing for the creation of a new class type. This parent script sets the initial parametrs for
// the class and makes it accessible via the right click - create - menu inside of Unity. It then creates a variation of this main class with inputs that can be adjusted using the inspector.
// the inspectore is able to access the public variables that have been set in this parent script.

public class StatManager : ScriptableObject {

   //This is where the class creates new public variables, to be accessed by the inspector.
   //The StatManager class creates a public 'NEW' string - and names each 'Stat'
   //The class also contains string variables for StatDescriptions

    public new string name;
    public string StatDescription;

   //The class creates a new public sprite for 'StatSpriteArtwork' - allowing a sprite image to be assigned on creation.
   //
   
    public Sprite StatSpriteArtwork;

    // The class 'StatManager' then creates public int values for the 'Statvalue', 'MinValue' and 'MaxValue' of each new string 'StatName'

    public int StatValue;
    public int MinValue;
    public int MaxValue;

}

Then a StatManagerDisplay script

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

Code: Select all

public class StatManagerDisplay : MonoBehaviour

    // This script derives from the StatManagerDisplay paraent. Using the StatManager to set new public text variables. Allowing those text variables to be assigned to the StatManager component.
    // On Start - the newly created public text objects can be assignend using the inspector by dragging and dropping objects to link with. In this example it uses a 'StatManager' canvas and
    // within that canvas there are Unity.Ui elements of text/image types. To access these functions, at the top of the script we call UnityEngine.UI.
    // As the StatValue,MinValue and MaxValues derived from the parent StatManager Scriptable Object are Integers (numbers without a decimal) - we use .ToString to convert them into String values.
    // The String Values are required to display correctly as a Text Element. 
{
    public StatManager statmanager;

    public Text nameText;
    public Text descriptionText;

    public Image StatSpriteArtwork;

    public Text statvaluetext;
    public Text statminvaluetext;
    public Text statmaxvaluetext;

    void Start()
    {
        nameText.text = statmanager.name;
        descriptionText.text = statmanager.StatDescription;
        statvaluetext.text = statmanager.StatValue.ToString();
        statminvaluetext.text = statmanager.MinValue.ToString();
        statmaxvaluetext.text = statmanager.MaxValue.ToString();
        StatSpriteArtwork.sprite = statmanager.StatSpriteArtwork;

    
    
    }

}   
How would I approach this sort of set-up so that it creates the variables in the database and allows me to update them via lua events and then return corrrect 'currrent' values' to display as text output?

I may be approaching this in a completely stupid fashion. I apologize if that's the case.

I am hoping to have a system in place that allows me to access a (list?) of the database variables - that I can then use to drive mmfeedback events from the top down engine.

For example - using the variable for 'Strength' in my dialogue database - I would like to use a
MMFeeedbacks in combination with a Feedbacks - Float Controller that communicates with the Dialouge System database to update my strength variable stored in the dialogue datbase.

I am guessing that I would need to set up an MMFeeedbackEvent/Unity Event to trigger component updates on the Dialogue Database but I don't really understand how to make the two systems talk to each other properly.

If this is outside the remit of what you can help with I understand.

Thanks for any pointers you can offer.

Re: Need some help with clearing database values & understanding UI text elements.

Posted: Sun Jan 16, 2022 8:24 pm
by Tony Li
Hi,

In which direction do the values change?

1. An MMFeedback Float Controller changes a float value, which then automatically pushes the value to a DS variable.

2. A conversation changes a DS variable, which then automatically pushes the value to an MMFeedback Float Controller.

Do you want to do (1), (2), both, or something else?

---

Information overload incoming. :-)

I'm just providing the info below in case it's something you're interested in digging into right away. But once we know which direction you want the values to change, I can probably provide a more succint, less intimidating wall of text to help.

---

For (1), you could make a subclass of FloatController that overrides Update(). Something roughly like:

Code: Select all

public class FloatControllerPlusDS : FloatController
{
    [VariablePopup] public string DialogueSystemVariable;
    
    protected float PreviousValue;
    
    protected virtual void Update()
    {
        base.Update();
        if (CurrentValue != PreviousValue)
        {
            PreviousValue = CurrentValue;
            DialogueLua.SetVariable(DialogueSystemVariable, CurrentValue);
        }
    }
}
For (2), you could write a C# method such as SetFloatVar (rough example below), register it with Lua, and use it to set the DS variable and inform a FloatController or MMFeedbackFloatController:

Code: Select all

// These FloatControllers want to be informed when a variable changes:
protected Dictionary<string, MMFeedbackFloatController> feedbackFloatControllers = new Dictionary<string, MMFeedbackFloatController>();

public void RegisterFloatController(string dialogueSystemVariable, MMFeedbackFloatController feedbackFloatController)
{
    feedbackFloatControllers[dialogueSystemVariable] = feedbackFloatController;
}

public void UnregisterFloatController(string dialogueSystemVariable)
{
    feedbackFloatControllers.Remove(dialogueSystemVariable);
}

public void SetFloatVar(string dialogueSystemVariable, double value)
{
    DialogueLua.SetVariable(dialogueSystemVariable, value);
    
    if (feedbackFloatControllers.HasKey(dialogueSystemVariable))
    {
        var feedbackFloatController = feedbackFloatControllers[dialogueSystemVariable];
        feedbackFloatController.ToDestinationValue = (float)value;
	feedbackFloatController.Play(feedbackFloatController.transform.position);
    }
}
That's the gist. The actual code you need may be different.

Re: Need some help with clearing database values & understanding UI text elements.

Posted: Sun Jan 16, 2022 10:07 pm
by PolarJam
Hi Tony,

Thanks again for your help and speedy response!

With the scripts and documentation you linked, it's starting to make a lot more sense in terms of how to tackle the overall structure.

I think I am looking to do both.

In the sense that I can use the dialogue manager's friendly and fast UI to create my list of variables using the drop downs and then when I am modifying a 'managing' game object attached to a prefab I have the option to update my floats / strings / bools / etc directly from the dialogue manager conversation trees or based on the input of a mmfeedbacks stack.

The example prefab structure I am experimenting with to get things working is a 'boxing bag'

At the moment, how my 'boxing bag' works - is like this:

I have a BoxingBag Prefab and within that prefab I have a model object and a feedbacks object.

Currently, how I have things working is by using a box collider and on button use triger.

On use, the trigger references my dialogue system database and starts a conversation.

From within the conversation - I have branching dialogue options for the 'BoxingBagUsable'

The boxing bag usable has options 'I can train here' or 'I am too tired to train, I should rest'

I then give additional options within the converstaion tree:

Train Strength, Train Stamina, Train Dexterity, etc (referencing variables from the database)

I run conditional checks on the conversation branches - for example - to train Strength:

Condition: Variable["Stamina"] >= 50

Code: Select all

Script:

Variable["Stamina"] = Variable["Stamina"] - 50;
Variable["Strength"] = Variable["Strength"] + 1
The player actor can select this option when the conversation is running.

It then goes down the conversation tree and the 'BoxingBagUsable' actor does this:

Code: Select all

Dialogue Text: My [em1]Strength[/em1] has increased by [em2]+1.[/em2]  My [em1]Stamina[/em1] is now [em2][var=Stamina].[/em2] My [em1]Strength[/em1] is now [em2][var=Strength].[/em2]
What I would like to be able to do - is determinte the Stamina cost and Strength gain - by using a MMFeedbacks event.

For example, select the 'Train Stamina' option in the conversation window and then:

Trigger the MMFeedbacks on my BoxingBagUsable prefab - the feedback would have a premade stack that does the follwing when that conversation option is called.

Play a sound, perform a camera shake, create a floating text and change my variables in the dialouge system database.

I'd like the Strength increase and Stamina cost to be determined by the curve of the float controller.

The floating text displayed would be the change in the variable Strength (+1) in this example.

I'd like to use the chance modifier of the feeedback stack to so that the strength change only happens say 25% of the times you have that 'conversation'.

When the 'feedback stack' finishes it's loop - I then want the results to be updated in the dialogue manager database.

I would then have a CanvasPanel pop up - that displays text - for example "Your Strength increased by x (the amount decideed by the float controller curve) - you lost y Stamina (again, the cost being determined by the float controller)

I'll have a dig through the scripts you have provided and read some more of the accessing c# lua documentation and try to find a solution that suits my needs. My brain is a bit fraazzled trying to wrap my head around it all.

Thank you again for your help

Re: Need some help with clearing database values & understanding UI text elements.

Posted: Mon Jan 17, 2022 9:27 am
by Tony Li
Hi,

Are you using the Strength and Stamina stat values elsewhere in your game, outside of conversations, such as computing damage values in combat?

If so, it might be more convenient to keep those stat values in a C# script instead of DS variables. Then your MMFeedbackFloatController can change the values of your C# variables without involving the Dialogue System.

If you write C# methods to get the stat values, such as GetStrength() and GetStamina(), you can register those methods with Lua and use them in your dialogue text. So instead of using [var=variable] this:

Code: Select all

Dialogue Text: My [em1]Strength[/em1] has increased by [em2]+1.[/em2]  My [em1]Stamina[/em1] is now [em2][var=Stamina].[/em2]
You'd use [lua(code)] like this:

Code: Select all

Dialogue Text: My [em1]Strength[/em1] has increased by [em2]+1.[/em2]  My [em1]Stamina[/em1] is now [em2][lua(GetStamina())].[/em2]
So, in summary, using this approach your stat values are in C# variables, and the Dialogue System uses C# methods to read those C# variables instead of maintaining DS variables for the stats.

More details
Let's say you have a class called PlayerStats:

Code: Select all

public class PlayerStats : MonoBehaviour
{
    public float Strength;
    public float Stamina;
}
Your MMFeedbackFloatController could directly modify Strength and Stamina.

You could write C# methods to return the stat values, and register them with Lua so the Dialogue System can use them:

Code: Select all

public class PlayerStats : MonoBehaviour
{
    public float Strength;
    public float Stamina;
    
    public float GetStrength() { return Strength; }
    public float GetStamina() { return Stamina; }
    
    void OnEnable()
    {
        Lua.RegisterFunction(nameof(GetStrength), this, SymbolExtensions.GetMethodInfo(() => GetStrength()));
        Lua.RegisterFunction(nameof(GetStamina), this, SymbolExtensions.GetMethodInfo(() => GetStamina()));
    }
    
    void OnDisable()
    {
        Lua.UnregisterFunction(nameof(GetStrength));
        Lua.UnregisterFunction(nameof(GetStamina));
    }
}

Re: Need some help with clearing database values & understanding UI text elements.

Posted: Fri Jan 12, 2024 10:10 am
by weto4ka
Hello!

I've been exploring approaches for integrating ScriptableObjects with the Dialogue System in Unity and came across a discussion on this forum. My scenario is somewhat similar, but instead of variables, I'm dealing with ScriptableObjects that contain text and corresponding audio files.

I'm seeking advice on how to link these ScriptableObjects with the Dialogue System and utilize L2 for translations. Each ScriptableObject has two fields: an audio file and text. The text can be updated via L2's Google Sheets integration or directly within the ScriptableObject. My goal is to ensure synchronization between these three elements (ScriptableObject, Dialogue System, and L2 translations).

The primary challenge is maintaining a consistent link between the Dialogue System entries, L2 fields, and the ScriptableObject, especially when texts change, which also triggers audio generation. While I understand you might not have specific insights on L2 integration, any guidance on syncing and tracking connections between the ScriptableObject and the Dialogue System would be immensely helpful. For example, how can I manage the IDs of dialogue entries in a way that maintains their association with the corresponding ScriptableObject, and ensure that any text changes are reflected across both systems?

Thank you in advance for your assistance!

Re: Need some help with clearing database values & understanding UI text elements.

Posted: Fri Jan 12, 2024 10:50 am
by Tony Li
Hi Yelyzaveta,

The Dialogue System has official i2 Localization integration.

Unless you absolutely must use the ScriptableObjects, a better workflow would be use write your dialogue in the dialogue database -- for example, using the Dialogue Editor window. Then you can use the i2 Localization integration. For audio, name your audio files according to their entrytags so you can play them without having to assign them to each ScriptableObject. (More info: Sequence Tutorials)

Re: Need some help with clearing database values & understanding UI text elements.

Posted: Sat Jan 13, 2024 2:29 pm
by weto4ka
Well, yes, I'm familiar with these tools and regularly use them in dialogue. I'm currently trying to utilize code snippets from them to trigger the right functionality for my needs.

The challenge is that all texts are originally in scriptable objects and can be updated from there. They also need to be synchronized with both the Scriptable Objects & from L2 (Google Sheets). Where we only need translations, it's straightforward, as handling scriptable objects and L2 is quite easy. However, some content must be in dialogues because texts + audio from scriptable objects are triggered at random moments in the code, and then I need to trigger a dialogue element (because it's like a part of our chat message, so there also needs to be sequences. therefore we could not use just L2 or just scriptable object). I would add this on runtime as a conversation entry in our dialogue, where all sequential actions would be triggered. Thus, we would use the Dialogue System, but I need to know which element of the Dialogue System is responsible for this scriptable object and keep it updated with its contents.

I cannot switch from these scriptable objects, as the system using them was not developed by me. My task is to integrate Dialogue functionality and translation into an already existing solution.

Re: Need some help with clearing database values & understanding UI text elements.

Posted: Sat Jan 13, 2024 2:54 pm
by Tony Li
Hi,

Can you rename the ScriptableObjects and put them in a Resources folder or mark them as Addressable? If so, you can rename them to the corresponding dialogue entry's entrytag.

This next suggestion is a little more complex, but you could assign an editor script method to DialogueEditorWindow.customDrawDialogueEntryInspector (more info) and show the ScriptableObject in the inspector view when you inspect a dialogue entry node.