Forum rules - please read before posting.

Cycle through Hotspots depending on Active Camera

I'm working on porting my game "The Abandoned Planet" to console:

https://store.steampowered.com/app/2014470/The_Abandoned_Planet/

I'm working with a porting team to do this. In fact, one of them, Ewoud, reached out about an input issue:

https://adventurecreator.org/forum/discussion/15379/gamepad-cursor-not-working-with-unity-ui-elements#latest

But on to my question here -- the main custom aspect to my game is how to navigate from area to area. Chris developed a script called MiniLocation that I use to do this. This script was discussed here:

https://adventurecreator.org/forum/discussion/13234/menus-being-stored-in-dontdestroyonload#latest

Since we are porting to console, we are reworking the input to work entirely with a gamepad. I had the idea to eliminate the cursor completely from the game!!! This is my idea:

  • When a new camera is active, all the enabled hotspots can be cycled through with the analogue sticks (the Dpad is being used for navigating the MiniLocations).
  • Perhaps each MiniLocation script could have an array of hotspots (Yes; I would tediously drag and drop each one in the scene into the array) that may or may not be enabled when the associated camera is active. (This would allow the player to cycle through them in an organized fashion... top to bottom of the array == left to right // up to down on the analogue stick).

I'm currently using the custom script here to flash an icon over all enabled hotspots:

https://adventure-creator.fandom.com/wiki/Hold_input_to_flash_Hotspots

That script just flashes that icon over all available hotspots, but I would want that icon to appear over the selected hotspot only. But maybe that's not the road to go down. Maybe using the interaction icons in the Cursor menu is the right way to go -- although I'm trying to eliminate the cursor since it can be cumbersome with a gamepad analogue stick.

Anyways, any guidance here would certainly be appreciated. What would be the best road to go down for something like this? - Jeremy

Comments

  • This can be done with the use of a custom interaction system. The Manual chapter of the same name has details.

    The behaviour you're going for, however, sounds quite similar to the included CustomInteractionSystemExample script - which involves clicking on-screen buttons to cycle through the various Hotspots in the scene. I'd recommend trying it out in AC's 3D Demo scene in a fresh project.

    Having each MiniLocation store its own Hotspots would be the first step: if you have your Hotspots all be children of a shared MiniLocation parent, however, you can automate their assignment. Something like this, added to the existing script:

    public Hotspot[] hotspots = new Hotspot[0];
    void OnValidate ()
    {
        if (hotspots.Length == 0) hotspots = GetComponentsInChildren<Hotspot> ();
    }
    

    You'd then need a custom script that reads input to cycle through the available Hotspots manually. Something like this, adapted from the example script:

    using UnityEngine;
    
    namespace AC
    {
    
        public class CustomInteractionSystemExample : MonoBehaviour
        {
    
            private Hotspot selectedHotspot = null;
            private int hotspotIndex = -1;
            private int inventoryItemIndex = -1;
            private MiniLocation miniLocation;
    
    
            private void Update ()
            {
                if (miniLocation != MiniLocation.activeMiniLocation)
                {
                    if (selectedHotspot) selectedHotspot.Deselect ();
                    hotspotIndex = -1;
                }
                miniLocation = MiniLocation.activeMiniLocation;
    
                if (miniLocation == null) return;
                if (KickStarter.stateHandler.gameState != GameState.Normal) return;
    
                if (KickStarter.playerInput.InputGetButton ("HotspotNext"))
                {
                    SetNextHotspot ();
                }
                else if (KickStarter.playerInput.InputGetButton ("HotspotPrevious"))
                {
                    SetPreviousHotspot ();
                }
    
                if (selectedHotspot != null)
                {
                    if (KickStarter.playerInput.InputGetButton ("InteractionA"))
                    {
                        selectedHotspot.RunUseInteraction ();
                    }
                    if (KickStarter.playerInput.InputGetButton ("InteractionB"))
                    {
                        selectedHotspot.RunExamineInteraction ();
                    }
                }
            }
    
    
            private void SetNextHotspot ()
            {
                Hotspot hotspot = null;
    
                if (MiniLocation.activeMiniLocation.hotspots.Length > 0)
                {
                    hotspotIndex ++;
                    if (hotspotIndex >= MiniLocation.activeMiniLocation.hotspots.Length)
                    {
                        hotspotIndex = 0;
                    }
                    hotspot = MiniLocation.activeMiniLocation.hotspots[hotspotIndex];
                }
    
                UpdateHotspot (hotspot);
            }
    
    
            private void UpdateHotspot (Hotspot hotspot)
            {
                if (hotspot)
                {
                    if (hotspot != selectedHotspot)
                    {
                        if (selectedHotspot)
                        {
                            selectedHotspot.Deselect ();
                            KickStarter.playerInteraction.DeselectHotspot ();
                        }
    
                        hotspot.Select ();
                        KickStarter.playerInteraction.SetActiveHotspot (hotspot);
                    }
                }
                else
                {
                    if (selectedHotspot)
                    {
                        selectedHotspot.Deselect ();
                        KickStarter.playerInteraction.DeselectHotspot ();
                    }
                }
    
                selectedHotspot = hotspot;
            }
    
    
            private void SetPreviousHotspot ()
            {
                Hotspot hotspot = null;
    
                if (MiniLocation.activeMiniLocation.hotspots.Length > 0)
                {
                    hotspotIndex --;
                    if (hotspotIndex < 0)
                    {
                        hotspotIndex = MiniLocation.activeMiniLocation.hotspots.Length - 1;
                    }
                    hotspot = MiniLocation.activeMiniLocation.hotspots[hotspotIndex];
                }
    
                UpdateHotspot (hotspot);
            }
    
        }
    
    }
    
  • OK. This is a great start. Thank you so much Chris! I'll be working with the porting team to get this working. Thanks again. - Jeremy

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.