Forum rules - please read before posting.

Stopping dialogue actions on running actionlists

Hello,

I run interactions without pausing so I can hear the dialogues while moving around.

The thing is when I run an interaction that has several dialogues, if I run a new interaction; the old interaction dialogues was continuing after the new interaction actions are over.

Therefore I created a custom action, killing all previous actions

        ActionList[] allLists = GameObject.FindObjectsOfType<ActionList>();
        foreach (ActionList list in allLists)
        {
            if (!list.actions.Contains(this))
            {
                list.Kill();
            }
        }

the problem is let's say the previous action was opening a door with dialogues. this stops the dialogues but also prevents the door opening.

do you have a suggestion for me? is it possible to cancel next dialogue actions for an action but continue with others?
I thought about skipping but then we need everything skippable right?

Thanks

Comments

  • Tricky one!

    You'll need to record which ActionList is allowed to display background speech, which - from the sounds of it - just needs to be the last to be triggered.

    However, presumably not every background list has speech - so you'll also need to tag up such list GameObjects with a special tag, e.g. "BackgroundSpeech".

    Then, you can hook into the OnBeginActionList to listen for such a tag and record the last one run:

    using UnityEngine;
    
    namespace AC
    {
    
        public class RecordLastBackgroundSpeechList : MonoBehaviour
        {
    
            public static ActionList lastBackgroundSpeechList { get; private set; }
    
            private void OnEnable () { EventManager.OnBeginActionList += OnBeginActionList; }
            private void OnDisable () { EventManager.OnBeginActionList -= OnBeginActionList; }
    
            private void OnBeginActionList (ActionList actionList, ActionListAsset actionListAsset, int startingIndex, bool isSkipping)
            {
                if (actionList.gameObject.tag == "BackgroundSpeech" && !isSkipping)
                {
                    lastBackgroundSpeechList = actionList;
                }
            }
    
        }
    
    }
    

    Having done that, you can then modify the speech Action to work out if it's being played from this recorded ActionList. If it's not, and its own ActionList is running in the background, don't do anything.

    You could modify the existing Action (ActionSpeech), or install a subclass as a custom Action:

    using UnityEngine;
    
    namespace AC
    {
    
        public class ActionSpeechLimiting : ActionSpeech
        {
    
            bool dontRun = false;
    
            public ActionSpeechLimiting ()
            {
                this.isDisplayed = true;
                category = ActionCategory.Dialogue;
                title = "Play speech (limit background)";
                lineID = -1;
            }
    
            public override void AssignParentList(ActionList actionList)
            {
                base.AssignParentList (actionList);
    
                dontRun = (runActionListInBackground && RecordLastBackgroundSpeechList.lastBackgroundSpeechList != actionList);
            }
    
            public override float Run()
            {
                if (dontRun) return 0f;
                return base.Run ();
            }
        }
    
    }
    
  • thanks sounds great

  • edited May 2020

    Hey Chris,

    I have an additional question on this one

    as the action list already knows if it has a speech (so it shows the assignment of a speech tag), is it possible to check if an action list has a speech without assigning a speech tag?

    currently I'm checking with

    if(actionList.tagID == 1 || (actionListAsset != null && actionListAsset.tagID == 1))

    but for this I need to set this tag to all speech actions and would love to have something like actionList.haveSpeech

    thanks

  • It's an expensive operation, but AC gets away with it because it only shows in the Editor, but it uses the following to determine that:

    bool hasSpeechAction = false;
    foreach (Action action in actionList.actions)
    {
        if (action != null && action is ActionSpeech)
        {
            hasSpeechAction = true;
        }
    }
    
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.