Forum rules - please read before posting.
Tech questions during the weekend? Drop in on the community Discord channel!

Is there a way to add audio for the document when gathering text?

edited January 30 in Technical Q&A

Hey Chis, is there a way to add audio for the document when gathering text? I don't see the placeholder for the audio file.
I use documents as notes that you can read, but I also have voice-overs. I know that I can do this for Speeches but I thought that I can do this for Documents as well. This is very important for my game because the big part of the game story is based on emotional notes that should have voice-overs.

Comments

  • edited January 31

    Audio assigned in the Speech Manager is strictly for speech only.

    There's a couple of ways you can get voiceover audio to play when opening a Document:

    1) Create a Dialogue: Play speech Action that plays the audio at the same time the Document is opened. If you have this speech be spoken by a specific character, e.g. "DocumentNarrator", you can limit your regular Subtitles menu from showing this dialogue, so that it is only heard.

    2) Through scripting, hook into the OnOpenDocument custom event and play audio assigned in an Inspector, based on the Document's translation ID:

    using UnityEngine;
    using AC;
    
    [RequireComponent (typeof (AudioSource))]
    public class DocumentAudioPlayer : MonoBehaviour
    {
    
        [SerializeField] DocumentAudio[] documentAudios;
        private AudioSource audioSource;
    
    
        private void OnEnable ()
        {
            audioSource = GetComponent <AudioSource>();
            EventManager.OnOpenDocument += OnOpenDocument;
        }
    
    
        private void OnDisable ()
        {
            EventManager.OnOpenDocument -= OnOpenDocument;
        }
    
    
        private void OnOpenDocument (Document document)
        {
            int docID = document.ID;
    
            foreach (DocumentAudio documentAudio in documentAudios)
            {
                if (documentAudio.docID == docID)
                {
                    audioSource.clip = documentAudio.audioClip;
                    audioSource.Play ();
                }
            }
        }
    
    
        [System.Serializable]
        private class DocumentAudio
        {
    
            public int docID = 0;
            public AudioClip audioClip = null;
    
        }
    
    }
    
  • edited February 1
    1. "Audio assigned in the Speech Manager is strictly for speech only." - Is there a chance you can add this function in the next AC updates?

    2. "Create a Dialogue: Play speech Action that plays the audio at the same time the Document is opened. If you have this speech be spoken by a specific character, e.g. "DocumentNarrator", you can limit your regular Subtitles menu from showing this dialogue, so that it is only heard." - I thought about doing this but there are many other questions regarding using this trick, for example - how can I stop playing this audio when I press the exit button in the document UI? Also I have several pages, so how can play audio for the second page? I think this is a too tricky method. Your thought on this Chris?

    3. "Through scripting, hook into the OnOpenDocument custom event and play audio assigned in an Inspector, based on the Document's translation ID:" - I like the idea of using the script but again, I not fully sure how to use it. Can you please help me with this step by step?

    • I need to create an empty object and apply this script right?
    • In this script, I have to set a number of documents (Document Audio size)?
    • Next, I need to set Doc ID, but what exect ID it is - the number of this document in the document list or Speech Manager ID? But if I have more than one page, what ID I have to put (each page has it's own ID in speech manager)?
    • Next, I need to add to my action list Object: Call Event and place there my empty object with this script and what next, what I have to choose? Or maybe this is not correct at all?

    All this seems too hard and tricky for me, I wish you could do this much simpler (in Speech Manager same as for speeches). But I understand that it could be not easy to add this since AC is not just an adventure system but a HUGE PLANET:)

    So, can you please explain in details. I really need to make audio in documents:) Here are some screenshots:

    https://prnt.sc/qvzlxs
    https://prnt.sc/qvzm0p
    https://prnt.sc/qvzm3c
    https://prnt.sc/qvzm61
    https://prnt.sc/qvzm8l
    https://prnt.sc/qvzmb9
    https://prnt.sc/qvzmdr

  • You do not need to call anything with the Object: Call event Action. Simply placing the script in the scene as a component on a GameObject is enough.

    The "Doc ID" refers to the numbers listed at the top of the Inventory Manager (in your screenshot, the first is 0, not 9). Nothing referenced by the Speech Manager is necessary.

    Here is an updated script to handle the different pages:

    using UnityEngine;
    using AC;
    
    [RequireComponent (typeof (AudioSource))]
    public class DocumentAudioPlayer : MonoBehaviour
    {
    
        [SerializeField] private string documentMenuName = "Document";
        [SerializeField] private DocumentAudio[] documentAudios;
        private AudioSource audioSource;
        private int docID;
    
    
        private void OnEnable ()
        {
            audioSource = GetComponent <AudioSource>();
            EventManager.OnOpenDocument += OnOpenDocument;
            EventManager.OnMenuElementShift += OnMenuElementShift;
            EventManager.OnMenuTurnOff += OnMenuTurnOff;
        }
    
    
        private void OnDisable ()
        {
            EventManager.OnOpenDocument -= OnOpenDocument;
            EventManager.OnMenuElementShift -= OnMenuElementShift;
            EventManager.OnMenuTurnOff -= OnMenuTurnOff;
        }
    
    
        private void OnOpenDocument (Document document)
        {
            PlayAudio ();
        }
    
    
        private void OnMenuElementShift (MenuElement _element, AC_ShiftInventory shiftType)
        {
            if (_element is MenuJournal)
            {
                PlayAudio ();
            }
        }
    
    
        private void OnMenuTurnOff (Menu _menu, bool isInstant)
        {
            if (_menu.title == documentMenuName)
            {
                StopAudio ();
            }
        }
    
    
        private void PlayAudio ()
        {
            Document document = KickStarter.runtimeDocuments.ActiveDocument;
            if (document != null)
            {
                int pageIndex = KickStarter.runtimeDocuments.GetLastOpenPage (document);
    
                PlayAudio (document.ID, pageIndex);
            }
        }
    
    
        private void PlayAudio (int documentID, int pageIndex)
        {
            foreach (DocumentAudio documentAudio in documentAudios)
            {
                if (documentAudio.documentID == docID)
                {
                    foreach (PageAudio pageAudio in documentAudio.pageAudios)
                    {
                        if (pageAudio.pageIndex == pageIndex)
                        {
                            audioSource.clip = pageAudio.audioClip;
                            audioSource.Play ();
                        }
                    }
                }
            }
        }
    
    
        private void StopAudio ()
        {
            audioSource.Stop ();
        }
    
    
        [System.Serializable]
        private class DocumentAudio
        {
    
            public int documentID = 0;
            public PageAudio[] pageAudios = new PageAudio[0];
    
        }
    
    
        [System.Serializable]
        private class PageAudio
        {
    
            public int pageIndex = 0;
            public AudioClip audioClip = null;
    
        }
    
    }
    

    It may take a bit further tweaking, but this will allow you to define AudioClips for each page in a document (again, these are not Speech Manager IDs), and as many Documents as you like. It should also stop the audio when you close the Document menu.

  • Ok, I did it and now I have 3 issues:

    1. This script is not working when "Pause game when" checked in the document menu (I use this function in my game now). But when I unchecked - I hear the sound.
    2. I've set up document ID 0. Next, I've added 2 pages, set Page index 0 and 1 and added 2 different audio files. When I open the document it starts playing second audio file for both pages. If I will set page index to 1 and 2 it will start playing the first audio file for both pages. I've tried to swap audio files but the result is the same - one audio file playing for both pages.
    3. I have several languages and all documents should have translation audio files too. Is it possible to add this somehow?
  • I shall look into it.

  • Again, if this is something that will go crazy, leave this Chris, I'll think how to deal with a voice. Maybe I will leave it as it is, without a voice over.

  • Use this:

    using UnityEngine;
    using AC;
    
    [RequireComponent (typeof (AudioSource))]
    public class DocumentAudioPlayer : MonoBehaviour
    {
    
        [SerializeField] private string documentMenuName = "Document";
        [SerializeField] private string documentElementName = "PageText";
        [SerializeField] private DocumentAudio[] documentAudios;
    
    
        private void OnEnable ()
        {
            EventManager.OnOpenDocument += OnOpenDocument;
            EventManager.OnMenuElementShift += OnMenuElementShift;
            EventManager.OnMenuTurnOff += OnMenuTurnOff;
        }
    
    
        private void OnDisable ()
        {
            EventManager.OnOpenDocument -= OnOpenDocument;
            EventManager.OnMenuElementShift -= OnMenuElementShift;
            EventManager.OnMenuTurnOff -= OnMenuTurnOff;
        }
    
    
        private void OnOpenDocument (Document document)
        {
            PlayAudio ();
        }
    
    
        private void OnMenuElementShift (MenuElement _element, AC_ShiftInventory shiftType)
        {
            if (_element is MenuJournal)
            {
                PlayAudio ();
            }
        }
    
    
        private void OnMenuTurnOff (Menu _menu, bool isInstant)
        {
            if (_menu.title == documentMenuName)
            {
                StopAudio ();
            }
        }
    
    
        private void PlayAudio ()
        {
            MenuJournal journalElement = PlayerMenus.GetElementWithName (documentMenuName, documentElementName) as MenuJournal;
            Document document = KickStarter.runtimeDocuments.ActiveDocument;
            if (document != null)
            {
                int pageIndex = journalElement.showPage - 1;
                PlayAudio (document.ID, pageIndex);
            }
        }
    
    
        private void PlayAudio (int documentID, int pageIndex)
        {
            foreach (DocumentAudio documentAudio in documentAudios)
            {
                if (documentAudio.documentID == documentID)
                {
                    if (pageIndex >= 0 && pageIndex < documentAudio.pageAudios.Length)
                    {
                        PageAudio pageAudio = documentAudio.pageAudios[pageIndex];
                        KickStarter.dialog.GetNarratorAudioSource ().ignoreListenerPause = true;
                        KickStarter.dialog.StartDialog (null, pageAudio.speechLineID, true, true);
                    }
                }
            }
        }
    
    
        private void StopAudio ()
        {
            KickStarter.dialog.EndSpeechByCharacter (null);
        }
    
    
        [System.Serializable]
        private class DocumentAudio
        {
    
            public int documentID = 0;
            public PageAudio[] pageAudios = new PageAudio[0];
    
        }
    
    
        [System.Serializable]
        private class PageAudio
        {
    
            public AudioClip audioClip = null;
            public int speechLineID;
    
        }
    
    }
    

    Instead of assigning audio clips directly, this refers to pre-made speech lines.

    Create a new scene just for document audio. Add a Dialogue: Play speech Action, set as narration (no speaker), for each page text. Gather it up, and assign the audio in the Speech Manager in the usual way.

    Then assign each line's ID number into the component, where before you assigned audio clips.

  • Thank you Chris! I will try!
    Btw. the release of a short demo game is soon, stay tuned, I hope you will like it!

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.
Do NOT follow this link or you will be banned from the site!