Create and coding animator script with Unity - animation

i have a three animation state and two bool parameters.
I want to circle of that.
The entry state "BeklemeAtakYap" there is in nothing animation.
Firstly, i set bool "Bekle" true, "Saldir" false.
The animation starting "Bekleme" state.
I am setting on the script "Bekle" false and "Saldir" true.
Animation contiunning "Saldir" state.
And i make a translation "Saldir" and "BeklemeAtakYap".
When the "Saldir" state end and the "BeklemeAtakYap" starting, i want the bool parameters "Bekle" true "Saldir" false how can do that?

You can add an AnimationEvent at the end of Saldir state.
just right click on the top of the timeline just below times and select add AnimationEvent.
Then write a function in a script which is attached to the AnimationController and assign it to the AnimationEvent. In that function you can manually set animation parameters.
GetComponent<Animator>().SetBool("Saldir", false);
By the way please use English words in your question for better readability.

I click "BeklemeAtakYap" state and click the Add Behavior-> Add Script.
Open the script and write;
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
animator.SetBool ("Saldir", false);
animator.SetBool ("Bekle", true);
}
That's work.

Related

Validation in a Datagridview

I have an application with a datagrid view
This datagrid is filled by code, not binded to a datasource.
All cells are editable
when a user edits a value in a cell, then i need to perform an action
Private Sub dgView_CellValidated(sender As Object, e As DataGridViewCellEventArgs)
Handles dgView.CellValidated
Dim nColumnIndex As Integer
DIm nRowIndex as Integer
If sender.iscurrentRowDirty Then
nRowIndex = e.RowIndex
nColumnIndex = e.ColumnIndex
Call UpdateRowData(nRowIndex, nColumnIndex)
End If
End Sub
The Function UpdateRowData is called when user edits en then leave the cell, but if he goes to a cell in the same row. Then this routine will be called again when the user again goes to another cell without any editing
I want this function only called once
How are you going to know if the cell’s value had “actually” changed from its original value? And what is this “action” that is taken if the cell “was” changed? Is what I am getting at… is that it is unclear “what” this “action” is doing? If it is an extensive process that may take some time and you want to avoid this “action” if the cells value doesn’t “actually” change. Then you will need to know if a cells value actually DID change. And this will require a different event and some additional code implementation on your part.
On the other hand, if the “action” is simply to update something with the new value, then it may take MORE execution steps to actually “check” if the value has changed as opposed to simply overwriting the same values. So, if the “action” is trivial, I wouldn’t bother “checking” if the values have changed.
However, if you DID need to make sure that the user “actually” did change the cells value… Then below is a crude, yet simple, solution for this.
One possible issue is if the user clicked into a cell and edited it by “actually” typing some characters, but, after the user finishes typing characters they had ended up simply re-typing what the original value was… then “technically” from the grids perspective… THAT cells value DID change. In other words, We will need to somehow get the original value of the cell “BEFORE” the user starts to edit the cell. Then we could “compare” the new value with the original value when the user tries to leave the cell.
Fortunately, there is a grid event that should make this fairly trivial to implement. The event I suggest using is the grids CurrentCellDirtyStateChanged event. This event will actually fire TWICE. The event will fire once when the cell goes into “edit” mode. And it will fire again when the user ends the same cells edit mode.
Therefore, we can take advantage of this, however, we will need to know that WHEN the event fires… is it fired when the user “enters” the cells edit mode… OR … is the event fired because the user is “ending” the cells edit mode. I do not think the event keeps track of this internally so we need to create our own “mechanism” to be able to distinguish when the event is fired on the “begin” edit and the “end” edit.
One possible solution to make this work is to create two global variables… one a bool variable called FirstIn and a string variable called OriginalValue… When the event fires the first time to “begin” the cells edit mode, we can check the FirstIn variable. If it is true then we know the cell is “beginning” the edit of the cell… this is where we would capture the cells current value and set the OrignalValue string variable so we can “check” it against the final cells value when the user ends the cells edit mode.
Capturing the current cells value and setting FirstIn to false is all we need to do. We now wait until the user ends the cells edit mode and the event fires for the second time. When it fires the second time… again we check the FirstIn variable and in this case it is false which means the cells is ending its edit mode. Here we could check the OriginalValue with the cells current value and do your “action” if they are different. And finally setting FirstIn to true to start the whole process over.
Below is an example of what is described above.
bool FirstIn = true;
string OriginalValue;
private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e) {
if (FirstIn) {
FirstIn = false;
OriginalValue = dataGridView1.CurrentCell.Value.ToString();
}
else {
string NewValue = dataGridView1.CurrentCell.Value.ToString();
FirstIn = true;
if (OriginalValue.Equals(NewValue)) {
MessageBox.Show("NO changes were made in the cell edit");
}
else {
MessageBox.Show("YES changes were made in the cell edit");
}
}
}
Sorry but I wrote this in C#, below is a VB version.
Dim FirstIn As Boolean = True
Dim OriginalValue As String
Private Sub DataGridView1_CurrentCellDirtyStateChanged(sender As Object, e As EventArgs) Handles DataGridView1.CurrentCellDirtyStateChanged
If (FirstIn) Then
FirstIn = False
OriginalValue = DataGridView1.CurrentCell.Value.ToString()
Else
Dim NewValue As String = DataGridView1.CurrentCell.Value.ToString()
FirstIn = True
If (OriginalValue.Equals(NewValue)) Then
MessageBox.Show("NO changes were made in the cell edit")
Else
MessageBox.Show("YES changes were made in the cell edit")
End If
End If
End Sub

