Forum rules - please read before posting.

Animate cursor on click

edited October 2018 in Technical Q&A
I'd like to shortly animate my cursor whenever I click. Such that it plays maybe 1-3 frames and then goes back to the default non-animated sprite of the current cursor.

My interface is set to 'Choose hotspot then interaction'. I will mostly be working with 'Single 'use' interaction' hotspots, but my hotspots will be set to different cursors (i.e. I will for example have a 'use' cursor, a 'pick up' cursor, a 'talk to' cursor, etc.).

I'd like to animate my cursor on click both for my 'walk' cursor (i.e. when not clicking on hotspots) and for my other cursors (i.e. when clicking on hotspots).

I guess I will have to write a custom script for this, but perhaps someone could give me some clues about how I should approach it?
«1

Comments

  • @salex thank you for your reply!

    I did read that thread, however it looks to me like it's something slightly else, as it seems like it wouldn't be possible to have several different cursors with that script.
  • The AC cursor gets reset upon clicking (and possibly hidden depending on other options if a Cutscene then occurs), so you'd have to take the same approach as the other thread - i.e. playing an animation through Unity UI at the same mouse position.

    Try this:

    I've adapted it to respond to mouse clicks (as opposed to taps), and will now also set an Animator's integer parameter to the cursor ID when clicking a single-use Hotspot, or -1 when not clicking a Hotspot.

    You'll therefore have to wire up an Animator that takes both an integer and trigger parameter and uses them to play animations, but first just make sure the Console spits out the correct messages.
  • Thank you @ChrisIceBox !

    I have now created a UI canvas in my scene with a UI Image 'CursorImage' in it. I've attached an Animator to CursorImage, and created a couple of animations for it, as well as attached the script to CursorImage and assigned the CursorImage Animator as the Animator of the script. In my Animator I have specified the IconID and ClickEffect parameters.

    I have put an animation 'CursorAnim0' with no keyframes as my default entry transition, and then I have put an animation 'CursorAnim-1' to transition from CursorAnim0 if IconID == -1, and an animation 'CursorAnim7' to transition from CursorAnim0 if IconID == 7.

    It's working fine - CursorAnim-1 plays when I click on nothing during gameplay, and CursorAnim7 plays when I click on objects using icon number 7.

    However, I have at least three questions:

    1. My main cursor is now always accompanied by CursorImage, even when it's not playing animations. I thought I could remedy this by giving CursorAnim0 no keyframes, but that doesn't work. How would I render CursorImage invisible whenever it's not animating?

    2. The animations keep running until I click on something else. I.e. when I click on nothing, it plays CursorAnim-1, and that animation keeps playing until I click on an object using icon number 7, and vice versa. I tried putting transitions with exit times from CursorAnim-1 and CursorAnim7 back to CursorAnim0, but it keeps transitioning back to CursorAnim-1 and CursorAnim7. I'm probably doing something wrong. Right now I fail to see the purpose of the "_animator.SetTrigger (clickEffectTrigger);" line, so perhaps that as something to do with - maybe I wired up something in a wrong way? What I need is for it to play through the animation once, and then transition back (effectively rendering CursorImage invisible again).

    3. At the moment CursorImage renders at the default size of the sprites used. Can I make it automatically the size of my cursor icons as specified under 'Cursor' in the AC Game Editor?

    4. Right now the UI canvas with CursorImage is in my scene. Will I have to manually put it in every scene from now on, or is there some way to automatically call it from scenes, like it's doing with the menus?
  • 1. You'd create a separate "invisible" animation (i.e. assigning an invisible/empty texture in the Image's texture field) that plays by default.

    2. The clickEffectTrigger should only trigger when you click the cursor, which you can use to prevent the animations from running at any time.  Make sure that you incorporate that parameter into your animation transitions.

    3. No - the two systems are completely separate.  You'll have to manipulate the Canvas / UI components to determine how large the animations appear.

    4. You could conceivably create a new Unity UI Menu in the Menu Manager that links up to your Canvas prefab to have it spawn automatically.  Make sure it's set to always display (Appear type: Manual, Enabled on start? checked) and that it has no transition effect or linked elements.
  • edited October 2018
    Thank you @ChrisIceBox !

    Okay, I think I got it pretty much working now, except for three things:

    1. The AC cursor is not rendered invisible while CursorImage is animating, so the CursorImage animation plays on top of the AC cursor. I tried solving this by including a coroutine that sets the cursor icon to null, waits for a fixed time (which would then have to be adjusted to fit the exact time of the CursorImage animation), and then sets the icon texture back to normal. It is working, however it produces a lot of "null texture passed" messages in the log (if I'm hovering over a hotspot while the coroutine is running), and it seems like a bad solution, and possibly one that could cause some problems I'm not aware of at the moment (EDIT: I just realized that if I click somewhere else or end the game while the coroutine is still running, the texture remains null, which of course makes this solution useless). Is there there instead a way to temporarily make the cursor (regardless of which icon is currently showing) invisible?

    2. I have a UI canvas with an InventoryBox that displays always during gameplay. Right now CursorImage also animates when I click on that UI canvas. How can I make it so that CursorImage doesn't animate when clicking on UI elements?

    3. If for example I want my CursorImage animation to simply be the cursor briefly changing colour, I would have make sure that the sprites of the AC cursor and the sprites of my CursorImage animation are rendered at exactly the same size. How would I do that?
  • edited October 2018
    1. While an invisible texture would prevent null errors, you can also disable the cursor completely via the Display cursor field in the Cursor Manager, which can be manipulated at runtime by right-clicking its label to access the API:

    AC.KickStarter.cursorManager.cursorDisplay

    2. You can read the state of the IsMouseOverMenu method:

    AC.KickStarter.playerMenus.IsMouseOverMenu ()

    3. Make sure you're relying on Hardware cursor rendering - that way, it'll be of a constant size, and you can set up your UI canvas to match.  Alternatively, it might be easier to just rely on the UI canvas the whole time - and hide the AC cursor completely.
  • @ChrisIceBox thank you, I'll try out those things!
  • edited October 2018
    I've been trying some different solutions to get it exactly as I want (and on the way trying to figure out exactly how I want it), and I keep running into one problem, I have yet to solve:

    As long as I don't click on a hotspot (active hotspot == null) it's working fine, and if I click on a hotspot that is set to make the player walk to some point before initiating its actionlist it's also working - BUT if I click on a hotspot that initiates its actionlist right away the animation doesn't run.

    There really seems to be two distinct problems here:

    1. If the actionlist starts right away, the mode shifts to cutscene/not in gameplay the moment the click is done, and therefore the animator never receives its trigger. I could then remove the condition IsInGameplay, but that would obviously be a problem in other regards. I think I need to somehow trigger the animation before AC goes into cutscene mode, but how would I do that?

    2. When I click on a hotspot, that hotspot seems to be temporarily deactivated (a part of the logical structure of AC I presume), so even if the animator receives the trigger, it wouldn't know to play the correct animation, since when the hotspot is deactivated, the cursor ID shifts to -1. Is there perhaps some way I can get the hotspot cursor ID before the hotspot gets deactivated?

    Do you have an idea for how to solve these problems, @ChrisIceBox ?
  • For the specific case of clicking on Hotspots, it's probably better to rely on the OnHotspotInteract custom event, which you can hook into to run code whenever the player initiates a Hotspot interaction:

    http://pasteall.org/1321291/csharp

    However, I still think relying on an entirely UnityUI-based cursor may be the answer.  You can use events similarly to tweak things if necessary, but here's a sample script to demonstrate:

    http://pasteall.org/1321292/csharp

  • Thank you @ChrisIceBox !

    I'm not a seasoned scripter, so I don't fully understand that second script, but I'll keep trying to grasp it.

    Right now I'm looking into relying entirely on a UnityUI-based cursor, and I'm wondering if AC has a method that allows me to get the sprite of the currently selected inv item, such that I can set the source image of my UnityUI Image as that sprite while the inv item is selected?
  • The second script I just posted should do that automatically, since it takes the texture passed to the OnSetHardwareCursor custom event.

    However, the currently-selected item's texture can also be read with:

  • Great, thank you!
  • MY GOD such a simple thing need all this to make it work? Who would have thought. I really have to study this to make something so simple :(

  • @Antonis: A script for a Unity UI-based cursor has since been posted on the wiki. It can be adapted further to suit your own needs, but allows for animation control through the use of Animator parameters.

  • @ChrisIceBox yeah but it doesn't really explain anything. It is given with the minimum info

  • edited July 2019

    The issue is complicated because the way you might want the cursor to behave can be so varied. The script offers full animation control over the cursor, but the cursor itself is very complex - with different states, icons, and inventory items.

    The wiki page does assume prior knowledge of Unity UI / Animation workflows, and how the script is used is down to you, as each user's needs will be different. Please state exactly what behaviour you're looking to achieve - how, and when, you want the cursor to be animated.

    To use the script for just animating the cursor when clicking:

    1. Attach a RawImage as a child object to a new UI Canvas.
    2. Set the RawImage's texture to the texture of your cursor's "regular" graphic.
    3. Attach an Animator and Animator Controller, and add an animation (using Unity's Animation workflow) that animates the RawImage in the way you intend when clicking.
    4. Also add another animation that acts as the default by just adding a single frame of animation that sets the RawImage's texture to the default cursor graphic. Right-click in the Animator to make it the default (yellow).
    5. Create a new Trigger parameter in the Animator named "Click", and use it to transition from the default animation to the click animation. Make sure that "Has Exit Time" is unchecked.
    6. Create another transition when the click animation ends, back to the default animation.
    7. Attach the script to the Canvas and assign the Animator to the Animator field.
    8. Assign an empty Cursor texture to the Empty Texture field.
    9. Clear the first three parameter fields.

    Further tweaks to the script can be made if necessary, but that should get you a simple cursor click animation. Try following these steps, and if you get stuck please share as much detail and screenshots as you can so that further help can be given.

  • edited July 2019

    I m trying to re create what you said here.

    One point to ask is, do I set the Click trigger also when there is a transition from the moving animation of the cursor to the other animation that has only one frame?

    In AC do I remove the cursor icon that is there (not animating) in Main cursor settings ?

    When you say empty cursor texture to the empty texture field you mean a completely blank transparent texture ?

    Up to the moment I have a cursor in the middle of the screen that animates when i click but there is another cursor ( i suspect taken from the main cursor settings) that is static that is it is not animating but follows the mouse movement.

    PS: thank you for all the help. I would never have thought it would be so complex to just have an animated cursor upon click.

  • It is strange. This is what I am getting. https://www.dropbox.com/s/w42kly9metejf1w/error1.jpg?dl=0

    One cursor within the red frame which animates upon clicking but does not move. And another cursor which is now shown in print screen that is bigger and is not animating but can move around.

  • edited July 2019

    do I set the Click trigger also when there is a transition from the moving animation of the cursor to the other animation that has only one frame?

    No - only from the single-frame to the click animation. The click animation should revert back to the single-frame once it has come to its natural end.

    In AC do I remove the cursor icon that is there (not animating) in Main cursor settings ?

    So long as you supply the "Empty Texture" field, that should override the main cursor.

    When you say empty cursor texture to the empty texture field you mean a completely blank transparent texture ?

    A blank transparent texture.

    I would never have thought it would be so complex to just have an animated cursor upon click.

    It is a complex thing to do in Unity, but again - if you can share exactly what you want, I may be able to offer a more simple solution. By this I mean that I need to know precisely how you want your cursor to behave at all times, i.e. do you want it to change when hovering over a Hotspot, or when an item is selected - and is it animated then as well? All these details contribute to the complexity, which is why there is no "one size fits all" approach.

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.