Forum rules - please read before posting.

[Scripting][Custom Action] Open Document and Wait (until it's closed) - never waits

Hi there!
I was unsure about where to post this, since I ended up extending AC, but may be not the best approach, so I posted it here

I needed to create an Actionlist Asset that could accept as parameters

  • 1 on-Scene Cutscene reference (used to comment the document before reading it)
  • 1 document
  • 1 on-Scene Cutscene reference (used to comment the document after reading it)

The desired flow is:

Click on a hotspot that triggers such Actionlist Asset, using Set Interaction Parameters to pass the appropriate IDs and documentIDs.

  • the main char says a comment, stored as a cutscene in the scene.
  • The Unity uGUI prefab Document Menu pops up (rendered as camera overlay since I still haven't solved the screen ratio issue)
  • The player closes the document via the close button.
  • The char comments about what she's just read.

I have several documents and using just a single ActionList Asset to handle the action is very useful to me, since I could make some changes, and it would propagate to the whole game.

So I created the OpenDocumentAndWait Custom Action but, for some reason, I can't find what to check to avoid exiting immediately.

I even added an extra wait by default, but menu.IsOn/IsActive/IsVisible is not helping me to wait for the Menu to disappear.

The custom script is basically identical to the Open Document, but waits until the Document menu disappears.

Here's what I changed, but doesn't seem to work, and currently I can't figure out what's wrong.

Thanks for your time.

Could you please have a look and see if there's something obvious that I'm doing wrong?

` override public float Run ()
{
Document document = KickStarter.inventoryManager.GetDocument (documentID);
Menu menu = PlayerMenus.GetMenuWithName("Document");

        if (document != null)
        {
            if (addToCollection)
            {
                KickStarter.runtimeDocuments.AddToCollection(document);
            }
            KickStarter.runtimeDocuments.OpenDocument(document);

            return defaultPauseTime;
        }

        if (!menu)
            return 0f;

        if (menu.IsOn())
            return defaultPauseTime;

        return 0f;
    }`

Comments

  • I forgot to mention - so this is also a feat. request thread :P - would it be possible to add a few events like "OnDocumentOpen(documentID)" and (OnDocumentClose(DocumentID)), if they're not already there?

  • I believe I solved it (found the above events).

    I should hide a few menus temporarily, but there's no way to "compose" the show conditions (something like a showMask), so I will try to do it manually by hooking the OnDocumentOpen and OnDocumentClose events - hoping not to compromise the UI due to something going wrong while the menus are temporarily hidden.

    Unfortunately to make everything respect the black bars and forced aspect ratio, the Document UI is rendered via camera overlay. But the menus I need to hide are on shown as screen space overlay, so they always get shown first.

    I hope that TurnOn and TurnOff are going to do the job.

    So, here's my solution, even if I can't understand what was wrong with the code I posted above (maybe the use of isRunning and willWait?)

    `
    public override float Run ()
    {
    // First run
    if (!isRunning)
    {
    cachedDocument = KickStarter.inventoryManager.GetDocument(documentID);
    cachedMenu = PlayerMenus.GetMenuWithName("Document");

                thisDocGotClosed = false;
    
                if (cachedDocument != null)
                {
                    if (addToCollection)
                    {
                        KickStarter.runtimeDocuments.AddToCollection(cachedDocument);
                    }
    
                    KickStarter.runtimeDocuments.OpenDocument(cachedDocument);
    
                    EventManager.OnCloseDocument += EventManagerOnCloseDocument;
                }
    
                isRunning = true;
            }
    
            if (thisDocGotClosed)
            {
                EventManager.OnCloseDocument -= EventManagerOnCloseDocument;
                isRunning = false;
                return 0f;
            }
    
            if (!willWait)
            {
                EventManager.OnCloseDocument -= EventManagerOnCloseDocument;
                isRunning = false;
                return 0f;
            }
    
            return defaultPauseTime;
        }
    
        protected virtual void EventManagerOnCloseDocument(Document document)
        {
            if (document == cachedDocument)
            {
                thisDocGotClosed = true;
            }
        }`
    
  • Bear in mind that the ActionList in question would have to be running in the background - or the Document menu would have to be interactive during Cutscenes - otherwise gameplay will be blocked for the duration.

    The first script did have issues with isRunning, but you can also just check the state of the RuntimeDocument script's ActiveDocument variable.

    A separate Action that does this, after the Document: Open Action, is as follows:

    using UnityEngine;
    #if UNITY_EDITOR
    using UnityEditor;
    #endif
    
    namespace AC
    {
    
        [System.Serializable]
        public class ActionDocWait : Action
        {
    
            public ActionDocWait ()
            {
                this.isDisplayed = true;
                category = ActionCategory.Document;
                title = "Wait until closed";
            }
    
            public override float Run ()
            {
                if (!isRunning || KickStarter.runtimeDocuments.ActiveDocument != null)
                {
                    isRunning = true;
                    return defaultPauseTime;
                }
                else
                {
                    isRunning = false;
                    return 0f;
                }
            }
    
        }
    
    }
    
  • I see, I forgot the "isRunning" was essential to avoid the action to exit on first run.

    Yes, at first I was checking if the document was open, but I ended up doing something a bit more complex.

    I went a step ahead actually, basically freezing the game :P

    That is, I entered a scripted cutscene as soon as the document was open.

    But, of course, no "back" button was working on the document interface anymore.

    So I had to add some actual code to the button, using Unity's raycaster, implementing the Ipointerclick interface, doing a few checks, intercepting the click on the Back button, exiting from cutscene mode, and faking another button click, to let AC act as usual.

    Very hackish, I know, but I have both a screen space overlay and a camera overlay UI, and the easiest way that I knew to hide ALL other UIs and to remove all possible input or interaction was to enter a cutscene.

    it's sort of working now, but I definitely need to solve the aspect ratio issue, so that I can switch back to using Screen Space Overlay UIs only, allowing me to mask or block clicks, without having UIs overlapping.

    Also, camera overlay canvases are giving me all kind of headaches, since I have some extreme closeup on objects.

    And, of course, if the camera distance to the object is 3cms, and the camera UI is at 0.5m, it gets rendered behind walls.
    And, reducing the distance from the camera UI creates all kind of artifacts with text rendering/

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.