Controlling animations in an animator via parameters, in sequences

So I am animating an avatar, and this avatar has its own animator with states and such.
When interacting with props, the props itself has an animator with states in it. In both case, I transition to some animations through parameters in the animator (bool type).
For example, for a door, the character will have "isOpeningDoor", while the door will have "isOpen".
Now the question: when I change the value on an animator on GO1, and then change the bool on GO2; do the first animation finish and then the second start? Because in my case, it does not happen; they start almost at the same time.
void OnTriggerEnter (collider door)
{
if (door.gameObject.tag=="door")
{
GOAnimator1.SetBool("isOpeningDoor", true);
GOAnimator2.SetBool("isOpen", true);
}
}
I believe that I am doing it wrong, since I change the parameter on the animator, but I do not check for the animation to end; is this even possible or am I doing something not kosher?
I really think it might be doable!
As you have it in your code now, the animations on GO1 and GO2 start at almost the same time because that's how it's written. The OnTriggerEnter() function will complete the execution in the frame it is called, and return the control to Unity.
What I think that might help you are coroutines and sendMessage between gameobjects:
http://docs.unity3d.com/Manual/Coroutines.html
http://docs.unity3d.com/ScriptReference/GameObject.SendMessage.html
The idea is to:
Create a coroutine in GO2 that waits an amount of time until it sets the GOAnimator2 variable to activate the door animation.
Create a function in GO2 that calls the aforementioned coroutine
From the OnTriggerEnter() send a message to GO2 to execute the newly created function
It reads complicated, but it's fairly simple. The execution would be like this:
1.Code for the coroutine:
function GO2coroutine(){
float timeToWait = 0.5f; //Tweak this
for ( float t = 0f; t < timeToWait; t+=time.deltaTime)
yield;
GetComponent<Animator>().SetBool("isOpen",true);
}
Code for the function calling it:
function callCoroutine() {
StartCoroutine("Fade");
}
And the code modification for your OnTriggerEnter():
void OnTriggerEnter (collider door)
{
if (door.gameObject.tag=="door")
{
GOAnimator1.SetBool("isOpeningDoor", true);
GO2.SendMessage("callCoroutine");
}
}
I didn't have a chance to test the code, so please don't copy paste it, there might be slight changes to do.
There is another way, but I don't like it much. That is making the animation longer with an idle status to wait for the first game object animation to end... but it will be a hassle in case you shorten the animation because you have to, or have any other models or events.
Anyway, I think the way to go is with the coroutine! Good Luck!

Unity2d game shooting and animation sync issue

