Hello Guest

Author Topic: How to play animationf after a WaitForSeconds  (Read 8609 times)

alfchee

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 6
    • View Profile
How to play animationf after a WaitForSeconds
« on: July 04, 2012, 03:58:20 am »
Hi everybody!!

I'm new using 2DToolkit, and I want to play several animations in response to an action. What i want to do is: make a click on an object, make the character walk to the object executing that animation, and when the character is beside the object play another animation. Im trying to use a coroutine calculating the amount of time necesary to get to the object clicked and make a yield WaitForSecond, but the animation is not played.
I added some debug messages and these messages get showed but the animation is not getting played. What could be the problem?

Here is part of the code:

Code: [Select]

public IEnumerator ProcessCurrentState()
{
switch (State)
{
case CharacterState.Idle:
anim.Play("idle");
anim.animationCompleteDelegate = WalkCompleteDelegate;
break;
case CharacterState.WalkingRight:
anim.Play("walking_side_right");
break;
case CharacterState.WalkingLeft:
anim.Play("walking_side_left");
break;
}

if(currentAction.CompareTo("Prune") == 0)
{
Debug.Log("if prune");
yield return new WaitForSeconds(5f);
anim.Play("prune_left");
Debug.Log("after yield");
}
yield return null;
}//ProcessCurrentState()

public void Prune()
{
currentAction = "Prune";
StartCoroutine(TP_Animator.Instance.ProcessCurrentState());
}

fsadeq

  • 2D Toolkit
  • Sr. Member
  • *
  • Posts: 353
    • View Profile
Re: How to play animationf after a WaitForSeconds
« Reply #1 on: July 04, 2012, 04:13:24 am »
I think you would be better off just having a trigger around the object that you are clicking. Then you can much more easily (and properly) detect when the player is near it and play whatever animation you want.

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: How to play animationf after a WaitForSeconds
« Reply #2 on: July 04, 2012, 10:02:43 am »
Hi everybody!!

I'm new using 2DToolkit, and I want to play several animations in response to an action. What i want to do is: make a click on an object, make the character walk to the object executing that animation, and when the character is beside the object play another animation. Im trying to use a coroutine calculating the amount of time necesary to get to the object clicked and make a yield WaitForSecond, but the animation is not played.
I added some debug messages and these messages get showed but the animation is not getting played. What could be the problem?

Here is part of the code:

Code: [Select]

public IEnumerator ProcessCurrentState()
{
switch (State)
{
case CharacterState.Idle:
anim.Play("idle");
anim.animationCompleteDelegate = WalkCompleteDelegate;
break;
case CharacterState.WalkingRight:
anim.Play("walking_side_right");
break;
case CharacterState.WalkingLeft:
anim.Play("walking_side_left");
break;
}

if(currentAction.CompareTo("Prune") == 0)
{
Debug.Log("if prune");
yield return new WaitForSeconds(5f);
anim.Play("prune_left");
Debug.Log("after yield");
}
yield return null;
}//ProcessCurrentState()

public void Prune()
{
currentAction = "Prune";
StartCoroutine(TP_Animator.Instance.ProcessCurrentState());
}


calling anim.Play(...) repeatedly will make it get stuck at the first frame (i.e. the clip keeps getting restarted) - can you please confirm that this isn't happening. If you call Prune from Update() it will happen.

And yea - as fsadeq says, you'll probably be better off using triggers to detect clicks and trigger the animations.
« Last Edit: July 04, 2012, 10:12:28 am by unikron »

alfchee

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: How to play animationf after a WaitForSeconds
« Reply #3 on: July 14, 2012, 11:34:03 pm »
Thanks for all the answers. I was out of job so I couldn't test anything. I'm gonna try with the triggers, and I gonna tell you what about.

alfchee

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: How to play animationf after a WaitForSeconds
« Reply #4 on: July 15, 2012, 11:36:10 pm »
Well, about this same situation, I'm changing the way to do the things, so using the colliders I see that the Sprites uses a mesh collider, but I cant raycast to it, why that??

Im using this code, and I'm not getting it. Using the same code with a primitive collider works perfectly.

Code: [Select]
GameObject GetObjectClicked()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;

if(Physics.Raycast(ray, out hit))
return hit.collider.gameObject;
else
return null;
}//GetObjectClicked()

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: How to play animationf after a WaitForSeconds
« Reply #5 on: July 16, 2012, 12:14:59 am »
Set "collider cap" on the mesh colliders, and commit your sprite collection. By default no cap is generated.

alfchee

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: How to play animationf after a WaitForSeconds
« Reply #6 on: July 16, 2012, 11:11:33 pm »
Thanks!!! that was the problem, I set the "Collider Cap" to "Front" and now it works.

alfchee

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: How to play animationf after a WaitForSeconds
« Reply #7 on: July 27, 2012, 06:12:11 pm »
Hi! I changed the code and I'm now using a trigger, so when the character get close to the grass (if the grass was clicked), the character stops and start the animation of "prunning". But the animation get stopped in the first frame. I would like if you make me see the mistake I'm doing, and thanks for all.

PDD: I think that the State is not changing to "Prunning" or it changes but in the same frame update is changing to "Idle"

