2D Toolkit Forum

2D Toolkit => Support => Topic started by: ExCx on March 18, 2013, 10:44:25 am

Title: Doing an action on a certain frame (Triggers?)
Post by: ExCx on March 18, 2013, 10:44:25 am
Hi,

I'm a newbie on both Unity and 2d Toolkit, so this is probably a simple thing. I want to run a function when my animation comes to a certain frame. It seems there isn't a way to ask a tk2d animation which frame it is currently on, so I don't know how to do this properly. I noticed these things called "triggers", but can't figure out how to use them (not really sure if they are even relevant in this situation).
Title: Re: Doing an action on a certain frame (Triggers?)
Post by: evs on March 18, 2013, 11:01:19 am
http://unikronsoftware.com/2dtoolkit/forum/index.php/topic,1256.msg6025.html#msg6025


cheers

evs
Title: Re: Doing an action on a certain frame (Triggers?)
Post by: unikronsoftware on March 18, 2013, 02:21:11 pm
Triggers are probably relevant here. It asks your animated sprite to trigger something when its on a particular frame. That way you don't have to really care about frames themselves, and you can set it up visually.

Check out sample "5 - animation". The "Message" button plays a sample which has a trigger in it. You can see how this is all wired up in tk2dDemoAnimController.cs
Title: Re: Doing an action on a certain frame (Triggers?)
Post by: ExCx on March 19, 2013, 11:48:09 am
Oh thanks, I get it now. You should put info about triggers on the online documentation, too.

This also makes me understand how delegates work on C# (I read about them before, but never used). Btw, I'm calling animationEventDelegate at every frame (on Update) to catch all triggers. Is this a good practice?
Title: Re: Doing an action on a certain frame (Triggers?)
Post by: unikronsoftware on March 19, 2013, 11:52:27 am
Do you have triggers set up every frame? I'm not sure why you call animationEventDelegate...
Title: Re: Doing an action on a certain frame (Triggers?)
Post by: ExCx on March 25, 2013, 10:49:07 am
Yeah, I mean, I have triggers on most of my clips, some of them have 5 consecutive triggers, some have only 1. So I need to check them constantly.

For this, I binded the delegate to the following method:

Code: [Select]
void Start () {
anim = GetComponent<tk2dAnimatedSprite>();
spot = GameObject.Find("spot");
}

void animEvent(tk2dAnimatedSprite sprite, tk2dSpriteAnimationClip clip, tk2dSpriteAnimationFrame frame, int frameNum){
spot.transform.position = new Vector3(frame.eventInt,768,frame.eventFloat);
}

void Update () {
anim.animationEventDelegate = this.animEvent;
}

As you can see, triggers are all supposed to change the position of a GameObject (other than self). This concludes in a very slow and problematic experience in Unity's own Game screen (on consecutive triggers) but it ran smoothly on iPad, so I haven't messed with the code further.

If you tell me a more efficient way to control the triggers, I'd be happy to know.
Title: Re: Doing an action on a certain frame (Triggers?)
Post by: unikronsoftware on March 25, 2013, 01:09:37 pm
In your case you can set the delegate up in Start. As the delegate is never unset, it should never need to change. Setting a delegate like that will allocate, albeit a tiny amount of memory, so best do it at startup, or when it actually needs to change.

Hint: You can cache the delegate in a local variable to avoid the allocation.

I don't see why this should be slow in the editor. It should work fine, even if you fire it every frame.
Title: Re: Doing an action on a certain frame (Triggers?)
Post by: ExCx on April 11, 2013, 01:08:32 pm
Hmm, yeah I set the delegate in Start function now. It works fine. I read about this delegate thing, but I still didn't get it completely, so I'd appreciate if you show me how to cache this delegate in a local variable and use it that way (if it is really advantageous).
Title: Re: Doing an action on a certain frame (Triggers?)
Post by: unikronsoftware on April 12, 2013, 12:05:20 am
Its not worth cacheing the delegate until it becomes a problem :) The problem only occurs when you keep doing this every frame - each delegate set will allocate a tiny bit of memory.

You can cache it by creating a local variable containing the delegate.

class YourClass {

tk2dAnimatedSprite.AnimationCompleteDelegate yourCompleteDelegateInstance;

void Awake() {
    yourCompleteDelegate = TheDelegateImplementation; // allocation occurs here


}

void Update() {
    anim.AnimationCompleteDelegate = yourCompelteDelegateInstance; // set the instance, not create a new delegate instance every time.
}

void TheDelegateImplementation(tk2dAnimatedSprite sprite, int clipId) {
    Debug.Log("DoSomethign");
}

}