I am creating a menu for my turn-based battle. And the animations(buttons move across the screen using bools as a condition to move) were breaking when I spam pressed the keys, so I added this delay. It is pretty good for a start but now when I spam press the keys the animation transition is noticeably slow and awkward looking. If I were to slowly push the key down and back up at a moderate pace the animation transition through the menu is about 1.5-twice as fast. Any ideas for a fix?
Thanks for the input :), but this doesnât fix/help my problem at all. Formatting is not an issue.
To reiterate, Iâm trying to get it so that if I either spam press the key or press the key normally the menu will move at the same pace. Perhaps I need to take a different approach overall?
My code works just fine.
I tried tinkering with my inDelay but 0.2f is the lowest I can get it without the animations breaking again due to the bools in my animator toggling on/off too fast for the animations itself to keep up.
Thereâs nothing in this code where youâre affecting any animations at all, so how could this code contain the issue youâve described?
Also, typically in the case of an animation not looking right, itâs 100x easier to get a handle on the problem if you can post a screen recording of it looking right vs. what youâre actually seeing. I have no idea what ânoticeably slow and awkward lookingâ actually means.
1: Just showing the code so you can see the logic behind the button input which triggers each animation and its delay. It is not my whole document. If you read my whole post you would see I mentioned that I am controlling the transitions of animations with bool triggers, I am not directly calling each animation through code.
If you must know I am using a coroutine for a âcurrent button selectedâ state machine(contains all the bool triggers) and an enum so I can cycle through the menu with my input.
I was asking if there was a way to optimize it and make the animation transition nicer on a spam press. (see #3). I would assume that this snippet of code contains the issue as the speed of my input seems to create different outcomes.
2: I have no means of screen recording.
3: I will explain the issue again but this time I will break it up for ya more conciselyâŚ
When I press the W/S key slowly/moderately the animation goes through the menu at itâs intended pace.
When I press the W/S key in a spamming fashion the animation goes slightly slower through the whole menu.
By taking another look at it, I can tell you that when I scroll by spam pressing the buttons stops in its end position for a few frames before moving on to the next. Again, pressing at a slower pace makes it look as intended.
Also, Has Exit Time is disabled in every transition.
Iâm not sure I understand the logic nor the relevance to your issue: what is curButton for [assumption: itâs an index to the currently selected button]?
But letâs assume the logic is working (except for the tiny undefined state where on passing through Reset inDelay is exactly 0) - you donât show how you set and/or trigger the animations. If you get too fast, will you have multiple animations for multiple Buttons run at the same time?
Here is my whole document since it seems to be problematic for yall, so sorry about that. I was explaining how everything was workingâŚbut take a look lol
No thatâs not it. Iâve got everything all working itâs only this small issue. No multiple animations playing. The issue is that if I spam the button the animation will play fully and wait in its end position for a few frames (lasts about 1/2 a second) before playing the next animation. As compared to when I press the button only moderately fast the animations will play fluidly between eachother.
My OCD is driving me crazy every time I see it hahaha.
Yes. As I said before itâs working. My issue is the input. I had to add a very small delay to the input in order to allow the aminations to transition in sync with my variable switch.(see line 126) I want the animation to move smoothly down/up the list no matter how fast I press it.
The fact that you have so many SetBool functions being redundantly called every frame is a big red flag. You are probably not using the animator in a great way. My guess is that since the animator takes a frame to process your inputs, when you spam SetBool changes, youâre delaying that transition process.
Could you show a screenshot of your animator graph, how are you setting up your states and transitions? Is everything connected to the AnyState node for these bools to transition correctly?
The ideal setup here would be to create one button with an animator as a prefab and reuse the button, each one animates independently when itâs told it is selected or not. That would allow you to zip thru all the buttons and have them all select/deselect at any rate you want, even at the same time potentially. You definitely donât need one animator controlling the entire menu worth of button states and animations. Think more modularly.
If thatâs too big of a change, or you donât fully understand how that would all work, I think you can probably get away one of these approaches instead:
Have a single integer parameter, and pass in curButtononly when it changes, and have your transitions act based on that value.
Keep all your bool parameters, but use a single SetTrigger call only when curButton changes, setting the one relevant boolean true, which will automatically become false once it is used in a transition.
Add a function to wait until the animator changes states before allowing a new input ( not as easy as it sounds to get runtime animator state info, but it is possible)
Hereâs a quick example of a possible structure for an index-based menu:
Example
public class Button : MonoBehaviour
{
public Animator animator;
public void Selected()
{
// animate in
animator.SetBool("Selected", true);
}
public void Deselected()
{
// animate out
animator.SetBool("Selected", false);
}
}
public class Menu : MonoBehaviour
{
public Button[] buttons;
private int currentButtonIndex;
private void Start()
{
SelectButton(currentButtonIndex);
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.W))
{
SelectButton(currentButtonIndex + 1);
}
if (Input.GetKeyDown(KeyCode.S))
{
SelectButton(currentButtonIndex - 1);
}
}
private void SelectButton(int newIndex)
{
if (buttons.Length > 0 && newIndex != currentButtonIndex)
{
// deselect old button
buttons[currentButtonIndex].Deselected();
// keep index looping between 0 and # of buttons
currentButtonIndex = (int) Mathf.Repeat(newIndex, buttons.Length-1);
// select new button
buttons[currentButtonIndex].Selected();
}
}
}
Alternatively to all of this, you can leverage the Unity UI functionality in the inspector. You can setup navigation buttons right in the inspector, give them an animation to play in the inspector, set their OnClick callback in the inspector, and have stuff working more or less out of the box.
Thank you. This was very resourceful. I will be looking into all this for the next week probably to see what can work out
Now that you point it out, it does make sense that I shouldnât be structuring my animator in the way I did. I have exactly what you inferred. A ton of animations that indicate moving up or down the list of buttons. 2 animations per button.
I didnât connect them to my AnyState though. It comes in from entry and goes to an Idle animation and connects into the huge web of animations that indicates where you are on the list.
I deleted this animator and all its animations. Figured I needed to go from scratch again.
This menu is a bit tricky because I want 4 buttons to be visible at a time and have the buttons move offscreen to the left or downward as I scroll through. Also, itâs important to know that the neutral position button is the 3rd button from the bottom and the 2nd visible button from the bottom. The button sitting in the neutral position slot should be the one that is selected.
So I would just need to use 1 button? and then just set up animations for that and dupe it? and make the animator as a prefab, or are you talking about the button?
There are some built-in options for button state animations, but nothing built-in for a scrolling list animation. So you can use a scrollrect, and use an animator, but it is a rigid animation that has to be manually edited if you add/remove buttons, and isnât very reusable for other button lists.
If you have a set number of buttons that most likely wont change, this could be a viable option.
----
You can code it yourself (i prefer to avoid the animator & animation state logic).
Personally I think a strong way to set something like this up is with a ScrollRect component, and using code to tell the scrollrect what position to be in, and tell the buttons to be selected or not, based on the current index. Then youâre not tied to an animator/animation, it becomes a procedural animation that is flexible and reusable.
Then you can have as many buttons as you want and not have to worry about editing the animation and adding a new state to the animator and new variables in the script etc, just drag in another button prefab, hook up the OnClick callback in the inspector or in code.
You can use âScrollRect.verticalNormalizedPositionâ or âScrollRect.horizontalNormalizedPositionâ to pass a value from 0 to 1 for where the scrollrect should scrolled to. If you have 5 buttons, and youâve selected the 3rd button, then you could scroll to (3f / 5f) for instance.
This function can make a scrollrect snap to a RectTransform (easier to get centered positioning, or if all your elements arent the same size) https://stackoverflow.com/a/30769550
That function, or the normalized position setting can be coded to interpolate smoothly over-time with a coroutine or tween.
----
Lastly instead of coding it yourself, are efforts out there for scroll-snap components that do all the work for you: https://discussions.unity.com/t/693194
I know thatâs a lot of info, but thereâs a thousand ways to make anything in Unity so you kind of just have to try stuff and see what works best for you. Iâd suggest googling anything you donât understand to find examples or tutorials, but Iâm happy to answer questions about anything Iâve said.
I think of all the options I would like to code it myself. Being able to tweak and reproduce assets like that seems useful in the long run. Iâve got many many tabs open, and Iâm reading over everythingâŚa bit of a headache lol. A little hard to understand. I keep making no progress after reading for hours in the day and then turning in for the night.
I think I can figure out the movement/scrolling of the list, maybe, since I guess I just need to set up everything with things that fall under ScrollRect and RectTransform. Please correct me if Iâm wrong.
But I could use a little help laying down the groundwork. Getting the index menu running. Iâm a bit frustrated at the moment.
1: I canât even attach my button prefabs to my button array. It shows the + sign when I drag and hover my button prefab over the array slot in the inspector, so I know itâs trying to accept it. Iâll drop it in there and it will still say Element 0 â [None(Button)]. Iâll check the list of things I could add to the element by clicking that Lil âoâ and the list is completely empty. This is throwing me for a loop because I had no problem putting my buttons in an array days ago when I was working with the animator, never thought I would need it at the time.
2: I know you probably didnât give me all the pieces in the example you gave me of the index menu. I am trying my best to make it work. My best guess is that the button array needs to be set up first and that I need to look into other logic since I no longer wish to work with the animator.
I appreciate the words man.
I gotta say googling and looking on YouTube sometimes comes up with little information if what I want is too specific. I often find things that have little context to what is being discussed or I find things that are so elementary that it is super not helpful.
Maybe I just need to keep rephrasing my search terms lol.
1 - Thatâs weird. If you named your script Button, it will conflict with Unityâs Button class, maybe thatâs messing you up. If so, my bad for naming my example âButtonâ.
2 - Itâs pretty much all there, but I wrote it quickly without testing so I didnât do a lot of cleanup or bug prevention
Googling is a skill like anything else, you have to practice it and you get really good at it. When you google and search and canât find anything, thatâs when you should post on the forums.
Since youâre clearly putting in some effort to learn, Iâm just going to post a working example because I think youâll learn faster by looking at something functional than reading my explanations.
Itâs a very bare bones example, and I tried to code it in a short and concise way to hopefully make it easier to read.