I'm a new in Unity and making my first 2D game. I seen several topics on this forum in this issue, but I didn't found the solution.
So I have a lovely shooting animation and the bullet generation. My problem, I have to generate the bullet somewhere at the middle of the animation, but the character shoots the bullet and the animation at the same time, which killing the UX :)
I attached an image, about the issue, this is the moment, when the bullet should be initialized, but as you can see it's already on it's way.
Please find my code:
The GameManager update method calls the attackEnemy function:
public void Awake(){
animator = GetComponent ();
animator.SetTrigger ("enemyIdle");
}
//if the enemy pass this point, they stop shooting, and just go off the scren
private float shootingStopLimit = -6f;
public override void attackPlayer(){
//animator.SetTrigger ("enemyIdle");
if (!isAttacking && gameObject.transform.position.y > shootingStopLimit) {
isAttacking = true;
animator.SetTrigger("enemyShoot");
StartCoroutine(doWait());
gameObject.GetComponentInChildren ().fireBullet ();
StartCoroutine (Reload ());
}
}
private IEnumerator doWait(){
yield return new WaitForSeconds(5);
}
private IEnumerator Reload(){
animator.SetTrigger ("enemyIdle");
int reloadTime = Random.Range (4,7);
yield return new WaitForSeconds(reloadTime);
isAttacking = false;
}......
My questions:
- How can I sync the animation and the bullet generation ?
Why not the doWait() works ? :)
Is it okay to call the attackPlayer method from the GameManager update ?
The enemies are flynig from the right side of the screen to the left, when they reach the most right side of the screen, they became visible to the user. I don't know why, but they to a shooting animation (no bullet generation happen )first, only after it they do the idle. Any idea why ?
Thanks,
K
I would suggest checking out animation events. Using animation events, you can call a method to instantiate your bullet.
To use Mecanim Animation Events you need to write the name of the function you want to call at the selected frame in the "Function" area of the "Edit Animation Event" window.
The other boxes are for any variables that you want to pass to that function to trigger whatever you have in mind.
Triggering/blending between different animations can be done in many different ways. The event area is more for other things that you want to trigger that are not related to animation (e.g. audio, particle fx, etc).

XEvent Handling in animation

I'm having some understanding problem of event-handling with Xlib functions.
My question would be - how do i press a key during an animation, without disturbing the animation.
My setup so far, is that i have some animation in a while loop and want to achieve a KeyPress event which modifies a parameter.
It looks something like this
while(1){
XNextEvent(dis, &report);
switch (report.type) {
case KeyPress:
if (XLookupKeysym(&report.xkey, 0) == XK_space){
//...modify parameter a..//}}
//...Some animation where parameter a is used to modify animation...//}
Now, the problem is that i have to press the key consistently to get the animation on my screen, otherwise nothing appears. I've tried some multiple code-modifications, with KeyRelease etc. but i don't have clou, really.
Trivially said - i need to hook a key during animation without the XNextEvent process, waiting for any event. But without the XNextEvent statement in my code, conditional statements for KeyPress event checking aren't working.
I guess formally this would mean:
while(1){
if(report.type==KeyPress) {
if (XLookupKeysym(&report.xkey, 0) == XK_space){
//...modify parameter a..//}}
//...Some animation where parameter a is used to modify animation...//}
Use XPending() to check for XEvents before getting them with XNextEvent().
XPending() returns then number of events in the event queue so modify your loop:
while(1){
if (XPending(dis) > 0) {
XNextEvent(dis, &report);
switch (report.type) {
case KeyPress:
if (XLookupKeysym(&report.xkey, 0) == XK_space){
//...modify parameter a..//
}
}
}
//...Some animation where parameter a is used to modify animation...//
}

Edit Control not updating with Spin Control MFC

I am trying to use an edit control along with a spin control using MFC visual studio .net 2003. I have carried out the basic settings for the spin control like setting the "AutoBuddy" property and "SetBuddyInteger" property to True so that the Spin control works in coordination with the edit control next to it. In my Spin control's event handler, I am facing a problem when I am trying to call my Invalidate() function. The float value in my edit control does not update and stays zero. If I remove the Invalidate(), then the value increments but my paint function is not updated obviously. A code of the following is given below:
void CMyDlg::OnSpinA(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
// TODO: Add your control notification handler code here
UpdateData();
m_A = m_ASpinCtrl.GetPos(); // m_A is my edit control float value variable
Invalidate(); // Invalidate is to be called to update my paint function to redraw the drawing
UpdateData(false);
*pResult = 0;
}
I have carried out the tab order correctly as well for the two controls.
Any suggestions on where I am going wrong?
Thanks in advance.
If you just want to have a spinning integer, you don't have to override anything.
The spin control has to be right next to the edit control in the tab order. With AutoBuddy that's all you have to do.
m_A when getting the position back would do something weird and would not return you the correct value. Try using the pointer to get your position and value and then carry out the invalidate().
{
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
// TODO: Add your control notification handler code here
UpdateData();
CString tempStr;
m_A += pNMUpDown->iDelta;
tempStr.Format("%f",m_A);
m_ACtrl.SetWindowText(tempStr); // Like a CEdit m_ACtrl to display your string
Invalidate();
UpdateData(false);
*pResult = 0;
}
This should work perfectly well. Let me know if you still get any problems.

Resources