Forum rules - please read before posting.

Additional interaction cursor

Hi,

I have a first person, context sensitive, touchscreen based game, where I would like to have an additional cursur shown when hovering an inventory item over a hotspot.

Currently, the inventory item's main graphic is shown as a cursor when dragging the item from the inventory over the screen and disappears when let go.

The intended flow is:

  • When hovering the item over a hotspot that has this item as an "Inventory interaction", animated cursor A should show behind the inventory main graphic.
  • When hovering the item over a hotspot that does not have this item as an "Inventory interaction", animated cursor B should show behind the inventory main graphic.

Here is my cursor inspector. (I know the Use, No use naming is not correct, but don't know what to name them and how to use them). The graphics have texture type : cursor.
https://imgur.com/a/3EDIV4K

// Magnus

Comments

  • Sounds like a case for the use of Unity UI cursor rendering.

    With this mode, you can use Animation to control the appearance of the cursor.

    This relies on parameters and transitions, as with regular animation.

    For example, when Inventory item ID = 2 is over a Hotspot, the InventoryID Int parameter will be 2, and the IsOverHotspot bool parameter will be True.

    You can use custom scripting to inject additional parameters if necessary - for example, if the currently-selected Hotspot has an Interaction for the selected Inventory item:

    void Update ()
    {
        GetComponent<Animator>.SetBool ("HasInvInteraction", HasValidInventoryInteraction ());
    }
    
    bool HasValidInventoryInteraction ()
    {
        var hotspot = AC.KickStarter.playerInteraction.GetActiveHotspot ();
        var item = AC.KickStarter.runtimeInventory.SelectedItem;
    
        if (hotspot == null || item == null) return false;
        return hotspot.HasValidInventoryInteraction (item);
    }
    

    Switching your Cursor rendering to Unity UI should give you access the default prefab, UnityUICursor, already assigned. If not, you can grab/duplicate it from the default UI folder in /Assets/AdventureCreator.

  • edited April 14

    Ok, thanks!
    I thought I was close, but I cannot get the Unity UI cursor to move.
    I've made a Cursor prefab (CursorHotspot) with 3animated circles and 1 inventory item image.
    Cursor Setings, Cursor Prefab Inspector :
    https://imgur.com/a/Gfp39sl

    Is it correct that I also need to add an image for the selected InvItem texture to this prefab since the InvItem graphics stopped showing when changing to UnityUI Cursor? The "Change cursor" setting under "Inventory Cursor" doesn't seem to be affected when rendering is set to Unity UI.

    I added this to the Cursor prefab root :

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    using AC;
    
    public class CursorHotspot : MonoBehaviour
    {
    
    
        private Animator anim;
        public Image img1;
        public Image img2;
        public Image img3;
    
        void Start()
        {
                anim = GetComponent<Animator>();
        }
    
        void Update()
        {
            anim.SetBool("HasInvInteraction", HasValidInventoryInteraction());
            transform.position = Input.mousePosition;
        }
    
        bool HasValidInventoryInteraction()
        {
            var hotspot = AC.KickStarter.playerInteraction.GetActiveHotspot();
            var item = AC.KickStarter.runtimeInventory.SelectedItem;
    
            if (hotspot == null || item == null)
            {
                img1.enabled = false;
                img2.enabled = false;
                img3.enabled = false;
                return false;
            }
            else
            {
                img1.enabled = true;
                img2.enabled = true;
                img3.enabled = true;
            }
            return hotspot.HasInventoryInteraction(item);
        }
    }
    

    and this to the Inventory image child object:

    using UnityEngine;
    using UnityEngine.UI;
    using AC;
    
    public class CursorInventoryDisplay : MonoBehaviour
    {
        public RawImage inventoryIconImage;
    
        void Update()
        {
            if (KickStarter.runtimeInventory.SelectedItem != null)
            {
                inventoryIconImage.enabled = true;
                inventoryIconImage.texture = KickStarter.runtimeInventory.SelectedItem.tex;
            }
            else
            {
                inventoryIconImage.enabled = false;
            }
        }
    }
    

    The inventory image shows when dragging an inventory item and the circles-animation plays when it should, but they are both stuck in the middle of the screen and won't move with the mouse/touchdrag. What am I missing?

    // Magnus

  • You need to assign the Unity UI Cursor component's RectTransform to position field as a child of the Canvas root - it can't control the Canvas itself.

    When set, it'll reposition this object where the cursor should be - so all other objects should be a child of that as well.

    This avoids the need for your own script to set the position in Update.

    Also, this component can be doing more of the work that your scripts are doing. If you have a separate RawImage child object reserved for the Inventory image, you can assign it in the Inventory RawImage field and it will be updated automatically.

  • Yep!! Works fine. I made a panel object between the Prefab root and the raw image/images and set this panel as the "Rect Transform to Position". I also added a blank Raw Image to the panel and set this as the "Cursor Raw Image" in the "Unity UI Cursor" components and all works fine!!

  • ok, one last thing, with the risk of this being a Unity question and not "UI cursor component" question. All of the above works, but the Circle animation is rendered on top of the inventory item graphic. How do I get the circle animation below the inventory graphic?
    I have tried changing child hierarchy in the UI object, set Sibling order through script, put an empty parent to the animation object, changing z-values, adding canvas with higher sorting order to the Inventory RawImage, but no luck so far.

  • This'll be a Unity issue - AC won't be controlling the sorting order.

    You should only need 1 canvas - on the root.

    What components are you using to render the circle animation?

  • Sorry about the Unity issue...
    I'm triggering the animation (increasing scale of rawImage circles) through an anim bool variable that changes based on the CursorHotspot script below, attached to the "Canim" object. Red circles if the inventory item does not have an interaction and green circles if it has an interaction.
    https://imgur.com/a/4BrHQ6H

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    using AC;
    
    public class CursorHotspot : MonoBehaviour
    {
    
    
        private Animator anim;
        public RawImage img1;
        public RawImage img2;
        public RawImage img3;
    
        void Start()
        {
                anim = GetComponent<Animator>();
        }
    
        void Update()
        {
            anim.SetBool("HasInvInteraction", HasValidInventoryInteraction());
        }
    
        bool HasValidInventoryInteraction()
        {
            var hotspot = AC.KickStarter.playerInteraction.GetActiveHotspot();
            var item = AC.KickStarter.runtimeInventory.SelectedItem;
            bool isOverHS = AC.KickStarter.playerInteraction.IsMouseOverHotspot();
    
            if (isOverHS == false || item == null)
            {
                return false;
            }
            if (hotspot != null && hotspot.HasInventoryInteraction(item))
                {
                    img1.color = Color.green;
                    img2.color = Color.green;
                    img3.color = Color.green;
                    return true;
                }
            if (isOverHS && item != null)
               {
                    img1.color = Color.red;
                    img2.color = Color.red;
                    img3.color = Color.red;
                    return true;
               }
            return false;
        }
    }
    
  • If you're just dealing with RawImage components, then I'd expect their relative Z positions should be enough to control their order.

  • Unfortunately that doesn't help, anyway, thanks for checking!

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.