Forum rules - please read before posting.

Hotspot Highlighter

Is there a way that I could map a hotkey so that all the enabled hotspots in a scene are highlighted when the user presses it?
Maybe like a rectangular texture or the objects themselves glowing?

Thank you so much!

Comments

  • Also just wanted to give a heads up -- seems like the highlight texture is not working on my front, so I was just wondering what the reason might be -- I assigned an object to the "Object to Highlight" section in the hotspot, and I also added the "highlight component".

    I was trying to use "FlashHotspots" in the Input Manager btw, if that would help!

  • FlashHotspots is the input to use, yes.

    The Highlight component's default brightening effect is dependent on the render pipeline and shader the material uses. What are these for the project/sprite being affected?

    As well as the sprite itself brightening, you can also opt to show an icon over the Hotspot when highlighting. The options for this are in the "Hotspot" section of the Settings Manager.

  • I'm using the URP! The sprite is using the sprite-lit-default shader.
    And gotcha! Thank you for the heads up -- I'll look into that option if the highlighting does not work then! :)

  • That section of the Settings Manager also has a Highlight material override field, which you can use to replace the shader keyword that gets affected.

    Does the use of either _BaseColor or _Color here make any difference?

  • Ah actually I was hoping to us this shader as the outline: https://assetstore.unity.com/packages/vfx/shaders/all-in-1-sprite-shader-156513

    Here is a screenshot, along with the highlighted field.
    I'm kind of confused as to how to get this outline to show when flashing the hotspots. Might you have any thoughts?

    https://drive.google.com/file/d/1gJ7HlpwkXFYPqWTxz0XG0qh3ChttwtsC/view?usp=sharing

  • It's possible - so long as the property you want to control is publicly-accessible.

    As it's not a standard Color property that the Highlight can affect automatically, though, you'll need to update it manually.

    You'll first need to attach a custom script to the renderer that can control the property inside On/Off functions that either show or hide the intended effect.

    You can then either hook into AC's OnHotspotSelect/Deselect functions - or use the event boxes in the Highlight Inspector - to trigger these functions.

    A similar technique is used to provide an integration with the Easy Outline asset over on the wiki:
    https://adventure-creator.fandom.com/wiki/Easy_Performant_Outline_integration

    Exactly how you control the property though will be down to the shader - you may need to contact the asset's author for advice on this.

  • ah thank you so much!

    So I guess I was wondering -- is it possible for me to do it such that it doesn't highlight over when selected, but it does highlight when the "h" is pressed?

    For some reason mapping the "FlashInputs" to h currently doesn't work, but I might have missed something. The hovering does work to outline the object, however!

    I'm attaching a video of the current behavior, along with the inspector elements.
    I've also committed on GitHub just in case (I believe you should have access to the repo if you accepted the invite! :) )

    This is in the Forest2 scene!

    This is my script if that would help: https://drive.google.com/file/d/1x4KvSAaODQSp04CCZ3nDLCPonltiuyVd/view?usp=sharing

    `using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using AC;

    public class HotspotHighlight : MonoBehaviour
    {
    public Hotspot hotspot;
    private Material mat;
    // set rect to solid color so outline won't appear black
    private Color tempColor = new Color(1f, 1f, 1f, 1f);
    private Color transparentColor = new Color(0f, 0f, 0f, 0f);

    private void Awake()
    { 
        mat = GetComponent<Renderer>().material;
        mat.SetColor("_Color", transparentColor);
        //Debug.Log("COLOR AT START IS ", mat.GetColor());
    }
    
    private void OnEnable()
    {
        EventManager.OnHotspotSelect += OnHotspotSelect;
        EventManager.OnHotspotDeselect += OnHotspotDeselect;
    }
    
    private void OnDisable()
    {
        EventManager.OnHotspotSelect -= OnHotspotSelect;
        EventManager.OnHotspotDeselect -= OnHotspotDeselect;
    }
    
    
    private void OnHotspotSelect(Hotspot hotspot)
    {
        if (this.hotspot == hotspot)
        {
            //YOUR MATERIAL CODE HERE. For example: material.SetColor("_Color", Color.red);
            mat.SetColor("_Color", tempColor);
            mat.EnableKeyword("OUTBASE_ON");
        }
    }
    
    private void OnHotspotDeselect(Hotspot hotspot)
    {
        if (this.hotspot == hotspot)
        {
            //YOUR MATERIAL CODE HERE. For example: material.SetColor("_Color", Color.green);
            mat.SetColor("_Color", transparentColor);
            mat.DisableKeyword("OUTBASE_ON");
    
        }
    }
    

    }
    `

  • It might be that FlashHotspots is being detected - but the Highlight components aren't affecting the material correctly.

    To help debug, you can separately enable Hotspot icons in the "Hotspot" section of the Settings Manager. These will show when a Highlight component kicks in, but without the need for specific materials - check that the icons show both when hovering over Hotspots, and when the input is pressed.

    Regarding the script: you're hooking into the OnHotspotSelect / Deselect events, which'll kick in when you hover over Hotspots with the mouse. If you want to react to the "FlashHotspots" input, you'll instead need to hook into the OnHotspotsFlash event.

    As this is just a single event, though, you'll need e.g. a coroutine to turn the effect off afterwards. Something like this should do it:

    using System.Collections;
    using UnityEngine;
    using AC;
    
    public class HotspotHighlight : MonoBehaviour
    {
        public Hotspot hotspot;
        private Material mat;
        private Color tempColor = new Color (1f, 1f, 1f, 1f);
        private Color transparentColor = new Color (0f, 0f, 0f, 0f);
    
        private const float waitTime = 2f;
    
        private void Awake()
        { 
            mat = GetComponent<Renderer>().material;
            mat.SetColor ("_Color", transparentColor);
        }
    
        private void OnEnable () { EventManager.OnHotspotsFlash += OnHotspotsFlash; }
        private void OnDisable () { EventManager.OnHotspotsFlash -= OnHotspotsFlash; }
    
        private void OnHotspotsFlash ()
        {
            StopAllCoroutines ();
            StartCoroutine (FlashCo ());
        }
    
        private IEnumerator FlashCo ()
        {
            mat.SetColor("_Color", tempColor);
            mat.EnableKeyword("OUTBASE_ON");
    
            yield return new WaitForSeconds (waitTime);
    
            mat.SetColor("_Color", transparentColor);
            mat.DisableKeyword("OUTBASE_ON");
        }
    
    }
    
  • Thank you so much! This worked perfectly! :)

    Also just another minor thing -- is there a way I could show the names of all the hotspots above them when they are flashing?

    I tried looking in the manual, but I'm guessing this may require some custom scripting?

  • Yes, you'll need to have a regular Hotspot menu that then gets duplicated through script to show for all Hotspots at once.

    A script along these lines can be found on the AC wiki - it might just need a bit of tweaking:
    https://adventure-creator.fandom.com/wiki/Simultaneous_Hotspot_labels

  • Thank you so much! :)

    In case it helps anyone else, I went ahead and modified the script that @ChrisIceBox wrote out earlier to accommodate this change:

    `using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using AC;
    using TMPro;
    using UnityEngine.TextCore.Text;

    public class HotspotHighlight : MonoBehaviour
    {
    public Hotspot hotspot;
    private Material mat;
    private Color tempColor = new Color(1f, 1f, 1f, 1f);
    private Color transparentColor = new Color(0f, 0f, 0f, 0f);
    public TextMeshProUGUI textObj;

    // texture properties to make sure outline
    // amount looks consistent for hotspots
    public float outlineWidth = 0.024f;
    public float distortAmount = 0.3f;
    
    private const float waitTime = 2f;
    
    // action lists controlling
    // the disappearing and appearing of player when hotspots flash
    ActionList playerHide;
    ActionList playerShow;
    
    private GameObject playerToHide;
    
    
    private void Awake()
    {
        mat = GetComponent<Renderer>().material;
        mat.SetColor("_Color", transparentColor);
        mat.SetFloat("_OutlineWidth", outlineWidth);
        mat.SetFloat("_OutlineDistortAmount", distortAmount);
    
        playerToHide = GameObject.Find("Everlyn");
        //instantiate action lists controlling player visibility
        playerHide = gameObject.AddComponent<ActionList>();
        playerHide.actions = new List<Action> {
        ActionVisible.CreateNew(playerToHide, VisState.Invisible, true)
        };
    
    
        playerShow = gameObject.AddComponent<ActionList>();
        playerShow.actions = new List<Action> {
        ActionVisible.CreateNew(playerToHide, VisState.Visible, true)
        };
    
    }
    
    private void OnEnable() { EventManager.OnHotspotsFlash += OnHotspotsFlash; }
    private void OnDisable() { EventManager.OnHotspotsFlash -= OnHotspotsFlash; }
    
    private void OnHotspotsFlash()
    {
        playerToHide = GameObject.Find("Everlyn");
    
        playerHide.actions = new List<Action> {
        ActionVisible.CreateNew(playerToHide, VisState.Invisible, true)
        };
    
        playerShow.actions = new List<Action> {
        ActionVisible.CreateNew(playerToHide, VisState.Visible, true)
        };
    
        StopAllCoroutines();
        StartCoroutine(FlashCo());
    }
    
    private IEnumerator FlashCo()
    {
        if (hotspot.IsOn())
        {
            playerHide.Interact();
            KickStarter.stateHandler.SetMovementSystem(false);
            KickStarter.stateHandler.SetInputSystem(false);
            mat.SetColor("_Color", tempColor);
            mat.EnableKeyword("OUTBASE_ON");
            textObj.text = hotspot.GetName(0);
    
            yield return new WaitForSeconds(waitTime);
    
            mat.SetColor("_Color", transparentColor);
            mat.DisableKeyword("OUTBASE_ON");
            textObj.text = "";
            KickStarter.stateHandler.SetInputSystem(true);
            KickStarter.stateHandler.SetMovementSystem(true);
            playerShow.Interact();
        }
    }
    

    }`

    One thing to note is that I created a UI (in worldspace) for each hotspot.

    This is the final result when I press "H": https://drive.google.com/file/d/1lc3cOIqhdQ69Afmcg7tYyzvQLdEfns2g/view?usp=sharing

  • Looks great, thanks for sharing!

  • My pleasure! :)

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.