Table of Contents
Smoothly Move Analog Hands from Current Time to Zero (12:00) and Back
This tutorial will allow you to smoothly and realistically move the analog hands of a watch face to the 12:00 position (zero) and back to the current time, through the use of a tap action. In this scenario, “realistically” means not allowing the hands to “blink” into position. They must move as they would if they were physical objects, bound by the laws of motion.
This has been done countless times, and in many ways. The earliest method that I know of in Watchmaker came long before animation or scripting were available features of the program, and were done purely though tags and maths. Nowadays, it can be done much smoother, much easier, and with very little code. In fact, recently, I held a “Coding Challenge” to see if the brightest coding minds could come up with an even better solution. Mark Shoulson came up with a brilliant one, which is the basis for this wiki. (For reference, here's the original challenge post.)
So… what's the point? When would you ever use this? Well, there are many reasons, but an analog stopwatch is probably the most common. When activating the stopwatch, you'll want the hands to move to the zero position, and again when you reset the stopwatch. Then, when you leave stopwatch mode, you'll want to move them back to the current time. Simulating realistic movement adds to the analog effect, and adds a sense of realism to your watch face.
Example
Main Script
tweens.move=1 --wm_schedule
Rotation Field of Objects
Second Hand: {drss}*tweens.move Minute Hand: {drm}*tweens.move Hour Hand: {drh}*tweens.move
Tap Action (Script)
if tweens.move==0 then wm_schedule {action='tween',tween='move',from=0,to=1,duration=1,easing=linear} else wm_schedule {action='tween',tween='move',from=1,to=0,duration=1,easing=linear} end
Explanation
Seriously, that's all there is to it! Sure, things get a bit more complicated if, say, instead of zero, you try to move to the current value of a running stopwatch, but that's beyond the scope of this wiki. The goal here is to show how easy basic movement is, and you've got to admit… it doesn't get much easier than this.
So, let's go through this. There are no functions in the main script, so everything in the script will only be called once, at boot. The first line initializes our only variable, tweens.move, with a value of “1” for reasons I'll cover in a minute. The next line, “–wm_schedule” is a bit peculiar. When a line in a script begins with an em dash (yeah, that's what that “–” thing is called), it usually means that the line is a “comment” and not actual code, but I assure you, that line is quite necessary here. So what the…? Well, to explain, I'll quote the author (Mark Shoulson) here:
"It seems that tweening, at a millisecond level, DOES NOT WORK in WM unless the word 'wm_schedule' is present in the watch's main script, even as a comment."
Weird huh? So, basically, this line shouldn't be necessary, but because of a bug in the current version of WM, it needs to be there. Technically, it's still just a script comment, but the bug makes it a necessary comment.
In each hand's rotation field, The normal rotation value of the hands is simply multiplied by the value of tweens.move. Remember, we earlier initialized this as “1”. That's because anything multiplied by one is equal to itself, so if you multiply the rotational tag value by one, you get the rotational tag value; in this case: the current time. As the animation (tween) moves toward zero, that rotational value is instead multiplied by a decreasing fraction between 1 and 0. The result is that the hands slowly move counterclockwise back to zero. As it ramps from 0 to 1, the hands slowly move clockwise to the current time again. Cool, huh?
Then, all we need is a tap action. This one simply moves (over the course of one second) the tween from 0 to 1, or from 1 to 0, depending on its current value. (If you're not sure how the tween function works, that's explained elsewhere in this wiki.) Once the tween reaches the endpoint, it stays there until you tap again. That's all there is to it.
One last thing: Capitalization and auto-correct can get you into trouble. You'll notice there is no capitalization in any of the example code. That's because you have to be VERY careful with capitalization in any coding language. There's nothing wrong with it, but you'll find that most coders only use it for clarification, and avoid it otherwise. For example, a variable name like VarToMakeThingsEasierToRead kind of needs capitalization (or at least a good slap upside the head to the programmer that insists on using such long freaking variable names). Remember, Var_Num is not the same as var_num, when coding. If you're having issues, check to make sure that something didn't get capitalized or auto-corrected against your will.