Forum rules - please read before posting.

Hotspots Flash all clumped together

2»

Comments

  • So it currently does have one on the root but still doesnt work witj this updated code - check out the screenshots of my menu (am copying the speechbubble menu where the text image box resizes to the text):

    https://www.dropbox.com/scl/fi/gu13zktonet1cu2qt9j3z/UNnity-UI-SmallHotspotsLabels.png?rlkey=xkfo5vo7b4fxl6r6m1h75ehq6&st=hsyxnfat&dl=0

    Here is the script updated:

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    #if UNITY_EDITOR
    using UnityEditor;
    #endif
    
    namespace AC
    {
        [System.Serializable]
        public class ActionFlashHotSpots : Action
        {
            public float flashDuration = 3f;
            public string menuName = "SmallHotspotLabels"; // The name of the Hotspot Menu to copy
            public string labelName = "HotspotSmallLabel"; // The Label element of the Hotspot Menu
            private List<Menu> localMenus;
            private bool keepFlashing = true;
    
            public override ActionCategory Category { get { return ActionCategory.Custom; }}
            public override string Title { get { return "FlashHotspot"; }}
    
            public override float Run()
            {
                if (!isRunning)
                {
                    localMenus = new List<Menu>();
    
                    Hotspot[] hotspots = FindObjectsOfType(typeof(Hotspot)) as Hotspot[];
                    foreach (Hotspot hotspot in hotspots)
                    {
                        if (hotspot.enabled && hotspot.IsOn() && hotspot.PlayerIsWithinBoundary() && hotspot.highlight && hotspot != KickStarter.playerInteraction.GetActiveHotspot() && (KickStarter.settingsManager.hotspotDetection == HotspotDetection.MouseOver || KickStarter.player.hotspotDetector.IsHotspotInTrigger(hotspot)))
                        {
                            hotspot.Flash();
                            ShowForHotspot(hotspot);
                        }
                    }
    
                    isRunning = true;
                    keepFlashing = true;
                    CoroutineRunner.Instance.StartCoroutine(FlashHotspotsCoroutine());
                    return flashDuration;
                }
    
                StopFlashing();
                return 0f;
            }
    
            private IEnumerator FlashHotspotsCoroutine()
            {
                float timer = 0f;
    
                while (keepFlashing && timer < flashDuration)
                {
                    timer += Time.deltaTime;
                    yield return null;
                }
    
                StopFlashing();
            }
    
            private void StopFlashing()
            {
                foreach (Menu menu in localMenus)
                {
                    menu.TurnOff();
                    KickStarter.playerMenus.UnregisterCustomMenu(menu, false);
                }
    
                isRunning = false;
            }
    
            private void ShowForHotspot(Hotspot hotspot)
            {
                Menu menuToCopy = PlayerMenus.GetMenuWithName(menuName);
                if (menuToCopy == null)
                {
                    ACDebug.LogWarning("Cannot find menu with name '" + menuName + "'", this);
                    return;
                }
                Menu myMenu = ScriptableObject.CreateInstance<Menu>();
    
                myMenu.CreateDuplicate(menuToCopy); // Copy from the default Menu
                myMenu.appearType = AppearType.Manual; // Set it to Manual so that we can control it easily
                myMenu.isLocked = false; // Unlock it so that the default can remain locked if necessary
                myMenu.title += this.name;
                myMenu.HotspotLabelData.SetData(hotspot, string.Empty);
    
                if (!string.IsNullOrEmpty(labelName))
                {
                    (myMenu.GetElementWithName(labelName) as MenuLabel).labelType = AC_LabelType.Normal;
                    (myMenu.GetElementWithName(labelName) as MenuLabel).label = hotspot.GetName(Options.GetLanguage());
                }
    
                myMenu.TurnOn();
    
                KickStarter.playerMenus.RegisterCustomMenu(myMenu, true);
                localMenus.Add(myMenu);
            }
    
            #if UNITY_EDITOR
    
            public override void ShowGUI()
            {
                menuName = EditorGUILayout.TextField("Menu name:", menuName);
                labelName = EditorGUILayout.TextField("Label name:", labelName);
                flashDuration = EditorGUILayout.FloatField("Flash Duration:", flashDuration);
            }
    
            #endif
        }
    }
    
  • The important aspect is unchanged from last time. You need to register the menu before turning it on, and unregister it only once it's fully turned off.

  • Sory Chris can you give me a clue on this one? Struggling to get it to work

  • edited January 27

    I have tried to update the script but the hotspot still do not fade out after eth fade duration time:

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    #if UNITY_EDITOR
    using UnityEditor;
    #endif
    
    namespace AC
    {
        [System.Serializable]
        public class ActionFlashHotSpots : Action
        {
            public float flashDuration = 3f;
            public string menuName = "SmallHotspotLabels"; // The name of the Hotspot Menu to copy
            public string labelName = "HotspotSmallLabel"; // The Label element of the Hotspot Menu
            private List<Menu> localMenus;
            private bool keepFlashing = true;
    
            public override ActionCategory Category { get { return ActionCategory.Custom; } }
            public override string Title { get { return "FlashHotspot"; } }
    
            public override float Run()
            {
                if (!isRunning)
                {
                    localMenus = new List<Menu>();
    
                    Hotspot[] hotspots = FindObjectsOfType(typeof(Hotspot)) as Hotspot[];
                    foreach (Hotspot hotspot in hotspots)
                    {
                        if (hotspot.enabled && hotspot.IsOn() && hotspot.PlayerIsWithinBoundary() && hotspot.highlight && hotspot != KickStarter.playerInteraction.GetActiveHotspot() && (KickStarter.settingsManager.hotspotDetection == HotspotDetection.MouseOver || KickStarter.player.hotspotDetector.IsHotspotInTrigger(hotspot)))
                        {
                            hotspot.Flash();
                            ShowForHotspot(hotspot);
                        }
                    }
    
                    isRunning = true;
                    keepFlashing = true;
                    CoroutineRunner.Instance.StartCoroutine(FlashHotspotsCoroutine());
                    return flashDuration;
                }
    
                StopFlashing();
                return 0f;
            }
    
            private IEnumerator FlashHotspotsCoroutine()
            {
                float timer = 0f;
    
                while (keepFlashing && timer < flashDuration)
                {
                    timer += Time.deltaTime;
                    yield return null;
                }
    
                StopFlashing();
            }
    
            private void StopFlashing()
            {
                CoroutineRunner.Instance.StartCoroutine(StopFlashingCoroutine());
            }
    
            private IEnumerator StopFlashingCoroutine()
            {
                foreach (Menu menu in localMenus)
                {
                    menu.TurnOff();
                }
    
                // Wait for menus to finish turning off (adjust delay as needed for animations)
                yield return new WaitForSeconds(0.5f);
    
                foreach (Menu menu in localMenus)
                {
                    KickStarter.playerMenus.UnregisterCustomMenu(menu, false);
                }
    
                isRunning = false;
            }
    
            private void ShowForHotspot(Hotspot hotspot)
            {
                Menu menuToCopy = PlayerMenus.GetMenuWithName(menuName);
                if (menuToCopy == null)
                {
                    ACDebug.LogWarning("Cannot find menu with name '" + menuName + "'", this);
                    return;
                }
                Menu myMenu = ScriptableObject.CreateInstance<Menu>();
    
                myMenu.CreateDuplicate(menuToCopy); // Copy from the default Menu
                myMenu.appearType = AppearType.Manual; // Set it to Manual so that we can control it easily
                myMenu.isLocked = false; // Unlock it so that the default can remain locked if necessary
                myMenu.title += this.name;
                myMenu.HotspotLabelData.SetData(hotspot, string.Empty);
    
                if (!string.IsNullOrEmpty(labelName))
                {
                    (myMenu.GetElementWithName(labelName) as MenuLabel).labelType = AC_LabelType.Normal;
                    (myMenu.GetElementWithName(labelName) as MenuLabel).label = hotspot.GetName(Options.GetLanguage());
                }
    
                myMenu.TurnOn();
    
                KickStarter.playerMenus.RegisterCustomMenu(myMenu, true);
                localMenus.Add(myMenu);
            }
    
    #if UNITY_EDITOR
    
            public override void ShowGUI()
            {
                menuName = EditorGUILayout.TextField("Menu name:", menuName);
                labelName = EditorGUILayout.TextField("Label name:", labelName);
                flashDuration = EditorGUILayout.FloatField("Flash Duration:", flashDuration);
            }
    
    #endif
        }
    }
    
  • As-is, you'd want to split up your Run function so that it separates the turn on/off/end operations into separate blocks, e.g.:

    if (!isRunning)
    {
        // Turn menus on
    }
    else if (shouldTurnOff)
    {
        // Turn menus off
    }
    else if (areMenusOff)
    {
        isRunning = false;
        return 0f;
    }
    

    Given the use of coroutines (which looks like it requires a third-party API), an Action isn't the best way to handle this. A regular MonoBehaviour would likely be better as you can then avoid the Run function altogether.

  • got to here, but it the hotspost still won't turn off:

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    
    namespace AC
    {
        [System.Serializable]
        public class FlashHotSpots : MonoBehaviour
        {
            public float flashDuration = 3f;
            public string menuName = "SmallHotspotLabels"; // The name of the Hotspot Menu to copy
            public string labelName = "HotspotSmallLabel"; // The Label element of the Hotspot Menu
            private List<Menu> localMenus = new List<Menu>();
            private bool keepFlashing = true;
            private bool shouldTurnOff = false;
            private bool areMenusOff = false;
    
            private void Start()
            {
                // Optionally, the flashing could start immediately if desired.
                // StartCoroutine(FlashHotspotsCoroutine());
            }
    
            // This method will be called from Adventure Creator
            public void StartFlashing()
            {
                StartCoroutine(FlashHotspotsCoroutine());
            }
    
            private void Update()
            {
                if (shouldTurnOff)
                {
                    StopFlashing();
                }
            }
    
            private void TurnOnMenus()
            {
                localMenus.Clear();
                Hotspot[] hotspots = FindObjectsOfType<Hotspot>();
                foreach (Hotspot hotspot in hotspots)
                {
                    if (hotspot.enabled && hotspot.IsOn() && hotspot.PlayerIsWithinBoundary() && hotspot.highlight &&
                        hotspot != KickStarter.playerInteraction.GetActiveHotspot() &&
                        (KickStarter.settingsManager.hotspotDetection == HotspotDetection.MouseOver ||
                         KickStarter.player.hotspotDetector.IsHotspotInTrigger(hotspot)))
                    {
                        hotspot.Flash();
                        ShowForHotspot(hotspot);
                    }
                }
            }
    
            private IEnumerator FlashHotspotsCoroutine()
            {
                TurnOnMenus();  // Turn on menus at the start of the flashing
    
                float timer = 0f;
                while (keepFlashing && timer < flashDuration)
                {
                    timer += Time.deltaTime;
                    yield return null;
                }
    
                shouldTurnOff = true;  // After the duration, set to turn off the menus
            }
    
            private void StopFlashing()
            {
                StartCoroutine(StopFlashingCoroutine());
            }
    
            private IEnumerator StopFlashingCoroutine()
            {
                foreach (Menu menu in localMenus)
                {
                    menu.TurnOff();
                }
    
                // Wait for menus to finish turning off (adjust delay as needed for animations)
                yield return new WaitForSeconds(0.5f);
    
                foreach (Menu menu in localMenus)
                {
                    KickStarter.playerMenus.UnregisterCustomMenu(menu, false);
                }
    
                areMenusOff = true;
            }
    
            private void ShowForHotspot(Hotspot hotspot)
            {
                Menu menuToCopy = PlayerMenus.GetMenuWithName(menuName);
                if (menuToCopy == null)
                {
                    ACDebug.LogWarning("Cannot find menu with name '" + menuName + "'", this);
                    return;
                }
    
                Menu myMenu = ScriptableObject.CreateInstance<Menu>();
                myMenu.CreateDuplicate(menuToCopy); // Copy from the default Menu
                myMenu.appearType = AppearType.Manual; // Set it to Manual so that we can control it easily
                myMenu.isLocked = false; // Unlock it so that the default can remain locked if necessary
                myMenu.title += this.name;
                myMenu.HotspotLabelData.SetData(hotspot, string.Empty);
    
                if (!string.IsNullOrEmpty(labelName))
                {
                    (myMenu.GetElementWithName(labelName) as MenuLabel).labelType = AC_LabelType.Normal;
                    (myMenu.GetElementWithName(labelName) as MenuLabel).label = hotspot.GetName(Options.GetLanguage());
                }
    
                myMenu.TurnOn();
                KickStarter.playerMenus.RegisterCustomMenu(myMenu, true);
                localMenus.Add(myMenu);
            }
        }
    }
    

    See video and set up here, thanks:

    https://www.dropbox.com/scl/fi/cjf3mchdh1dpgf6x2xl99/FlashHostspotsIssue.mov?rlkey=k4k4grg1xuksw1v2bky4bol5n&st=14nh3j0k&dl=0

    and picture of my menu:

    https://www.dropbox.com/scl/fi/dxy4o4rutbc6ob0z9juxy/HotspotsMenu.png?rlkey=o20jy6t21ger5qmr2mszchac8&st=7e7uf4kp&dl=0

  • Any help on this Chris?

  • Works for me on my end.

    There's no need for a 2nd event, though. Also, put:

    shouldTurnOff = false;
    

    in StopFlashing to prevent spamming the UnregisterCustomMenu method.

    Does the Console report the Menus registering / unregistering?

  • Strangely my hotspots do not fade out completely, I adjusted the script and the hotspots all fade out correctly but they are now clumped together again? Any ideas?

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    
    namespace AC
    {
        [System.Serializable]
        public class FlashHotSpots : MonoBehaviour
        {
            public float flashDuration = 3f;
            public string menuName = "SmallHotspotLabels"; // The name of the Hotspot Menu to copy
            public string labelName = "HotspotSmallLabel"; // The Label element of the Hotspot Menu
            private List<Menu> localMenus = new List<Menu>();
            private bool keepFlashing = true;
            private bool shouldTurnOff = false;
            private bool areMenusOff = false;
    
            private void Start()
            {
                // Optionally, the flashing could start immediately if desired.
                // StartCoroutine(FlashHotspotsCoroutine());
            }
    
            // This method will be called from Adventure Creator
            public void StartFlashing()
            {
                StartCoroutine(FlashHotspotsCoroutine());
            }
    
            private void Update()
            {
                if (shouldTurnOff)
                {
                    StopFlashing();
                }
            }
    
            private void TurnOnMenus()
            {
                localMenus.Clear();
                Hotspot[] hotspots = FindObjectsOfType<Hotspot>();
                foreach (Hotspot hotspot in hotspots)
                {
                    if (hotspot.enabled && hotspot.IsOn() && hotspot.PlayerIsWithinBoundary() && hotspot.highlight &&
                        hotspot != KickStarter.playerInteraction.GetActiveHotspot() &&
                        (KickStarter.settingsManager.hotspotDetection == HotspotDetection.MouseOver ||
                         KickStarter.player.hotspotDetector.IsHotspotInTrigger(hotspot)))
                    {
                        hotspot.Flash();
                        ShowForHotspot(hotspot);
                    }
                }
            }
    
            private IEnumerator FlashHotspotsCoroutine()
            {
                TurnOnMenus();  // Turn on menus at the start of the flashing
    
                float timer = 0f;
                while (keepFlashing && timer < flashDuration)
                {
                    timer += Time.deltaTime;
                    yield return null;
                }
    
                shouldTurnOff = true;  // After the duration, set to turn off the menus
            }
    
            private void StopFlashing()
            {
                shouldTurnOff = false; // Prevent spamming the UnregisterCustomMenu method
                StartCoroutine(StopFlashingCoroutine());
            }
    
            private IEnumerator StopFlashingCoroutine()
            {
                Debug.Log("Turning off menus...");
                foreach (Menu menu in localMenus)
                {
                    menu.TurnOff(); // Turn off the menu
                    Debug.Log("Menu turned off: " + menu.title);
                }
    
                // Wait for the fade-out animation to complete
                yield return new WaitForSeconds(1f); // Adjust the delay as needed
    
                Debug.Log("Unregistering menus...");
                foreach (Menu menu in localMenus)
                {
                    KickStarter.playerMenus.UnregisterCustomMenu(menu, false); // Unregister the menu
                    Debug.Log("Menu unregistered: " + menu.title);
                }
    
                localMenus.Clear(); // Clear the list to avoid referencing destroyed menus
                areMenusOff = true;
                Debug.Log("Menus are fully turned off and unregistered.");
            }
    
            private void ShowForHotspot(Hotspot hotspot)
            {
                Menu menuToCopy = PlayerMenus.GetMenuWithName(menuName);
                if (menuToCopy == null)
                {
                    ACDebug.LogWarning("Cannot find menu with name '" + menuName + "'", this);
                    return;
                }
    
                Menu myMenu = ScriptableObject.CreateInstance<Menu>();
                myMenu.CreateDuplicate(menuToCopy); // Copy from the default Menu
                myMenu.appearType = AppearType.Manual; // Set it to Manual so that we can control it easily
                myMenu.isLocked = false; // Unlock it so that the default can remain locked if necessary
                myMenu.title += this.name;
                myMenu.HotspotLabelData.SetData(hotspot, string.Empty);
    
                if (!string.IsNullOrEmpty(labelName))
                {
                    (myMenu.GetElementWithName(labelName) as MenuLabel).labelType = AC_LabelType.Normal;
                    (myMenu.GetElementWithName(labelName) as MenuLabel).label = hotspot.GetName(Options.GetLanguage());
                }
    
                myMenu.TurnOn();
                KickStarter.playerMenus.RegisterCustomMenu(myMenu, true);
                localMenus.Add(myMenu);
            }
        }
    }
    
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.