How to write "When current animation finished"? - c#

I have a model with animation controller. I set the states and parameters for transitions between them. Now I need to make the model play its animations in order I want.
I can use:
GetComponent.<Animator>().SetBool("someparameter",true);
to uncheck currently checked parameter and check another parameter after current animation finished.
How can I make a condition for when the current animation finished?
Examples I'm finding are related to animation component (not animator), or they are too complicated for me, while I need a simple way I can understand and use quickly.

unity3d supports the events and triggers within the macanim, have a look the links below
https://docs.unity3d.com/Manual/animeditor-AnimationEvents.html
http://answers.unity3d.com/questions/750785/mecanim-trigger-event-at-end-of-animation-state.html

Try this
if(this.animator.GetCurrentAnimatorStateInfo(0).IsName("YourAnimationName"))
{
// Avoid any reload.
}

Related

Control on Page Navigations in Xamarin C#

I have a value on screen1 which keeps on incrementing from 0 and when I navigate to screen2 it has to stop. When I navigate back it has to start incrementing from the stopped value.
How do I catch the current page change in Xamarin C# like wise OnAppearing and OnDisappearing for the app
Thanks!
Do you use NavigationPage?
If yes, you can use its Pushed and Popped events.
If no, please describe how exactly you implement your navigation.

Nesting anonymous delegates in C# - how to make code maintainable and readable?

