change C# script during conversation

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
annathehank
Posts: 95
Joined: Sun May 03, 2020 2:17 pm

change C# script during conversation

Post by annathehank »

Hi Tony!

I hope I can explain this well! I managed to figure out how to get the achievement page to work, which is great. The problem I'm facing is getting the things that trigger during a conversation to apply to the new script that holds all the achievement information.

Here's an example of the achievement script I'm using. Where this basic setup would be applied for each achievement:

Code: Select all

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

public class AchievementHold : MonoBehaviour
{
    //L1 Dead
    public int L1Act;
    public GameObject L1A;
    public GameObject L1B;
    public int L1Code;
    public int L1Did;
    
    void Start()
    {
        L1Code = PlayerPrefs.GetInt("L1");
        L1Act = PlayerPrefs.GetInt("L1On");

        if (L1Act == 1 && L1Code == 12345)
        {
            L1A.SetActive(true);
            L1B.SetActive(false);
        }
        else L1A.SetActive(false);
        L1B.SetActive(true);
    }

    IEnumerator L1go()
    {
        L1Code = 12345;
        PlayerPrefs.SetInt("L1", L1Code);
        L1Act = 1;
        PlayerPrefs.SetInt("L1On", L1Act);
        yield return new WaitForSeconds(1);
    }    
}
The thing is, I'm not sure what I'm doing wrong to get the coroutine to run during a conversation or at the end of a specific conversation. I went into the dialogue node that would trigger the achievement to go off, but when I attach the script to the On Execute() of the Scene-Independent Event area, the option to utilize the coroutine does not show up. Is it something in my script I need to look into, or am I trying to run it from the wrong place in the Dialogue System?
Thank you in advance <3
User avatar
Tony Li
Posts: 22047
Joined: Thu Jul 18, 2013 1:27 pm

Re: change C# script during conversation

Post by Tony Li »

Hi,

There are a few ways you could do it.

If you want to use the scene-independent OnExecute() event, make your script(s) into a ScriptableObject asset (example).

Another solution is to register your C# method(s) with Lua, and use them in dialogue entry nodes' Script fields. For example, say your Achievements script looks like this:

Code: Select all

public class Achievements : MonoBehaviour // Add me to the Dialogue Manager so I survive scene changes.
{
    void Awake()
    {
        Lua.RegisterFunction("UnlockAchievement", this, SymbolExtensions.GetMethodInfo(() => UnlockAchievement(string.Empty)));
    }
    
    public void UnlockAchievement(string achievementName)
    {
        PlayerPrefs.SetInt(achievementName, 1);
        DialogueManager.ShowAlert("Achievement: " + achievementName);
    }
    
    public bool IsAchievementUnlocked(string achievementName)
    {
        return PlayerPrefs.GetInt(achievementName) == 1;
    }
}
Then you could set a dialogue entry node's Script field like this:
  • Dialogue Text: "Great job! You achieved the goal!"
  • Script: UnlockAchievement("L1")
More info: Lua Function Tutorial
annathehank
Posts: 95
Joined: Sun May 03, 2020 2:17 pm

Re: change C# script during conversation

Post by annathehank »

I made the script a scriptable object asset and added it to the scene-independent event. But it's still not letting me have it run the coroutine. Do I need to set the coroutine as a public void instead?
User avatar
Tony Li
Posts: 22047
Joined: Thu Jul 18, 2013 1:27 pm

Re: change C# script during conversation

Post by Tony Li »

What's the need for the coroutine?
annathehank
Posts: 95
Joined: Sun May 03, 2020 2:17 pm

Re: change C# script during conversation

Post by annathehank »

I need it to do all of this

Code: Select all

{
        L1Code = 12345;
        PlayerPrefs.SetInt("L1", L1Code);
        L1Act = 1;
        PlayerPrefs.SetInt("L1On", L1Act);
        yield return new WaitForSeconds(1);
    }    
I need to use int and not bools because I'm saving things as PlayerPrefs so they stay locked/unlocked across all sessions. And so I need the dialogue node to set the integers and then save them as PlayerPrefs.
annathehank
Posts: 95
Joined: Sun May 03, 2020 2:17 pm

Re: change C# script during conversation

Post by annathehank »

I may not need it is a coroutine though?

To be honest I was following and reverse engineering a script that was using a pop-up, so as a regular void would it still work?
User avatar
Tony Li
Posts: 22047
Joined: Thu Jul 18, 2013 1:27 pm

Re: change C# script during conversation

Post by Tony Li »

You could use the script I posted above to do that.

Since the "yield return new WaitForSeconds(1)" line is at the end, your coroutine doesn't do anything coroutine-y. You could turn it into a non-coroutine method and get rid of the yield return line:

Code: Select all

public void L1go()
{
    L1Code = 12345;
    PlayerPrefs.SetInt("L1", L1Code);
    L1Act = 1;
    PlayerPrefs.SetInt("L1On", L1Act);
}    
annathehank
Posts: 95
Joined: Sun May 03, 2020 2:17 pm

Re: change C# script during conversation

Post by annathehank »

ahh okay! Thank you. I'm not really 100% sure what all a coroutine does so it's good to know I can just do it as a void. Thank you very much for the help!
User avatar
Tony Li
Posts: 22047
Joined: Thu Jul 18, 2013 1:27 pm

Re: change C# script during conversation

Post by Tony Li »

Glad to help!

A coroutine runs a method over multiple frames instead of running all at once. For example, this coroutine will activate a GameObject for 2 seconds and then deactivate it:

Code: Select all

IEnumerator ShowFor2Seconds(GameObject go)
{
    go.SetActive(true);
    yield return new WaitForSeconds(2);
    go.SetActive(false);
}
Use StartCoroutine() to start it. Example:

Code: Select all

void SomeMethod()
{
    StartCoroutine(ShowFor2Seconds(someGameObject));
}
Post Reply