TP_Controller: when I handle the inputs
Code: [Select]

      public void Stop()
{
if(targetDirection.x > 0)
targetPosition = new Vector2(CharacterController.transform.position.x + (0.000002f), targetPosition.y);
else
targetPosition = new Vector2(CharacterController.transform.position.x - (0.000002f), targetPosition.y);
}//Stop()

public void HandleActionInput()
{
// Actions for Objects Clicked
if(Input.GetMouseButtonDown(0))
{
var objClicked = GetObjectClicked();

if(objClicked != null)
{
// If the object clicked is the ground or the grass, the character will move to the place clicked
if(objClicked.CompareTag("ground") ||
objClicked.CompareTag("grass"))
{
SetTargetToWalk();

// If the object clicked is the grass, we execute prune
if(objClicked.CompareTag("grass"))
Prune();
}
}
else
Debug.Log("Is null");
}

}//HandleActionInput()

void Prune()
{
TP_Animator.Instance.currentAction = "prunning";
}//Prune()

Grass: Script attached to the grass
Code: [Select]
void OnTriggerEnter(Collider other)
{
if(other.CompareTag("Player"))
{
TP_Animator tpa = (TP_Animator)other.GetComponent("TP_Animator");

if(tpa.currentAction == "prunning")
{
TP_Controller tpc = (TP_Controller) other.GetComponent("TP_Controller");
tpc.Stop();
tpa.Prune();
//tpa.State = TP_Animator.CharacterState.Pruning;
//StartCoroutine(tpa.ProcessCurrentState());
}
}

}//OnTriggerEnter()

TP_Animator: where the animations are executed
Code: [Select]
      public enum CharacterState
{
WalkingLeft, WalkingRight, Running, Idle, Falling, Jumping, Dead, Hitting, Pruning
}
public enum Direction
{
Stationary, Left, Right
}
        public CharacterState State;
public Direction MoveDirection;
public string currentAction = "";
........
        void DetermineCurrentDirection()
{
if(TP_Controller.Instance.targetDirection.x > 0)
{
MoveDirection = Direction.Right;
}
else if(TP_Controller.Instance.targetDirection.x < 0)
MoveDirection = Direction.Left;
else if(TP_Controller.Instance.targetDirection.x == 0)
MoveDirection = Direction.Stationary;
}//DetermineCurrentDirection()

void DetermineCurrentState()
{
if(State == CharacterState.Dead)
return;

if(!TP_Controller.CharacterController.isGrounded)
Debug.Log("It should be falling");

if(State != CharacterState.Dead &&
State != CharacterState.Jumping &&
State != CharacterState.Falling)
{
switch(MoveDirection)
{
case Direction.Stationary:
State = CharacterState.Idle;
break;
case Direction.Right:
State = CharacterState.WalkingRight;
break;
case Direction.Left:
State = CharacterState.WalkingLeft;
break;
}
}
}//DetermineCurrentState()

public IEnumerator ProcessCurrentState()
{
switch (State)
{
case CharacterState.Idle:
if(currentAction == "")
Idle();
else
Prune();
break;
case CharacterState.WalkingRight:
WalkingRight();
break;
case CharacterState.WalkingLeft:
WalkingLeft();
break;
case CharacterState.Jumping:
break;
case CharacterState.Falling:
break;
case CharacterState.Hitting:
break;
case CharacterState.Pruning:
Prunning();
break;
}

yield return null;
}//ProcessCurrentState()
..........
void Prunning()
{
if(!anim.isPlaying())
{
Debug.Log("Prunning");
State = CharacterState.Idle;
currentAction = "";
anim.Play("idle");
}
}//Prunning()

public void Prune()
{
Debug.Log("Start to prune");
State = CharacterState.Pruning;
anim.Play("prune_left");
}//Prune()

alfchee

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: How to play animationf after a WaitForSeconds
« Reply #8 on: November 06, 2012, 10:22:11 pm »
Previously Unikron has said:
Quote
calling anim.Play(...) repeatedly will make it get stuck at the first frame (i.e. the clip keeps getting restarted) - can you please confirm that this isn't happening. If you call Prune from Update() it will happen.

Now I'm having this kind of problem, but I don't know how to avoid that problem without use a trigger. In this case I'm using raycast and I don't know why with an object works well but with other doesn't. I'm doing this:

Code: [Select]
if(Physics.Raycast(origin,direction, out hitInfo,1.2f))
{
if(hitInfo.collider.gameObject.name == "pole" && Animator.Instance.currentAction == "hoistFlag")
{
StopInFrontObjectClicked();
Animator.Instance.HoistFlag();
}

if(hitInfo.collider.gameObject.name == "pump" && Animator.Instance.currentAction == "drinkingWater")
{
Debug.Log("ray hit the bump.");
StopInFrontObjectClicked();
Animator.Instance.DrinkFromWell();
}
}

and into another script with the code for the animations, I have:

Code: [Select]
public void HoistFlag()
{
State = CharacterState.HoistingFlag;
if(MoveDirection == Direction.Left)
anim.Play("hoist_flag_left");
else if(MoveDirection == Direction.Right)
anim.Play("hoist_flag_right");

anim.animationCompleteDelegate = ActionToIdleCompleteDelegate;
}//HoistFlag()

public void DrinkFromWell()
{
State = CharacterState.Drinking;
Debug.Log(State.ToString());
anim.Play("drink_water_from_well");

anim.animationCompleteDelegate = ActionToIdleCompleteDelegate;
}//DrinkFromWell()