Exact Cinematic timing (Trigger Queue and Timers)
Wait actions never work exactly and this is annoying especially when you create cinematics. If you don't know this problem, read the rest of this paragraph, otherways continue.
Maybe you noticed this when you built camerasways in the past: You said "Apply CameraX over 3 seconds", added a "Wait 3 seconds" behind it and then a final "Apply CameraY over 2 seconds". Then the sway will look very ugly because the sway stops for about 0.2 seconds when it reaches CameraX. The reason is that the "Wait" waits always longer than requested, no matter if it is a normal or a gametime "Wait". And the worst: the amount of delay always varies, so you often can't just make the waits shorter and everything is fine. This is annoying especially if you want to time animations and effects in action scenes.
Use a periodic event like used in Infrane's and Anitarf's JASS Cinematic System. If you don't want to do nearly everything in JASS, there is another alternative to these damn "Wait" actions: Use "Elapsed gametime equal to x seconds" events. They are exact. But they have obviuosly huge disadvantages:
This tutorial will teach you how to use a timer and the trigger queue to get your cinematic actions perfectly timed.
The Trigger Queue
The trigger queue is an old feature available since Reign Of Chaos but I never saw anybody using it; so there will probably be many people who don't know what it is and how it works. If you know the trigger queue and how to use it, skip to the next point.
The trigger queue is, just as the name says a queue of triggers. The triggers will be executed in the order you added them, so if you add Trigger1, then Trigger2 and then Trigger3, Trigger1 is the first that will be executed. The actions of the first trigger in the queue will be executed instantly. The second trigger waits until the first is removed from the trigger queue and as soon as the first is removed, it will instantly start. This is what we are going to base our cinematic's timing on.
What you need
Go to the trigger editor and to the variables window and create the following variables:
2. Creating the trigger structure
Well, of course it is not necessary that you use this structure for your map, but I recommend it when you use this method the first time, because I had good experiences with it. Later you may use your own variation if you like it more.
You should have a folder for initialization and general triggers. In this folder, I devide the simple initialization triggers and the general triggers by comments. You can do this as you like, but you should know what is where and be able to find it easily. I have two initialization triggers: One to fire at "Map Initialization" and one to fire at "Elapsed game-time is 0.00 seconds". We need the difference because the first is still in loading screen and the second is actually about 0.2 seconds after the loading screen, so you see the difference this trigger causes, if there is any (e.g. I often see cinematics that turn cinematic mode on at 0.00 seconds - this should save loading time, I heard. This may be, but it looks so ugly that you really should do this at map init).
Create also a new folder called "Queued Cinematic Triggers". Your structure in the trigger editor should now look like this:
3. Create your first cinematic trigger
All queued cinematic triggers do not need any event or condition.
The first cinematic trigger has three parts, which you should show by comments:
Instead of 2.00 seconds, you should insert the time you want to wait until the next cinematic trigger should start.
We don't have any additional triggers for this scene yet so we can't add any.
The first trigger will fire instantly when the cinematic should start, so add things like applying the first camera and fading in the third part. You should always add only actions that you want to execute actually at the moment the trigger fires, because we want to get rid of waits, so it's best not to begin using them at all.
At last, add a trigger action
where you want to start the cinematic, in my example I add it to the "Gametime 0 init" trigger.
Trigger - Add Cinetrigger 01 <gen> to the trigger queue (Ignoring conditions)
4. Create following cinematic triggers
The normal cinematic triggers structure is nearly the same as with the first one, but the "Add this scene's triggers" part is missing. So I just copy&paste the first trigger, rename it and replace each "start NextTrigger" time with the time I need (this may also be very few, e.g. 0.1 seconds - it will work well and exactly!) as well as of course setting "This cinematic trigger's actions" to the ones I need. You may do it the same way or copy the things manually if you prefer this for any reason.
5. Adding the following cinematic triggers to the queue
Well, now that we have some more triggers for the queue, we should also add them. You should do this in the first trigger in the "Add this scene's triggers" using actions of the type "Trigger - Add trigger to the trigger queue" for every following trigger in the scene.
Now we have all triggers in the queue, but if you remember the principe the trigger queue works, you should know that only the first one will fire, because it keeps the others from starting until it is removed.
6. Create the "Start Next Trigger" Trigger
Just add the following trigger to the General Triggers:
Well, I could say, that's all. So how does this work? At the start of every queued trigger, the variable "RunningTrigger" is set to this trigger, so always the running trigger will be removed from the queue. But it will wait with removing and therefore with firing the next trigger until the timer expires. As soon as the timer expires, the current trigger is removed and the next trigger starts, so the effect is just as if you would have copied each following trigger's actions to the first with a wait between the "actions-packs". But since timers are very accurate, you now have perfect timing that always behaves the same way.
Theoretically, you can add all triggers to the trigger queue at the beginning of the cinematic. I did not test it, but I think it's better for performance to keep the trigger queue not too long. You also can add always only the following trigger when starting each of the triggers, but that's probably quite difficult to overview. I personally prefer a structure of scenes: I give all triggers of each scene the same name and a number. In the first trigger of each scene, I add all remaining triggers of the scene and the first of the next scene to the queue.
Escape function in playable maps
Canceling a cinematic in playable maps also gets much easier. You don't need any boolean "cinematic skipped" variable or all these if/then/else actions with "skip remaining actions" any longer. Just pause the NextTrigger timer and clear the trigger queue. Now nothing of the cinematic triggers should follow anymore but everything is ready for the next cinematic. Of course you should fade out and setup the things for continuing gameplay, too. :emote_wink:
Well, probably you already realized that this method will cause you to build very many small triggers instead of the few big ones you had using waits. Every trigger takes memory, so you should try to reduce their count ingame. The best way to do this is just to add this action to every trigger that, once it's executed, is no longer needed:
This will free the memory the trigger took before, but the trigger is not useable in any way afterwards. Anyways, I recommend that, because probably you are not able to build a map that does not at all use more and more memory with increasing game time (leak), and the more memory a map uses, the slower it will run, especially on computers with not that much RAM.
Custom Script: call DestroyTrigger(GetTriggeringTrigger())
Yay, thanks for resubmitting it.
It's now ready for approval.
Hey, thanks! :emote_thumbup:
Does this technic can correct the difference between a wait in solo games and a wait in b.net games ? .. or just be better than a basic wait ?
Well, it replaces the waits, always being exact the time you use for it in the trigger editor - no matter if b.net or local game. So it should also solve your problem, since there are no waits (never waiting the value you gave) at all anymore (I don't have much experience with b.net).
I hate necro-ing discussions, but I'd really like to know if anyone has used this method, and might be able to provide a small working demo? I've read it, tried using it in the editor, but without any legitimate commands in the triggers, I'm not sure of the overall structure...
I'm only a beginner with WE and am not even remotely experienced enough to try the alternate scripting based camera system, but I do need something to give me better control over timing and camera control. This looks interesting, and in theory it's sound, but unfortunately, I learn best by evaluating and studying working models...
|All times are GMT. The time now is 03:02 AM.|
Powered by vBulletin (Copyright ©2000 - 2019, Jelsoft Enterprises Ltd).
Hosted by www.OICcam.com
IT Support and Services provided by Executive IT Services