Forum rules - please read before posting.

Disable inventory interaction for specific hotspots

Is it possible to disable inventory interactions for specific hotspots? I.e. such that if an inventory item is active (such that the cursor is currently that item) and you hover over the hotspot, it simply won't react in any way (no updating of hotspot label, etc.).

At the moment I need this primarily for hotspots that represent doors. I'd like for my doors to be 'Single interaction' hotspots that perform a 'Switch scene' action when clicked, and that this is the only interaction available whatsoever for those hotspots.

Comments

  • edited March 2019

    Is there a pattern to this? Would it be to disable all single-use Hotspots, whenever any inventory item is selected?

    You could do it by hooking into the OnInventorySelect and OnInventoryDeselect custom events - and disabling/enabling such Hotspots.

    Something like this:

    using UnityEngine;
    using System.Collections;
    using AC;
    
    public class AutoDisableSingleHotspots : MonoBehaviour
    {
    
        private void OnEnable ()
        {
            EventManager.OnInventorySelect += OnSelectInventory;
            EventManager.OnInventoryDeselect += OnDeselectInventory;
        }
    
        private void OnDisable ()
        {
            EventManager.OnInventorySelect -= OnSelectInventory;
            EventManager.OnInventoryDeselect -= OnDeselectInventory;
        }
    
        private void OnSelectInventory (InvItem _item)
        {
            foreach (Hotspot hotspot in AllHotspots)
            {
                if (hotspot.IsSingleInteraction ())
                {
                    hotspot.TurnOff ();
                }
            }
        }
    
        private void OnDeselectInventory (InvItem _item)
        {
            foreach (Hotspot hotspot in AllHotspots)
            {
                if (hotspot.IsSingleInteraction ())
                {
                    hotspot.TurnOn ();
                }
            }
        }
    
        private Hotspot[] AllHotspots
        {
            get
            {
                return FindObjectsOfType <Hotspot>();
            }
        }
    
    }
    
  • Thank you! I'll take a look at this. Although at this point I'm not completely sure if it should apply to all Single interaction hotspots, I can probably figure out some kind of pattern. As for the script, which element should I apply that to?

  • You can adapt the script to expose the exact Hotspots you want to apply it to.

    Just attach it to an empty GameObject in your scene.

  • Right, so I need this script to be present in every scene that it should apply to?

  • Yes. You can attach it to your GameEngine prefab to automate this.

  • Ah yes, thank you! I had just applied a DontDestroyOnLoad() to the script, but it's probably safer to simply attach it to the GameEngine.

    In case others want to make use of this thread, let me just point out a typo in the script: in the OnDeselectInventory() function it should be 'hotspot.TurnOn()' instead of .TurnOff() :)

  • Quite right - fixed.

  • Hello! I'm using the script above. It works great for selecting, deselecting and using inventory items, but if I combine items the hotspots stay inactive... Is there an easy fix for that?

  • Yes - the OnInventoryCombine event is triggered when that happens:

    using UnityEngine;
    using System.Collections;
    using AC;
    
    public class AutoDisableSingleHotspots : MonoBehaviour
    {
    
        private void OnEnable ()
        {
            EventManager.OnInventorySelect += OnSelectInventory;
            EventManager.OnInventoryDeselect += OnDeselectInventory;
            EventManager.OnInventoryCombine += OnCombineInventory;
        }
    
        private void OnDisable ()
        {
            EventManager.OnInventorySelect -= OnSelectInventory;
            EventManager.OnInventoryDeselect -= OnDeselectInventory;
            EventManager.OnInventoryCombine -= OnCombineInventory;
        }
    
        private void OnSelectInventory (InvItem _item)
        {
            foreach (Hotspot hotspot in AllHotspots)
            {
                if (hotspot.IsSingleInteraction ())
                {
                    hotspot.TurnOff ();
                }
            }
        }
    
        private void OnDeselectInventory (InvItem _item)
        {
            TurnOnHotspots ();
        }
    
        private void OnCombineInventory (InvItem _itemA, InvItem _itemB)
        {
            TurnOnHotspots ();
        }
    
        private void TurnOnHotspots ()
        {
            foreach (Hotspot hotspot in AllHotspots)
            {
                if (hotspot.IsSingleInteraction ())
                {
                    hotspot.TurnOn ();
                }
            }
        }
    
        private Hotspot[] AllHotspots
        {
            get
            {
                return FindObjectsOfType <Hotspot>();
            }
        }
    
    }
    
  • Thanks Chris!

  • I have another issue with this script. I have a number of single-use hotspots that starts disabled (locked doors), this scripts enables them. Is there an easy fix for that?

  • The script above specifically targets all single-use Hotspots, at the request of the original post in this thread.

    You could invert it so that only Hotspots that aren't single-use are affected by replacing:

    if (hotspot.IsSingleInteraction ())
    

    with:

    if (!hotspot.IsSingleInteraction ())
    

    Or are you looking to omit specific set of Hotspots from being affected?

    If so, you can tag Hotspots to ignore with something separate, i.e. "LockedDoor", and then replace that line instead with:

    if (hotspot.IsSingleInteraction () && !hotspot.gameObjectTag != "LockedDoor")
    
  • Yes, I'm looking to omit locked doors from being affected by the script. Adding a locked door tag works while the door is locked, but is there a way to remove the tag once the door is unlocked? I can't find an action for that..

  • If you want it to be dynamic, better to rely on a component variable instead of a tag.

    Forget the tag, and instead attach a Variables component to each Hotspot you want to control this way. (Also add a Remember Variables if you want to save its state).

    In the new Variables component, define a Bool variable named "IsLocked". You can then check/set this value with the regular Variable: Check / Variable: Set Actions.

    However, in the script, we can also check for this value. So instead of checking the tag, try this:

    if (hotspot.GetComponent <Variables>() == null || !hotspot.GetComponent <Variables>().GetVariable ("IsLocked").BooleanValue)
    
  • Perfect! Thanks again Chris! :)

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.