I'm making a game, and it may have modal UI windows, like popover windows.
I encapsulated all the fiddling into my class and I just call one method to show such window on screen, for example a method to show a list of characters:
ShowCharactersTable(List<Character>list,
Action<Character>didSelectCharacter, Action<bool>didCancel)
Example in use:
ShowCharactersTable(someList, delegate(Character selectedCharacter) {
// code that runs after you picked a character
, delegate(bool didCancel){
// code that runs after you cancelled selection
});
This is fine. Everything is transparent and easy to use. But I get into trouble as soon as I need to nest this. For example, on character list I have few buttons on each character cell, so I need to provide delegates for that. This gets complicated. I also might need to show another modal window on top of that, with a call like this:
ShowActivitySelector(List<Activity>activitiesToShow,
Action<Activity>didSelectActivity,
Action<bool>didCancelPickingActivity);
And when I select activity I might need to show Alert if something goes wrong, like here:
ShowAlert(string alertText, Activity<bool>didAccept,
Activity<bool>didCancel);
So now, to call a simple table of characters I need to write a 3 page long method with nested delegates. Does not sound like fun. How can I modularize this and make easier/more maintainable?
I don't want to couple my interface to my model, as I will need to show those lists, selectors and alerts from many different parts of my game with different parameters.
How can this be fixed and what do I do about this?

Which architecture for Unity4.6 UI implementation

I'm working on a Unity project. It's a visualisation software, so most of the game mechanics are based on buttons, sliders, color-picker updating my GamesObjects.
I can't figure out how to organise my UI implementation.
Is it a good idea to apply some kind of MVC pattern to unity, any idea how to do it (I found some article about that but they weren't clear to me) ?
Currently I'm adding UI elements in the scene. An empty game objets called UIManager is holding scripts concerning the UI. Those scripts hold references to UI elements, add a listener to them and contain methods called by the event.
My approach is correct? How to improve it?
My UI Manager contain scripts like this one :
public class someMenuGUI : MonoBehaviour {
public Button enable;
public void Start()
{
enable.onClick.AddListener(Enable);
}
public voidEnable()
{
GameObject[] Objs = Object.FindObjectsOfType (typeof(GameObject)) as GameObject[];
// then do something on them
};
That's a very good question without an answer that can be considered to be universally true. However, I would like to share my approach to this.
When I write Unity code, I have two categories of users in mind: players and designers. Essentially, since almost all Unity code is contained in MonoBehaviours, and MonoBehaviours are used in the editor, you're constantly writing a tool for designers that they use to actually create a game.
Even if you don't have a designer and work alone, it's useful to think about code in this terms. This way, you have a clear separation between code space and editor space: code doesn't have to make any assumptions about what happens in the editor; instead, designer has to be able to use your components to build what they want.
So, where do you draw the line? I think that if you're going to use the MVC pattern, the separation is quite clear: the controller logic should be contained in code, but the wiring up of the actual UI elements should be in the hands of the designer. Which, finally, brings us to the code.
A great way to implement the MVC pattern is to use events instead of solid references: this way the controller and the view don't have to know each other's types, they only have to know the model. But since you want the designer to hook events up in the editor, you can't use C# delegate events. Thankfully, there's a new feature of Unity's UI system just for that: UnityEvent.
So, let's say that your script, which plays the role of the controller, has to have two-way communication with the view: from controller to the view to update the information, and from view to controller to run the user's action. Turns out, it's very simple to set up. Create a public UnityEvent (with a correct generic argument) for update of the data, public method for user action, and you're done with the code! All that designer will have to do is to set the Unity event on your script to update the UI, and to set up Unity event of UI element to call your controller's method.

Debug Event being "used" in Unity 3D

I'm having an issue with the user interface on project I'm working on. It involves "nodes" and connecting them together. I have the connecting of two nodes together tied to pressing a button on an initial node and then clicking the other node to connect to it. The latter half is implemented by checking for when Event.current.type == EventType.MouseDown then joining the initial node with the node you last hovered over.
This works fine most of the time however I noticed that sometimes when you clicked on another node it would not join them together instantaneously, but until you click off of the node. After doing Debug.Log(Event.current.type) it showed that sometimes the event was coming up as "used" when I clicked, instead of "mouseDown" and as such would not perform the join code until I clicked somewhere else. It seems to only happen for some nodes.
Here are two gifs of the behaviour with the console output:
Problem code:
private bool detectEscape()
{
Debug.Log(Event.current.type);
return (Event.current.type == EventType.MouseDown);
}
This function is returning False sometimes on mouse clicks due to the event being "used" sometimes. It is called in the GUI.
Know of any reason what causes the current event to be used? I do comparisons like above in a number of places in my code. Could that be what is causing the current event to be used? How do I avoid it?
Am I using the Event system correctly?
Know of a better way to capture mouse clicks? Using Input.GetMouseButtonDown(0) unfortunately isn't an option as it only works when the game is running and this program is meant to be an extension to the editor.
Otherwise, know of a way to put a break point in Unity 3D's source code so that I can put one in the the function Event.Use() and determine what is consuming the mouse event?
Presumably you are calling detectEscape from OnGUI somewhere, right? The current event is only valid during OnGUI. Additionally, OnGUI can be called multiple times per frame, with different current events. Sometimes the event type might be Repaint, sometimes it might be MouseDown, sometimes it might be something else. So if the event type is not MouseDown, you don't want to assume that the mouse is not down; the mouse might still be down but a different event might be occurring.

C# How To: Trying to call button twice in same class?

Did some searches here & on the 'net and haven't found a good answer yet. What I'm trying to do is call a button twice within the same class in C#.
Here's my scenario -
I have a form with a button that says "Go". When I click it the 1st time, it runs through some 'for' loops (non-stop) to display a color range. At the same time I set the button1.Text properties to "Stop". I would like to be able to click the button a 2nd time and when that happens I would like the program to stop. Basically a stop-and-go button. I know how to do it with 2 button events, but would like to utilize 1 button.
Right now the only way to end the program is the X button on the form.
I've tried different things and haven't had much luck so far so wanted to ask the gurus here how to do it.
BTW, this is a modification of a Head First Labs C# book exercise.
Thanks!
~Allen
You would need to use Multithreading (launch the process intensive code asynchronously in a separate thread), for instance, using the BackgroundWorker object in .NET 2+. This would be necessary because your UI will not respond to the user's click until the loop running in the Start method is completed. It is quite irrelevant if you use the same button or another one to toggle the process, because the processor is busy processing the loop.
The BackgroundWorker has a property called WorkerSupportsCancellation which needs to be true in this scenario. When the user clicks Stop you would invoke the CancelAsync method of the BackgroundWorker.
See MSDN for a good example. Also DreamInCode has a good tutorial which seems quite similar to your requirement.
Why not create two buttons, hide one when the other is visible? That should be a lot of easier to handle.
Or you can add a bool field to indicate which operation branch to execute.
One simple solution would be to add a boolean member to your form that is, e.g., true when the button says "Go" and false when the button says "Stop".
Then, in your button's event handler, check that boolean value. If the value is true, then start your operation and set the value to false when you change the button's text to say "stop". Vice-versa for the other case. :)
There are other techniques that I might prefer if this were production code, perhaps including considering the design of the form more carefully, but as this is clearly a learning exercise I believe that a simple boolean flag indicating the current state of the form is just what you're looking for.
Note that I would strongly discourage you from checking the value of the button text to determine what state the object is in. Whenever possible, as a general rule of good design, you want your visual state to be "decoupled" from your underlying object's state. That is to say, your visual widgets can depend on your underlying objects, but your underlying objects should not depend on your visual widgets. If you tested the text of the button, your underlying logic would depend on your visual state and that would violate this general rule.
If your problem is related to the fact that you can't cancel the operation while it's being performed, you'll want to look into using a BackgroundWorker to perform your long-running activity.
Another option would be to check the current text on your button to determine what to do:
void btnStartStop_Click(Object sender, EventArgs e)
{
if (btnStartStop.Text == "Go")
{
btnStartStop.Text = "Stop";
// Go code here
}
else
{
btnStartStop.Text = "Go";
// Stop code here
}
}
Are you getting your second button click event? Put a breakpoint in your click handler and run your code. When you click the second time, do you ever hit your breakpoint?
If your loop is running continuously, and it is in your button click handler, then your loop is running in the UI thread. You probably don't get to "see" the second button click until after the loop is completed. In addition to the branch code that you see above, try either inserting a DoEvents in your loop processing (this is a place where your loop will temporarly give up control so that messages can be processed). Or, (better) have a look at the backgroundworker class -- do most of your processing in a different thread, so that you UI can remain responsive to button clicks.
Cerebrus is right about using the Background Worker thread. However if you are doing a WPF app then it won't be able to update the UI directly. To get around this you can call Dispatcher.BeginInvoke on the main control/window.
Given code like:
Private Delegate Sub UpdateUIDelegate(<arguments>)
Private Sub CallUpdateUI(<arguments>)
control.Dispatcher.BeginInvoke(Windows.Threading.DispatcherPriority.Background, New UpdateUIDelegate(AddressOf UpdateUI), <arguments>)
End Sub
Private Sub UpdateUI(<arguments>)
'update the UI
End Sub
You can call CallUpdateUI from the Background Worker thread and it will get the main thread to perform UpdateUI.
You could set the Tag property on the button to a boolean indicating whether the next action should be "Stop" or "Go", and reset it each time you click the button. It's an Object property, though, so you'll have to cast it to bool when you read it.

Categories

Resources