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):
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.
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);
}
}
}
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);
}
}
}
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:
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
I have tried to update the script but the hotspot still do not fade out after eth fade duration time:
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.:
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:
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:
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?