Forum rules - please read before posting.

Global conversations struggles

Hi, I've been trying to come up with an elegant way of handling global conversations. I've not yet succeeded.
Note that I only need to toggle conversation options from other scenes, the actual conversation is fixed to a specific scene.

Here's what I've tried and my problem with it.

Conditions
One option would be affecting the conversations values at the beginning of a scene based on variables. Though that requires a lot of global variables.

SyncConversations
The old wiki script SyncConversations has it's limitations. It loads data from the previous scene. It has to, it has no way of knowing which scene holds the most recent instance of the conversation. And that method fails if there's an inbetween scene. A solution would be to put the conversation prefab into all the possible scenes that the player could encounter inbetween, but that means running this operation on scenes where the conversations are not technically present.

DontDestroyMe
DontDestroyMe method. I still need to create a prefab from the conversation so I can reference it in other scenes in order to toggle its options.
First thing I don't like about it is the need of working with action assets. It makes things more messy in opposite of having everything in a single scene. It also requires to create a dummy interaction just to reference those assets to include them in text gathering operation.
It also seems that if I want to run nested conversations which don't need to be "global" as they won't be affected outside of its scene it also requires to make them as prefabs and as DontDestroyMe objects.

How are you handling it? Am I missing something?
Thanks for any suggestions.

Comments

  • The old SyncConversation script indeed had its limitations - but that was before AC was able to store persistent Remember components as global data.

    As persistent objects do not exist in the active scene, ActionList assets are a necessity - but the main intention behind the "Global Conversations" wiki page is to provide a way of running a Conversation from any scene, which is a little different to what you're using it for in this case.

    In your situation, you only need to affect which options are enabled/disabled outside of a specific scene. What you should be able to do here is instead create the Conversation - along with any nested Conversations - in the scene itself. Then, create a separate "Global" Conversation that shares the same number of dialogue options as the one in the scene.

    This wouldn't ever be run - only a means to set its various options via other scenes. Then, via a simple script, you'd transfer those option states from the global Conversation onto the scene one.

    using UnityEngine;
    using AC;
    
    public class TransferConversationState : MonoBehaviour
    {
    
        public Conversation globalConversationPrefab;
    
        private void OnEnable () { EventManager.OnAfterChangeScene += OnAfterChangeScene; }
        private void OnDisable () { EventManager.OnAfterChangeScene -= OnAfterChangeScene; }
    
        private void OnAfterChangeScene (LoadingGame loadingGame)
        {
            Conversation conversation = GetComponent <Conversation>();
            int globalConversationConstantID = globalConversationPrefab.GetComponent <ConstantID>().constantID;
            Conversation globalConversation = ConstantID.GetComponent <Conversation> (globalConversationConstantID);
    
            for (int i=0; i<globalConversation.options.Count; i++)
            {
                conversation.options[i].isOn = globalConversation.options[i].isOn;
                conversation.options[i].isLocked = globalConversation.options[i].isLocked;
            }
        }
    
    }
    

    Attach this to the scene-based Conversation, and assign the prefab of the Global Conversation it should sync with. Make sure the Global Conversation prefab has a Constant ID component with Retain in prefab? checked, so that the script can find the local instance of it at runtime. You should then find that - after the scene is loaded - it finds the Global Conversation and syncs its own option states with it.

  • Actually, I may have over-thought this.

    A Conversation is separate from the Actions that run when options are clicked. The Actions that process its various options can all be part of the scene.

    If you create a new Cutscene with a Dialogue: Start conversation Action, reference the Global Conversation prefab, and check Override options?. From there, you can supply all the Actions that run upon clicking an option (even if they're ActionList: Run Actions to run another list). The state of the Conversation, and its options, will still survive scene changes and can be modified in other scenes.

  • edited September 2020

    Actually, I may have over-thought this.

    You and me both, haha.

    Good point, overriding the global prefab options seems elegant enough. It allows for having all the actions directly inside the scene without using any asset lists whatsoever and thus also no need to have dummy action lists for referencing.

    Though, you still can't use the option "run other conversation" on local only conversations. But when I think about it it's really not any different from using the "stop" option and then starting the conversation at the end of the actions thread.

    Aye, that's definitely the most clean way of working with it. Each override would be a simple "ActionList: Run" action running the actual "dialogue option" action list. Though here I could just use a classic interaction action lists instead.

    Thank you for the information, I'm happy with that.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.