Forum rules - please read before posting.

Sentence build ignore certain hotspots?

edited January 2019 in Technical Q&A

This may require scripting, but is it possible to have the sentence ignore certain types of objects? I imagine this would be accomplished using tags or checking if the object is an NPC, but I'm not quite sure if it's possible out-of-the-box or not. Here's an example: https://gfycat.com/SphericalUnhappyBullfrog - you can attempt to look at and pick up every hotspot, but are only able to attempt to talk-to the salesman or the clown.

This could be taken further for other uses, of course, but for my needs I'd like to keep the Talk To cursor from changing the sentence when hovering over non-NPC or tagged with a specific tag hotspots. Would this require hooking into the sentence building event?

PS: this is also used for the Give cursor: https://gfycat.com/DarlingComplexJunebug
This is interesting as Give-to is only permitted to the salesman, and not the clown. This would imply a need to check for either a pair of tags or specify the object in seperate ways (if the object can be talked to but not given to; good for joke talk-to objects you can like Chuck the Plant or Dead Cousin Ted or even Thimbleweed Park's water fountain, but not allowing Give-to as it would never be necessary to give a non-human object an item).

Comments

  • It would require scripting - essentially you'd have to disable a given Hotspot when an icon that it doesn't make use of is selected.

    This can be done with the OnChangeCursorMode event, attached to a Hotspot, i.e.:

    void OnChangeCursorMode (int selectedCursor)
    {
        Hotspot hotspot = GetComponent <Hotspot>();
        if (selectedCursor < 0 || (hotspot.GetUseButton (selectedCursor)))
        {
            // Enable it
            hotspot.TurnOff ();
        }
        else
        {
            hotspot.TurnOn ();
        }
    }
    
  • I do apologize, I'm getting an error:

    http://pasteall.org/1460320

  • Ah, I didn't post the error: https://i.imgur.com/85WtvvC.png
    and without the first part: https://imgur.com/JCJe2Ui.png

    I don't think it's possible, but can this script go on a scene object, or does it definitely need to go on each hotspot?
  • Try this:

    void OnChangeCursorMode (int selectedCursor)
    {
        Hotspot hotspot = GetComponent <Hotspot>();
        if (selectedCursor < 0 || hotspot.GetUseButton (selectedCursor) != null)
        {
            // Enable it
            hotspot.TurnOff ();
        }
        else
        {
            hotspot.TurnOn ();
        }
    }
    

    I don't think it's possible, but can this script go on a scene object, or does it definitely need to go on each hotspot?

    As in, a single-scene Hotspot? You could adapt it for such, but unless you want it to work for all Hotspots (no need to check for a particular one), you'd have to define a List of Hotspots to check from. The above is just an example on one way to approach it.

  • Sorry, I meant can it go on a scene prefab rather than having to be fitted to every hotspot? There would always be a lot of hotspots that would have to be turned off, unless this script is actually working inverse to what I'm imagining it does, and it's actually turning off all the (human) hotspots except for the ones that should be shown when talk-to or give is selected?

  • void OnChangeCursorMode (int selectedCursor)
    {
        Hotspot hotspot = GetComponent <Hotspot>();
        if (selectedCursor < 0 || hotspot.GetUseButton (selectedCursor) != null)
        {
            // Enable it
            hotspot.TurnOn ();
        }
        else
        {
            hotspot.TurnOff ();
        }
    }
    
  • Do I need to modify this to only ignore the hotspots when I have Give or Talk cursors specifically chosen? i've put this exact script on a hotspot and it's still showing a give sentence when I hover with a item selected.

    And this definately needs to go on every hotspot that I want to ignore sentence building for? I'm not sure if you said it could just go once on single a scene object and I could ignore the hotspot if it had a talk-to interaction defined or a tag or some such?

  • edited January 2019

    Do I need to modify this to only ignore the hotspots when I have Give or Talk cursors specifically chosen?

    This script only disables the Hotspot if the cursor is set to a mode that the Hotspot doesn't have a Use interaction for. To have it ignore inventory items as well, you'd want something like this:

    void OnChangeCursorMode (int selectedCursor)
    {
        Hotspot hotspot = GetComponent <Hotspot>();
    
        if (KickStarter.runtimeInventory.SelectedItem != null && hotspot.GetInvButton (KickStarter.runtimeInventory.SelectedItem.id) == null)
        {
            hotspot.TurnOff ();
        }
        else if (selectedCursor >= 0 && hotspot.GetUseButton (selectedCursor) == null)
        {
            hotspot.TurnOff ();
        }
        else
        {
            hotspot.TurnOn ();
        }
    }
    

    And this definately needs to go on every hotspot that I want to ignore sentence building for?

    See the third line - it gets the Hotspot component its attached to, so this script needs to go on the Hotspot itself.

    You can, of course, adapt it to go on a single GameObject - this is just an example. Get it working for one first, though.

  • Okay, I understand now; I don't mind keeping the hotspot always on except if

    • Talk-to a hotspot that doesn't have a talk-to interaction defined
    • Give an inventory item to a hotspot that doesn't have a talk-to interaction defined

    So here's what I have so far:
    `void OnChangeCursorMode(int selectedCursor)
    {
    Hotspot hotspot = GetComponent();

        if (KickStarter.runtimeInventory.SelectedItem != null
            && hotspot.GetInvButton(KickStarter.runtimeInventory.SelectedItem.id) == null
            && selectedCursor == 4
            )
        {
            hotspot.TurnOff();
        }
        else if (selectedCursor == 1 )
        {
            hotspot.TurnOff();
        }
        else
        {
            hotspot.TurnOn();
        }
    }`
    

    selectedCursor == 1 is Talk-to cursor, selectedCursor == 4 is Give-to. So, I need to add into the first if statement a check if the hotspot has a talk-to interaction defined (or a person tag, but since I only have one tag per hotspot, it might be more efficient to just check if the hotspot has a talk-to interaction defined) but I couldn't find a way to reference if a specific interaction is defined or not.

    Then for the second if statement, I just need to add the same check if there's a talk-to interaction defined or not.

    Finally, do all the of scene hotspots need parsing into a list or some such in order for this to go on a single gameobject rather than being added to each hotspot manually? I'm not sure entirely how to do this, unfortunately.

  • I couldn't find a way to reference if a specific interaction is defined or not.

    I already provided you with this - GetUseButton.

    I'm not sure entirely how to do this, unfortunately.

    This is a general Unity scripting question. Start here.

  • I already provided you with this - GetUseButton.

    Sorry, I didn't realise you could define a specific interaction to check, GetUseButton's descriptive implied it checked the first set interaction. Using selectedcursor would be the apropriate way to check that just Talk-To was defined or not?

    This is a general Unity scripting question. Start here.

    Oh, I see, I was assuming it could be done in the similar way other AC-interacting scripts could be places on a single scene object, but I think the one's I've used so far didn't interact with multiple items in the scene, but rather inventory items and such. I'll have to ask on the discord for help with this I believe, but it would go in the hook rather than update, couldn't it (for performance reasons)?

  • GetUseButton's descriptive implied it checked the first set interaction.

    First available interaction for a given cursor ID - see the scripting guide's entry.

    If you pass the selectedCursor variable (which if zero or greater will be the current cursor ID), and it returns null, then the Hotspot has no interaction for that cursor.

    If you want to check specifically for Talk-to, ignore selectedCursor and just send the ID for Talk-to as set in your Cursor Manager.

    I'll have to ask on the discord for help with this I believe, but it would go in the hook rather than update, couldn't it (for performance reasons)?

    In Start:

    Hotspot[] allMyHotspots;
    
    void Start ()
    {
        allMyHotspots = FindObjectsOfType (typeof (Hotspot)) as Hotspot[];
    }
    
  • edited February 2019

    I'm not sure, all of the scripts I've tried so far gives me

    NullReferenceException: Object reference not set to an instance of an object
    HideGiveTalk.OnChangeCursorMode (Int32 selectedCursor) (at Assets/HideGiveTalk.cs:21)
    AC.EventManager.Call_OnChangeCursorMode (Int32 cursorID) (at Assets/AdventureCreator/Scripts/Managers/EventManager.cs:590)
    AC.PlayerCursor.set_SelectedCursor (Int32 value) (at Assets/AdventureCreator/Scripts/Controls/PlayerCursor.cs:1080)
    AC.PlayerCursor.SetCursor (AC.CursorIcon _icon) (at Assets/AdventureCreator/Scripts/Controls/PlayerCursor.cs:1020)
    AC.PlayerCursor.SetCursorFromID (Int32 ID) (at Assets/AdventureCreator/Scripts/Controls/PlayerCursor.cs:1006)
    AC.PlayerInteraction.ClickInteractionIcon (AC.Menu _menu, Int32 iconID) (at Assets/AdventureCreator/Scripts/Controls/PlayerInteraction.cs:2195)
    AC.MenuInteraction.ProcessClick (AC.Menu _menu, Int32 _slot, MouseState _mouseState) (at Assets/AdventureCreator/Scripts/Menu/Menu classes/MenuInteraction.cs:502)
    AC.MenuElement.ProcessClickUI (AC.Menu _menu, Int32 _slot, MouseState _mouseState) (at Assets/AdventureCreator/Scripts/Menu/Menu classes/MenuElement.cs:250)
    AC.MenuElement+c__AnonStorey0.<>m__0 () (at Assets/AdventureCreator/Scripts/Menu/Menu classes/MenuElement.cs:209)
    UnityEngine.Events.InvokableCall.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:166)
    UnityEngine.Events.UnityEvent.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:58)
    UnityEngine.UI.Button.Press () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:66)
    UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:108)
    UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:50)
    UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:261)
    UnityEngine.EventSystems.StandaloneInputModule:ProcessMouseEvent()
    AC.OptionalMouseInputModule:Process() (at Assets/AdventureCreator/Scripts/Menu/OptionalMouseInputModule.cs:80)
    UnityEngine.EventSystems.EventSystem:Update()

    or

    NullReferenceException: Object reference not set to an instance of an object
    HideGiveTalk.OnChangeCursorMode (Int32 selectedCursor) (at Assets/HideGiveTalk.cs:24)
    AC.EventManager.Call_OnChangeCursorMode (Int32 cursorID) (at Assets/AdventureCreator/Scripts/Managers/EventManager.cs:590)
    AC.PlayerCursor.set_SelectedCursor (Int32 value) (at Assets/AdventureCreator/Scripts/Controls/PlayerCursor.cs:1080)
    AC.PlayerCursor.DrawCursor () (at Assets/AdventureCreator/Scripts/Controls/PlayerCursor.cs:265)
    AC.StateHandler._OnGUI () (at Assets/AdventureCreator/Scripts/Game engine/StateHandler.cs:585)
    AC.StateHandler.OnGUI () (at Assets/AdventureCreator/Scripts/Game engine/StateHandler.cs:505)

  • edited February 2019

    Sorry, my fault! Here's the final working version! I tried to get the script working as a scene script, but I couldn't get Hotspot[] allMyHotspots; in the right place?

    ` void OnChangeCursorMode(int selectedCursor)
    {
    Hotspot hotspot = GetComponent();

        if (KickStarter.runtimeInventory.SelectedItem != null
            && hotspot.GetUseButton(1) == null
            && KickStarter.runtimeInventory.IsGivingItem()
            )
        {
            hotspot.TurnOff();
        }
        else if (selectedCursor == 1 && hotspot.GetUseButton(1) == null)
        {
            hotspot.TurnOff();
        }
        else
        {
            hotspot.TurnOn();
        }
    }`
    
  • I tried to get the script working as a scene script, but I couldn't get Hotspot[] allMyHotspots; in the correct place?
  • edited February 2019

    As I showed in the sample code, you keep it out of your functions. I can't give any more advice without seeing what you actually wrote.

  • Okay, here's the version that works on each hotspot: http://pasteall.org/1478179
    I know I needvoid Start () { allMyHotspots = FindObjectsOfType (typeof (Hotspot)) as Hotspot[]; }
    and Hotspot[] allMyHotspots; goes outside of the OnChangeCursorMode hook I think in public class HideGiveTalk : MonoBehaviour) but I' not sure how to get all of the hotspot references to work with this, or how to change Hotspot hotspot = GetComponent<Hotspot>(); so it works for all components in the scene.

  • Please use Markdown when posting code - separate code from prose with a line, and give all code a tabbed indent.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using AC;
    
    public class HideGiveTalk : MonoBehaviour
    {
    
        private Hotspot[] allMyHotspots;
    
    
        private void OnEnable ()
        {
            allMyHotspots = FindObjectsOfType (typeof (Hotspot)) as Hotspot[];
            EventManager.OnChangeCursorMode += OnChangeCursorMode;
        }
    
    
        private void OnDisable ()
        {
            EventManager.OnChangeCursorMode -= OnChangeCursorMode;
        }
    
    
        private void OnChangeCursorMode (int selectedCursor)
        {
            foreach (Hotspot hotspot in allMyHotspots)
            {
                UpdateHotspot (hotspot, selectedCursor);
            }
        }
    
    
        private void UpdateHotspot (Hotspot hotspot, int selectedCursor)
        {
            if (KickStarter.runtimeInventory.SelectedItem != null &&
                hotspot.GetUseButton(1) == null &&
                KickStarter.runtimeInventory.IsGivingItem ())
            {
                hotspot.TurnOff ();
            }
            else if (selectedCursor == 1 && hotspot.GetUseButton (1) == null)
            {
                hotspot.TurnOff ();
            }
            else
            {
                hotspot.TurnOn ();
            }
        }
    
    }
    
  • Thank you, this is PERFECT!

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.