I created this button prefab that is using the built-in Unity Button component, an image component with Raycast Target, and an Animator component that is playing a scaling animation when pressing the button. The problem is occurring when clicking on the edge of the button graphic and holding the mouse button down.
As the animation is scaling down the button size (as well as the image component with the Raycast Target) the mouse cursor is at some point no longer hovering over the button and the animation state is going back to normal. As the button scales back to normal size automatically (and while still holding the mouse button pressed) the button is getting pressed again - getting stuck in a loop.
How can I prevent that from happening? Do I need to modify the order of my components or maybe change something in the Animator?
To sum up what was said in the comments: you want the raycast target to stay the same size while animation plays. That's why you should probably split your Popup Button into two GameObjects: one will be the actual Button (that stays the same size) and the other will be animated, and then the question is mostly "how do I change another object's animation from button click".
To do that, you should have the Button component on the actual button, Animator component on the animated object, and in the Button's onClick list you should have the call to the animated objects' Animator Component -> SetTrigger with the name of the trigger you want as an argument. Also note that the animated object shouldn't be the raycast target, but the actual button should.
You can pick what happens when animation is triggerred again before it finishes (for example when button is clicked multiple times) by setting transition parameters in the animation controller. But in this case just separating the button from the animated image should do what you want, because the raycast target will now stay the same size and the animation won't get triggered multiple times anymore.
You can add timer for check animation is running.
example :
//your animation duration here:
private float animationduration = 0f;
bool isClickable = true;
//set your timer with default 0
private float timer = 0f;
private void Update()
{
timer += Time.deltaTime;
if (timer > animationduration)
{
isClickable = true;
}
else
{
isClickable = false;
}
if (isClickable && Input.GetMouseButtonDown(0))
{
clickFunction();
timer = 0f;
}
}
void clickFunction()
{
//ur function in here
}
then click function can't use before the animation end.
Related
I am trying to make a character play a specific animation when pressing the R button. I would like him to play the whole animation and then stop once it has run a cycle.
The issue now is that when I press "R" the animation only plays for a frame and no animation plays at all.
I started with this statement below.
void Update ()
{
if (Input.GetKeyDown(KeyCode.R))
{
anim.Play("Ready");
}
}
I then read that it might be better to create a bool instead, if the bool is true -> play Animation.
public bool ready;
void Update ()
{
if (Input.GetKeyDown(KeyCode.R))
{
ready = !ready;
}
if (ready == true)
{
anim.Play("Ready");
}
}
When bool ready is true, the animation plays one frame and then the character becomes static. If the bool the gets false again, the character returns to his idle animation.
My latest attempt to making this work is by structuring the code like this:
if (Input.GetKeyDown(KeyCode.R))
{
ready = !ready;
if(ready == true)
{
anim.Play("Ready");
}
}
However this only causes the animation to play a very small amount of frames until going back to the idle animation. Even though ready stays true.
I am not using the "Animator component" but rather the "Animation component" instead. This are the settings of it: Animation Component
Could it be the void Update() causing the issue?
Also, is there a way to make sure the animation only plays for one cycle and then stops?
Your method looks valid. Are there chances that your imported animation isn't?
You should use the Animator as suggested:
drop your clips in the Animator window,
right click on the default state > "make transition", release on the next clip,
create a parameter of type bool named "ready",
assign this parameter in the transition from idle to the next state (select the arrow and click the "+" button at the bottom of the component in the Inspector window, select your parameter),
in your script, you just have to call:
myAnimator.SetBool("ready", true);
There are a lot of benefits of using the Animator :
handle many animation clips, automatic transitions, preview, and more features with "humanoid" rigs (in the model import settings)...
I have a single canvas in my unity project which holds 2 main gameObjects which are the Main UI and Pause UI. To make Pause Ui load I set time.deltatime to 0.
pauseMenuUI.SetActive(true);
Time.timeScale = 0f;
When I try and click my button on pauseUI it won't click or even show that it is being hovered over. ANy ideas as to what is going on?
When I am in the pause state I can still interact by clicking the main screen and the players gun will fire if there is ammo available so I know the game isn't broken. I think it might have something to do with Z index but not sure.
Pictures for use.
add EvrentSystem in the Hierarchy by doing tight click in the hierarchy Than search for EventSystem, plus be sure that the buttons properties in the inspector are set to intractable
I have a problem cancelling pan feature of my app when a button in HUD is pressed.
We're using canvas for displaying UIs, so I can't use the RayCast to detect if a touch hit a button or not since the button is not directly in the world where the map to be panned located.
I already added collider to the buttons and tried printing the name of objects hitted by raycast but it just passes through the buttons like they are not there.
How am I suppose to detect if a button in canvas is touched so I can cancel executing pan feature?
Check EventSystem's IsPointerOverGameObject method. You can use it like this:
public bool IsPointerOverUI
{
get{
return EventSystem.current.IsPointerOverGameObject();
}
}
Don't forget to import UnityEngine.EventSystems
I'm working on a Windows app using XNA.
Actually I succeed moving my sprite, but I want to add a different action when the user touch the sprite but don't move it. I know TouchlocationState Enum exist but I don't understand the difference between Moved and Pressed.
For now I use Released and that's enough, I update the sprite position while it's not released and then I check collision.
So how can I add only one touch method when it's clicked? I mean when the user tap the sprite but don't move it.
Some code:
TouchPanelCapabilities touchCap = TouchPanel.GetCapabilities();
if (touchCap.IsConnected)
{
TouchCollection touches = TouchPanel.GetState();
if (touches.Count >= 1)
{
Vector2 PositionTouch = touches[0].Position;
if (touches[0].State == TouchLocationState.Released)
{
// Pause button click and others buttons
Mouseclik((int)PositionTouch.X, (int)PositionTouch.Y);
}
if (!PausePopUp)
{
CheckMoove(PositionTouch);
if (touches[touches.Count - 1].State == TouchLocationState.Released)
{
// this is where i try to add/check if its only "click" on my sprite
if (touches[0].Position == touches[touches.Count - 1].Postion)
{
TempoRectangle = ListSprite[save].ShapeViser;
isclicked = true;
}
My goal is to add a picturebox above the sprite to display information then if an other sprite is touched while the picturebox is diplayed, I want to draw a line between these 2 sprites.
The difference is simple:
TouchLocationState.Pressed means that a new location is detected.
TouchLocationState.Moved means that the location position was updated or pressed at the same position
This means that you will get only a Pressed state for each touch action, a sequence of Moved every cycle while the touch is pressed, and when you release it you'll get a Released.
This is explained in the link you provided, too.
I have a 2D game in which I use only the mouse as input.
How can I make it so that my when the mouse hovers over a Texture2D object, the Texture2D and the mouse cursor change, and when the texture is clicked it moves to another place.
Simply put, I want to know how to do something when I hover over or click on a Texture2D.
In XNA you can use the Mouse class to query user input.
The easiest way of doing it is to check the mouse state for each frame and react accordingly. Is the mouse position inside a certain area? Display a different cursor. Is the right button pressed during this frame? Show a menu. etc.
var mouseState = Mouse.GetState();
Get the mouse position in screen coordinates (relative to the top left corner):
var mousePosition = new Point(mouseState.X, mouseState.Y);
Change a texture when the mouse is inside a certain area:
Rectangle area = someRectangle;
// Check if the mouse position is inside the rectangle
if (area.Contains(mousePosition))
{
backgroundTexture = hoverTexture;
}
else
{
backgroundTexture = defaultTexture;
}
Do something while the left mouse button is clicked:
if (mouseState.LeftButton == ButtonState.Pressed)
{
// Do cool stuff here
}
Remember though that you will always have information of the current frame. So while something cool may happen during the time the button is clicked, it will stop as soon as released.
To check for a single click you would have to store the mouse state of the last frame and compare what has changed:
// The active state from the last frame is now old
lastMouseState = currentMouseState;
// Get the mouse state relevant for this frame
currentMouseState = Mouse.GetState();
// Recognize a single click of the left mouse button
if (lastMouseState.LeftButton == ButtonState.Released && currentMouseState.LeftButton == ButtonState.Pressed)
{
// React to the click
// ...
clickOccurred = true;
}
You could make it even more advanced and work with events. So you would still use the snippets from above, but instead of directly including the code for the action you would fire events: MouseIn, MouseOver, MouseOut. ButtonPush, ButtonPressed, ButtonRelease, etc.
I would just like to add that the Mouse Click code could be simplified so that you don't have to make a variable for it:
if (Mouse.GetState().LeftButton == ButtonState.Pressed)
{
//Write code here
}