Forum rules - please read before posting.

Does Player Vicinity override a disabled hotspot?

I have my hotspot settings set to player vicinity in a certain scene, but am also disabling specific hotspots, however, once the player is near these hotspots he can still interact with them. Is it the case that Player Vicinity overrides a disabled hotspot? And if so , how do i override that?

«1

Comments

  • A disabled Hotspot should not be interactive no matter what the detection mode is. What is your AC version?

    How are you disabling these Hotspots, and are they labelled as such at the top of their Hotspot components?

  • AC V1.74.2

    I created an actionlist parameter for off and one for on

    Here are screenshots of how I turn them off/on:

    https://www.dropbox.com/sh/yh74gyeqqus3kqp/AABP0THMuBMkUbjppIWkrZq_a?dl=0

  • When is the ActionList run, and are the Hotspots selected at the time?

    Again: are they labelled as disabled in their Inspectors? What layer are their GameObjects on after the ActionList has been run?

  • I fixed the above, but I have another question, is there a way (or a script) where you could choose whether hotspots were still active even with the Player Vicinity setting on?

  • For that, you would need to write a custom Hotspot Detection method script - see the Manual's "Custom interaction systems" chapter for details.

  • After looking at the manual, and being a bit of a noob, I'm still a little lost, would you be able to start me in the right direction?

  • You would need to elaborate more fully on what exactly you want the behaviour to be.

  • So, I would like to have an option on a hotspot in the inspector on whether it is affected by player vicinity or not, ie whether it overrides player vicinity setting if set.

  • With Hotspots being detected by mouse position otherwise?

    Switch your "Hotspot detect method" to "Mouse Over" and assign Interactive Boundaries to your Hotspots instead.

    Intended as an alternative to the Hotspot Detector, an Interactive Boundary describes a region that - if set - only allows a Hotspot to be interactive if the Player is within it.

  • Ok so to elaborate further to determine if the above solution you propose will still work, the player enters a scene that is pitch black, with three areas, left middle and right with hotspot detection for set to mouse over but with no hotspots enabled.

    Once the player lights his candle we switch to player vicinity so that hotspots become available in areas Left, middle and right when in the vicinity of the candle light.

    Once the player lights a lamp in the left part of the room, i want the hotspots in the left part of the room to be mouse over and the hotspots in middle and right to still be player vicinity as it is still dark in those areas and the candle light hotspots reveal.

    Once the player lights middle lamp is like middle hotspots to now be mouse over but remaining right area to still be player vicinity until right area lamp is lit.

    Does that make sense? Would your solution work or would a script placed on individual hotspots be better where I can call to switch their detection?
  • It would still work - all you'd need is a script attached to each Hotspot that dynamically assigns/unassigns the Interactive Boundary when each lamp is turned on. If a Hotspot's Interactive Boundary field is cleared, it then becomes interactive from any position again.

    Assuming each lamp's state has an associated Boolean variable set to True when lit, this script attached to each Hotspot should do it:

    using UnityEngine;
    using AC;
    
    public class DynamicInteractiveBoundary : MonoBehaviour
    {
    
        public string boolVarName;
        public InteractiveBoundary interactiveBoundary;
        public Hotspot hotspot;
    
        private void OnEnable () { EventManager.OnVariableChange += OnVariableChange; }
        private void OnDisable () { EventManager.OnVariableChange -= OnVariableChange; }
    
        private void OnVariableChange (GVar variable)
        {
            if (variable.label == boolVarName)
            {
                bool isOn = variable.BooleanValue;
                hotspot.interactiveBoundary = isOn ? null : interactiveBoundary;
            }
        }
    }
    
  • edited January 2022

    ok, so this isn't working for me. All hotspots are still on regardless of whether player is in the boundary whether variable is true or false:

    https://www.dropbox.com/s/w0ud13pa25al4sk/MouseOver.mov?dl=0

  • You need to assign the Interactive Boundary by default - either in the Hotspot's Inspector, or through script:

    using UnityEngine;
    using AC;
    
    public class DynamicInteractiveBoundary : MonoBehaviour
    {
    
        public string boolVarName;
        public InteractiveBoundary interactiveBoundary;
        public Hotspot hotspot;
    
        private void OnEnable ()
        {
            EventManager.OnInitialiseScene += OnInitialiseScene;
            EventManager.OnVariableChange += OnVariableChange;
        }
    
        private void OnDisable ()
        {
            EventManager.OnInitialiseScene -= OnInitialiseScene;
            EventManager.OnVariableChange -= OnVariableChange;
        }
    
    
        private void OnInitialiseScene ()
        {
            GVar variable = GlobalVariables.GetVariable (boolVarName);
            bool isOn = variable.BooleanValue;
            hotspot.interactiveBoundary = isOn ? null : interactiveBoundary;
        }
    
    
        private void OnVariableChange (GVar variable)
        {
            if (variable.label == boolVarName)
            {
                OnInitialiseScene ();
            }
        }
    }
    
  • edited January 2022

    Got it. Works perfectly! Thanks!

  • edited January 2022

    I'm now getting an odd behaviour in this scene where the dialogue subtitles no longer show for any interaction. And I get this error in the console:

    https://www.dropbox.com/s/rdw7bu6ld1d8y0l/Error.png?dl=0

    And when i then leave this scene to go into a new one, it is all strange and odd, with things in the wrong position etc

  • So, as you can see by the video in the link below, without the script the player has dialogue when entering the trigger, but when I use the script in the scene, one of my objects inexplicably is visible, and there is no dialogue in the entire scene.

    Something weird is therefore happening. Can you help?

    https://www.dropbox.com/sh/kbd1cnjl5vuzdgp/AABHJcRZ8BgvocZFNQ1nAz8Za?dl=0

  • edited January 2022

    Your first error refers to line 30 of a custom script - AnimateCursor. What is the contents of this script, and what is on line 30?

    The second error looks to be due to a variable not found. Are all the "Bool Var Name" fields for the Dynamic Interactive Boundary component correctly filled?

    Try this alternative:

    using UnityEngine;
    using AC;
    
    public class DynamicInteractiveBoundary : MonoBehaviour
    {
    
        public string boolVarName;
        public InteractiveBoundary interactiveBoundary;
        public Hotspot hotspot;
    
        private void OnEnable ()
        {
            EventManager.OnAfterChangeScene += OnAfterChangeScene;
            EventManager.OnVariableChange += OnVariableChange;
        }
    
        private void OnDisable ()
        {
            EventManager.OnAfterChangeScene -= OnAfterChangeScene;
            EventManager.OnVariableChange -= OnVariableChange;
        }
    
    
        private void OnAfterChangeScene (LoadingGame loadingGame)
        {
            GVar variable = GlobalVariables.GetVariable (boolVarName);
            if (variable == null) { Debug.LogWarning ("Cannot find variable named " + boolVarName); return; }
            bool isOn = variable.BooleanValue;
            hotspot.interactiveBoundary = isOn ? null : interactiveBoundary;
        }
    
    
        private void OnVariableChange (GVar variable)
        {
            if (variable.label == boolVarName)
            {
                OnAfterChangeScene (LoadingGame.No);
            }
        }
    }
    
  • i now get this error:

    Assets/Sleepytime Village/Scripts/DynamicInteractiveBoundary.cs(19,9): error CS0123: No overload for 'OnAfterChangeScene' matches delegate 'EventManager.Delegate_AfterSceneChange'

  • Your first error refers to line 30 of a custom script - AnimateCursor. What is the contents of this script, and what is on line 30?

    You gave me this code :) this is line 30:

        int fromSlot = inventoryBox.GetItemSlot (itemToMoveFrom);
    

    This is full script

    using UnityEngine;
    using System.Collections;
    using AC;
    
    public class AnimateCursor : MonoBehaviour
    {
    
        public Vector2 offset;
        public RectTransform cursorRectTransform;
        public int itemToMoveFrom;
        public int itemToMoveTo;
        public Canvas canvas;
        public float moveDuration = 3f;
    
        public string menuName = "Inventory";
        public string inventoryElementName = "InventoryBox";
    
    
        public void AnimateCombine ()
        {
            StopAllCoroutines ();
            StartCoroutine (AnimateCombineCo ());
        }
    
    
        private IEnumerator AnimateCombineCo ()
        {
            MenuInventoryBox inventoryBox = PlayerMenus.GetElementWithName (menuName, inventoryElementName) as MenuInventoryBox;
    
            int fromSlot = inventoryBox.GetItemSlot (itemToMoveFrom);
            RectTransform fromRectTransform = inventoryBox.uiSlots[fromSlot].GetRectTransform ();
    
            Sprite originalSprite = inventoryBox.uiSlots[fromSlot].uiButton.image.sprite;
            inventoryBox.uiSlots[fromSlot].uiButton.image.sprite = null;
    
            int toSlot = inventoryBox.GetItemSlot (itemToMoveTo);
            RectTransform toRectTransform = inventoryBox.uiSlots[toSlot].GetRectTransform ();
    
            Vector2 fromPosition = fromRectTransform.position / canvas.transform.localScale.x;
            Vector2 toPosition = toRectTransform.position / canvas.transform.localScale.x;
    
            Vector2 parentOffset = canvas.GetComponent<RectTransform>().sizeDelta / 2f;
            fromPosition -= parentOffset;
            toPosition -= parentOffset;
    
            fromPosition += offset;
            toPosition += offset;
    
            Vector2 originalPosition = cursorRectTransform.anchoredPosition;
    
            float timer = moveDuration;
            while (timer > 0f)
            {
                float p = 1f - (timer / moveDuration);
                cursorRectTransform.anchoredPosition = Vector2.Lerp (fromPosition, toPosition, p);
    
                timer -= Time.deltaTime;
                yield return null;
            }
    
            inventoryBox.uiSlots[fromSlot].uiButton.image.sprite = originalSprite;
            cursorRectTransform.anchoredPosition = originalPosition;
        }
    
    
        private Rect RectTransformToScreenSpace (RectTransform transform)
        {
            Vector2 size = Vector2.Scale(transform.rect.size, transform.lossyScale);
            return new Rect((Vector2)transform.position - (size * 0.5f), size);
        }
    
    }
    
  • I've edited the alternative script above - try it again.

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.