Forum rules - please read before posting.

Interaction selection with direct controls won't work as expected

edited July 2020 in Technical Q&A

Hello,
I have a character with a Hotspot Detector attached.

When the character collides with a hotspot trigger, the menu appears, however, i am encountering the following issues:

SCENARIO 1: Interaction Method set to: Context Sensitive
- The desired icon appears, but i can only activate that interaction pressing InteractionA on my gamepad.

SCENARIO 2: Interaction Method set to: Chose Hotspot then Interaction
- Even though a hotspot only have 1 available option, all interactions icons appears;
- I have set a unique Alternative Input Button to each interaction, but none works;

This is what i want to achieve:

  • Character collides with the hotspot. Menu with interactions appears (only available interactions, can be 1, can be 4);
  • Player presses the Unique button (on the gamepad) to activate the desired interaction. Interaction execute;

I have read tons of similar posts from uses with similar issues but unfortunately none of the solutions suggested works for me.

I am on 1.71.1, Unity 2018.4.0f1

Any ideas?

Thanks in advance

«1

Comments

  • Update:
    I have opened the 3d demo (Basement) and used whatever settings manager were associated with that demo on my debug level, the issue is still there (even though the same settings work in the demo).

    I am assuming the issue/bug is at the hotspot level?

    It's worth mentioning that i have both tried using AC UI and Unity UI

  • edited July 2020

    To have an Interaction menu only display icons that are available for the currently-selected Hotspot, check Auto-hide Interaction icons based on Hotspot? in the Settings Manager.

    Not sure why the "Alternative input button" fields wouldn't be responding, though. Do be aware that in this field you need to enter the name of the Input as defined in Unity's Input Manager - not the input key itself.

    Hard to say what else it might be, otherwise. If you'd like to share screenshots showing your setup - Settings Manager and Interaction elements included - I'll try to spot what's wrong.

  • edited July 2020

    Hello Chris,
    Auto-hide interactions icons was already active and i have also set the correct input name and not the input key (InteractionA, InteractionB, InteractionC and InteractionD, which are correctly set up in the Input Manager).

    I can't post screenshots right now but the setup is fairly simple:

    Settings/Interface Settings:

    Movement method: Direct;
    Input method: Keyboard or Controller;
    Interaction method: Choose hotspot then interaction;
    Select Interactions by: Clicking Menu;
    See interactions with: Click on Hotspot;
    V: Auto hide interaction icons based on Hotspot?
    V:Close Interactions if Player leaves Hotspot's vicinity;
    V: Lock cursor in screen's centre when game begins?
    V: Hide cursor when locked in screen's centre?

    Hotspot settings:

    Hotspot detection method: Player Vicinity;
    V: Place distant Hotspots on separate layer?
    Hotspots in vicinity: Nearest Only;
    Display Hotspot icons: Via Script Only (using raycast to determine which icon to show).

    Each menu interaction has an Alternative Input Button (such as InteractionA, InteractionB, InteractionC). I am using AC UI as source.

    What i am expecting to happen:

    Player enters Hotspot collider to highlight it;
    Only enabled interactions show up;
    Player presses a button on the gamepad, corresponding to the desired action;

    What happens instead:

    Player enters Hotspot collider to highlight it;
    ALL interactions show up;
    No matter what player presses, no interaction triggers;

    What i am trying to achieve is something along the line of Life Is Strange interaction method, as also discussed here:

    https://adventurecreator.org/forum/discussion/2420/user-interface-life-is-strange-style

    It's not entirely clear why you suggest to use custom scripts in that thread when the settings listed in AC Settings Manager should in theory achieve a similar result (visual customisation apart).

    I will try to post screenshots soon, till then, i hope what i have posted above is enough to identify the issue.

    Thanks in advance!

  • Thank you. Please do try to share screens when you can, but I will see what I can find out in the meantime.

  • I can't recreate any issue about the wrong interaction icons showing up when following the above and using the default interface, but be aware that "InteractionA" and "InteractionB" are existing input names that AC relies on.

    You should rename your Alternative Input Buttons to something else like "Icon_Use" etc to avoid there being a conflict.

    Also, if you're going for a "Life Is Strange" type interface where interaction icons show up automatically, take a look at these scripts on the AC wiki:

    https://adventure-creator.fandom.com/wiki/Proximity-based_Interaction_menus
    https://adventure-creator.fandom.com/wiki/Simultaneous_Hotspot_labels

  • Hey Chris,
    I think i have identified the issue, you have mentioned the solution in your previous response.

    Basically i was using the existing "Use" menu rather than creating a custom one and completely disregard the existing ones. Once i have assigned an alternative input key for each of the custom menu i have created (one per interaction), it worked.

    I am not sure it was completely clear when i have looked for that information up on the manual and i was just expecting for the "alternative input" to just take over the existing one.

    One last thing, how can i execute an action script when the player interacts with a Hotspot, before the interactions menu appears/disappears?

    • Player is near Hotspot, interaction icon appears;
    • Player interacts with the hotspot, Action Script is called (e.g. Camera swaps), The interaction menu appears (at the end of the Action Script functions);
    • Player chooses the desired interaction;
    • Player closes the interactions menu, Action Script is called (e.g. Camera swaps back to game-play);

    Thanks for the help!

  • edited July 2020

    In AC terms, Interaction menus are how you run a Hotspot interaction - so anything before then wouldn't technically be an interaction unless you involved another Hotspot.

    It is possible to hook into AC via custom events, which are a way of running custom code (even just to trigger another ActionList) when AC performs common tasks. Examples being when a Hotspot is highlighted, a menu is turned on, or a character speaks.

    It may be that OnHotspotSelect is what you're looking for, which runs when a Hotspot is highlighted but before the Player actually chooses an interaction from the menu - but this will kick in automatically without user input unless you're using a custom way to detect Hotspots.

    What's the actual scenario here? For a close-up? How should a Player "interact" with a Hotspot in order to bring up the interaction menu? If you can elaborate more on exactly what it is you're trying to achieve, I can see if I can give more specific advice - at the moment I can only offer general adivce.

  • edited July 2020

    Hello Chris,
    Ideally i would like to run an ActionList, so that i have access to AC's actions.

    In this specific case i would like to swap to a different camera but it can really be anything, reason why the AL solution would be desired.

    Isn't it possible to have something like the Interaction Menu's Action List when turn on/off, only related to hotspot, rather than the menu?

    This way, each hotspot could contain a set of custom Action List that are executed right before the interaction menu appears or right after it disappears (or right before it disappears, etc).

    Scenario:

    • Player moves with direct controls;
    • Hotspots icons are shown based to proximity;
    • Player presses a button on the gamepad to interact with the nearest hotspot; (select
      hotspot then interactions);

    • Camera blends to close-up of hotspot object (but not limited to, i might need anything else, depending on the scenario. Maybe an NPC walking to the player? A sfx? Lights in the room turns off? etc);

    • When the Action has finished (wait until finish), then the interaction menu is shown;
    • Player chose interaction, than decides to close the interaction menu (presses button on gamepad);
    • Interactions menu closes, camera swaps back to gameplay;
    • Player moves away from hotspot;

    My intent is to make the hotspot interaction less mechanical and more narrative.

    Hope this makes sense.

    If it can be of any help, i can upload on gdrive a debug project i have made to test the control options and hotspot interactions.

    Cheers!

  • edited August 2020

    If you wanted to run some Actions just when the interaction menu turns on, you could create an "ActionList when turn on" for it - and possibly customise it with parameters based on the Hotspot that it's displaying icons for.

    But to run a sequence of Actions before displaying the menu needs a different approach.

    This is quite a specific intended behaviour, so let's take things step-by-step and just focus on bringing up the menu to begin with.

    In your Settings Manager, set your See interactions with field to Via Script Only. This will disable the default way of bringing up interaction menus in favour of the ability to script it instead.

    To enable the Interaction menu for a given Hotspot, you can then call:

    AC.KickStarter.playerMenus.EnableInteractionMenus (myHotspot);
    

    The OnEndActionList can be used to run such a line once a Cutscene attached to a Hotspot has been run - so all you should need is a simple script to detect input and run the Cutscene:

    using UnityEngine;
    using AC;
    
    public class CustomSelectHotspot : MonoBehaviour
    {
    
        public string selectInput = "SelectHotspot";
        private Hotspot waitHotspot;
    
        void OnEnable () { EventManager.OnEndActionList += OnEndActionList; }
        void OnDisable () { EventManager.OnEndActionList -= OnEndActionList; }
    
        void Update ()
        {
            if (Input.GetButtonDown (selectInput) && KickStarter.stateHandler.IsInGameplay ())
            {
                Hotspot activeHotspot = KickStarter.playerInteraction.GetActiveHotspot ();
                if (activeHotspot)
                {
                    Cutscene cutscene = activeHotspot.GetComponent <Cutscene>();
                    if (cutscene)
                    {
                        waitHotspot = activeHotspot;
                        cutscene.Interact ();
                    }
                    else
                    {
                        KickStarter.playerMenus.EnableInteractionMenus (activeHotspot);
                    }
                }
            }
        }
    
        void OnEndActionList (ActionList actionList, ActionListAsset actionListAsset, bool isSkipping)
        {
            if (actionList != null && waitHotspot != null && actionList.gameObject == waitHotspot.gameObject)
            {
                waitHotspot = null;
                KickStarter.playerMenus.EnableInteractionMenus (waitHotspot);
            }
        }
    
    }
    

    Attach that to an empty GameObject in your scene and configure the input field. Attach a Cutscene to your Hotspot, and it should then run when it's selected and the input is pressed. Once the cutscene is over, the menu should then show.

  • Thank you Chris,
    That is exactly what i wanted to achieve.

    I think i can also extend the script you have shared so to run a "post-interactions" cut-scene which is unique to the ActiveHotspot.

    Thanks a lot for your help, much appreciated!

  • edited August 2020

    Update...

    For some reason, after selecting an interaction, the interaction menu automatically closes, even if CloseInteractionsWith is set to: ViaScriptOnly.

    I have also tested all other options, (cursor leaves menu, cursor leaves hotspot or menu, click off menu) but the result is always the same.

    Close Interactions Menu if Player Leaves Hotspot Vicinity is also true (i have also tried disabling it).

    Besides the script Christ shared in this thread, i have no other custom scripts running.

    Here's a video of the behaviour:

    This is what's happening in the video:

    • Player enters a hotspot trigger;
    • Player presses Gamepad Button (called Interaction_South, associated to A on Xbox controller);
    • Interaction Menu appears;
    • Player select any of the interactions. The associated action executes and then the interaction menu closes;

    I would just like the Interaction Menu to stay open even after an interaction has been triggered, i will later add an "exit hotspot" button either via menu or script.

    Edit:
    Now that i think about it, this is probably because the interaction menu is automatically set to close once the player interacts with one of the interactions?

    But given the interactions are only set to be shown via script, and there is no code for that, then the menu won't just come back?

    Unless i am missing something, it seems AC force the interactions menu to close briefly as an interaction is being triggered, even if the Hide interaction menu is set to any of the available options? (cursor leaves menu, cursor leaves hotspot or menu, click off menu, via script only).

  • edited August 2020

    AC will close interaction menus automatically when an interaction is chosen, yes.

    Specifically, it will affect menus that have an Appear type value of On Interaction.

    You can set this instead to e.g. Manual, but you'll then need to bypass the EnableInteractionMenus function above in favour of setting up and turning on the menu manually.

    Try this alternative:

    using UnityEngine;
    using AC;
    
    public class CustomSelectHotspot : MonoBehaviour
    {
    
        public string selectInput = "SelectHotspot";
        private Hotspot waitHotspot;
    
        void OnEnable () { EventManager.OnEndActionList += OnEndActionList; }
        void OnDisable () { EventManager.OnEndActionList -= OnEndActionList; }
    
        void Update ()
        {
            if (Input.GetButtonDown (selectInput) && KickStarter.stateHandler.IsInGameplay ())
            {
                Hotspot activeHotspot = KickStarter.playerInteraction.GetActiveHotspot ();
                if (activeHotspot)
                {
                    Cutscene cutscene = activeHotspot.GetComponent <Cutscene>();
                    if (cutscene)
                    {
                        waitHotspot = activeHotspot;
                        cutscene.Interact ();
                    }
                    else
                    {
                        KickStarter.playerMenus.EnableInteractionMenus (activeHotspot);
                    }
                }
            }
        }
    
        void OnEndActionList (ActionList actionList, ActionListAsset actionListAsset, bool isSkipping)
        {
            if (actionList != null && waitHotspot != null && actionList.gameObject == waitHotspot.gameObject)
            {
                Menu menu = PlayerMenus.GetMenuWithName ("Interaction");
                menu.MatchInteractions (waitHotspot, true);
                menu.TurnOn (true);
    
                waitHotspot = null;
            }
        }
    
    }
    

    Do note, though, that the whole concept of AC's own "interaction menus" can be overridden entirely with your own custom interaction script if desired. See the included "Custom Interaction System Example" component for an example - it's possible to access and trigger Hotspot interactions directly through custom script, meaning you can use an entirely custom means of displaying them if you wanted to.

  • Hello Chris,
    Not sure that does what i meant.

    My issue is that the Interactions Menu won't reappear after the interaction has been executed.

    The latest script you have shared seems to only trigger the interaction menu after the cut-scene on the Hotspot has been played (which already worked with the previous iteration of the script).

    Expected behaviour:

    • Player interacts with Hotspot;
    • Cut scene is executed (if there's one);
    • Interactions menu appears;
    • Player chooses an interaction;
    • Interaction menu disappears;
    • Interaction is executed;
    • Interactions menu appears (only once interaction action list ends);
    • And so on...

    Another issue is that if i set the AppearType to Manual in the Interaction Menu options (as you suggested), the interaction menu won't disappear once the player leaves the Hotspot proximity, even if that option is flagged.

    What I need is a function that checks once an interaction (Action List) has finished playing, so that the Interaction Menu can be shown again.

    Really appreciate your help.

  • edited August 2020

    Sorry, you're right - I did misunderstand. Revert the changes to the Menu's properties in my last post.

    What I need is a function that checks once an interaction (Action List) has finished playing, so that the Interaction Menu can be shown again.

    You could potentially record the Interaction ActionList as it begins, and then update the menu once it ends - but it would stop you from being able to run e.g. another Cutscene or ActionList asset within that Interaction as part of the reaction.

    Probably better to hook into the OnEnterGameState event, which can be used to detect when gameplay is returned to normal:

    using UnityEngine;
    using AC;
    
    public class CustomSelectHotspot : MonoBehaviour
    {
    
        public string selectInput = "SelectHotspot";
        private Hotspot waitHotspot;
        private Hotspot interactedHotspot;
    
        void OnEnable ()
        {
            EventManager.OnHotspotInteract += OnHotspotInteract;
            EventManager.OnEnterGameState += OnEnterGameState;
            EventManager.OnEndActionList += OnEndActionList;
        }
    
        void OnDisable ()
        {
            EventManager.OnHotspotInteract -= OnHotspotInteract;
            EventManager.OnEnterGameState -= OnEnterGameState;
            EventManager.OnEndActionList -= OnEndActionList;
        }
    
        void Update ()
        {
            if (Input.GetButtonDown (selectInput) && KickStarter.stateHandler.IsInGameplay ())
            {
                Hotspot activeHotspot = KickStarter.playerInteraction.GetActiveHotspot ();
                if (activeHotspot)
                {
                    Cutscene cutscene = activeHotspot.GetComponent <Cutscene>();
                    if (cutscene)
                    {
                        waitHotspot = activeHotspot;
                        cutscene.Interact ();
                    }
                    else
                    {
                        KickStarter.playerMenus.EnableInteractionMenus (activeHotspot);
                    }
                }
            }
        }
    
        void OnHotspotInteract (Hotspot hotspot, AC.Button button)
        {
            interactedHotspot = hotspot;
        }
    
        void OnEnterGameState (GameState gameState)
        {
            if (gameState == GameState.Normal && interactedHotspot != null)
            {
                if (KickStarter.player.hotspotDetector.GetSelected () == interactedHotspot)
                {
                    KickStarter.playerMenus.EnableInteractionMenus (interactedHotspot);
                    interactedHotspot = null;
                }
                interactedHotspot = null;
            }
        }
    
        void OnEndActionList (ActionList actionList, ActionListAsset actionListAsset, bool isSkipping)
        {
            if (actionList != null && waitHotspot != null && actionList.gameObject == waitHotspot.gameObject)
            {
                KickStarter.playerMenus.EnableInteractionMenus (waitHotspot);
                waitHotspot = null;
            }
        }
    
    }
    
  • edited August 2020

    Thanks for the update Chris,
    However the latest script generates a series of StackOverflowExceptions.

    I have managed to achieve the expected behaviour with a combination of custom actions and parameters, it's not ideal but I will stick to it so i can progress with my prototype.

    Thanks anyway, in any case I have learned a few new things about AC scripting!

  • Can you share the StackOverflow error as it appears in the Console? Maybe I can spot what's wrong - though I don't get such an issue myself.

  • There you go!

  • edited August 2020

    That's not the usual StackOverflowException message I was expecting. A google search of this suggests restarting Unity may fix it.

    At what exact point do the messages appear? Try this slightly better-practice alternative:

    using UnityEngine;
    using AC;
    
    public class CustomSelectHotspot : MonoBehaviour
    {
    
        public string selectInput = "SelectHotspot";
        private Hotspot waitHotspot;
        private Hotspot interactedHotspot;
    
        void OnEnable ()
        {
            EventManager.OnHotspotInteract += OnHotspotInteract;
            EventManager.OnEnterGameState += OnEnterGameState;
            EventManager.OnEndActionList += OnEndActionList;
        }
    
        void OnDisable ()
        {
            EventManager.OnHotspotInteract -= OnHotspotInteract;
            EventManager.OnEnterGameState -= OnEnterGameState;
            EventManager.OnEndActionList -= OnEndActionList;
        }
    
        void Update ()
        {
            if (Input.GetButtonDown (selectInput) && KickStarter.stateHandler.IsInGameplay () && !KickStarter.playerMenus.IsInteractionMenuOn ())
            {
                Hotspot activeHotspot = KickStarter.playerInteraction.GetActiveHotspot ();
                if (activeHotspot)
                {
                    Cutscene cutscene = activeHotspot.GetComponent <Cutscene>();
                    if (cutscene)
                    {
                        waitHotspot = activeHotspot;
                        cutscene.Interact ();
                    }
                    else
                    {
                        KickStarter.playerMenus.EnableInteractionMenus (activeHotspot);
                    }
                }
            }
        }
    
        void OnHotspotInteract (Hotspot hotspot, AC.Button button)
        {
            interactedHotspot = hotspot;
        }
    
        void OnEnterGameState (GameState gameState)
        {
            if (gameState == GameState.Normal && interactedHotspot != null)
            {
                if (KickStarter.player.hotspotDetector.GetSelected () == interactedHotspot)
                {
                    KickStarter.playerMenus.EnableInteractionMenus (interactedHotspot);
                }
                interactedHotspot = null;
            }
        }
    
        void OnEndActionList (ActionList actionList, ActionListAsset actionListAsset, bool isSkipping)
        {
            if (actionList != null && waitHotspot != null && actionList.gameObject == waitHotspot.gameObject)
            {
                KickStarter.playerMenus.EnableInteractionMenus (waitHotspot);
                waitHotspot = null;
            }
        }
    
    }
    
  • It appeared to be a bug with Unity, in fact the OverflowStack issue disappeared after restarting.

    Thanks for the incredible help Chris, the last version of the script you have shared works!

  • I am only reopening this thread because the following questions are related to it and opening a new thread would have been overkill. Happy to do it if advised otherwise.

    The following scenarios are happening when using the script shared by Chris (you can find it above).

    Issue 1:

    When interacting with one of the available interactions, the camera return to the last game-play camera before executing the associated action.

    This seems like a hard-coded behaviour as i have not seen any option in the system manager.

    Expected behaviour:

    • Player interacts with a hotspot;
    • If any, the hotspot cutscene (introduction) is played (e.g. camera zoom in);
    • The hotspot's interaction menu appears;
    • Player interacts with one of the interactions;
    • Interaction's associated action list is executed;
    • At the end of the action, the interaction menu appears again;
    • Player either select a different interaction or exit the hotspot;

    What happens instead:

    • Player interacts with a hotspot;
    • If any, the hotspot cutscene (introduction) is played (e.g. camera zoom in);
    • The hotspot's interaction menu appears;
    • Player interacts with one of the interactions;
    • The camera switch back to the last game-play camera (this is unintended);
    • Interaction's associated action list is executed;
    • At the end of the action, the interaction menu appears again, but the camera is the last game-play camera and not the hotspot camera i have initially switched to;

    Is there a way to prevent AC to automatically switching back to the last gameplay camera, without having to force a camera switch at the beginning of each interaction? (i am currently using this method)

    Issue 2:

    When executing an Object/ChangeMaterial action, the Interaction menu won't reappear. This does not happens if i am playing a dialogue on the player.

    Expected behaviour:
    - Player interacts with a hotspot;
    - If any, the hotspot cutscene (introduction) is played (e.g. camera zoom in);
    - The hotspot's interaction menu appears;
    - Player interacts with an action that changes the material of a given object;
    - The material changes;
    - The interaction menu reappears;

    What happens instead:

    • Player interacts with a hotspot;
    • If any, the hotspot cutscene (introduction) is played (e.g. camera zoom in);
    • The hotspot's interaction menu appears;
    • Player interacts with an action that changes the material of a given object;
    • The material changes;
    • The interaction menu does not reappear;

    If i add a Dialogue/Player right after the Object/ChangeMaterial node, the menu reappears. However, if the Dialogue/Player dialogue is empty, the menu won't reappear.

    Using AC 1.71.8 over Unity 2018.4.0f1.

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.