Jump to content

[Script] Animated analog clock


Recommended Posts

I have an analogue -electromechanical- clock with smooth hands movement on 4 faces in the CRP mod, for the church. No pendulum - but it can strike the hour (in sync with the movement, of course).

It is quite complicated, driven by a bunch of scripts. The continuous hands movement is implemented with TranslateTo(). There's a controller script updating all the dials once per second (could be adjusted), driving the hands translation by calculating expected angles for the next update interval. The minute hands are running a little fast (only 359° in their circle), so there's time to halt them for sync at the end of each hour.

It works fine up to timescale 200 or so and then starts skipping due to the 1 second update interval being too slow for timescales >200.

 

I think the easiest way to do a pendulum would be to use a NIF animation for one swing and then trigger it from script - Especially so if you don't have smooth hands movement but update them discretely, at regular intervals.

Link to comment
Share on other sites

Well it is good to know the idea if feasible and doable. Granted the phrase "driven by a bunch of scripts" might suggest a considerable resource overhead, should the wall clock be made buildable from the workshop. Personally, I like the idea of a large analog clock in the town square. I can image hearing its chimes whether they be Westminster,

St. Michael, and Whittington. Been meaning to check out the CRP mod for a while now, and niston's post is even more reason to do so.
Link to comment
Share on other sites

https://www.nexusmods.com/fallout4/mods/63357/

Various options. Clock, pendulum, door - separate nif's. The pendulum is a looped and voiced animation. Option 1 - one big 12 hour animation in real time 1 frame per second. The hour and minute hands are synchronized in real time. Option 2 - the same, but 12 sequences, an hour-long battle for every hour is sounded. 3 option. Static model + separate nif's hour and minute hands.

Link to comment
Share on other sites

 

Well it is good to know the idea if feasible and doable. Granted the phrase "driven by a bunch of scripts" might suggest a considerable resource overhead, should the wall clock be made buildable from the workshop. Personally, I like the idea of a large analog clock in the town square. I can image hearing its chimes whether they be Westminster,

St. Michael, and Whittington. Been meaning to check out the CRP mod for a while now, and niston's post is even more reason to do so.

 

 

Well, the clock has no Westminster chime or anything fancy as it's just a small town church.

It has a funky control panel tho and the bell sound attenuates when you are inside a building.

Link to comment
Share on other sites

PlayGamebryoAnimation() and OnTimerGameTime(), if the animation is in the .nif. For templates, see SecurityBarBase01.nif and securityBarScript.

 

The script also has to detect the current game time OnInit() to call the proper number of animation sequences as the clock's hour hand needs match the current time (e.g., if the current game time is 3pm, then play 3 sequences). To get the current game time, you can use this function or a GameHour global check (FormID: 00000038).

 

 

Forgot to mention that if the clock's hour hand is placed on the clock face by a script (could be an ObjectReference script attached to the clock's base form), then you can use TranslateTo or TranslateToRef so the hour hand rotates constantly. In this case, PlayGamebryoAnimation() is not necessary.

Probably over simplifying it but assuming one could setup the nif animation with the standard 20 to 1 time ratio (i.e., 1 minute in real life equates to 20 minutes in game time), could a very simple script like this work. Essentially set up the nif animation with a single 24 sequence named "PlayIdle01" and set the clock to start at say 12. Force the game time change by updating the global GameHour (set to 12), then start the animation sequence.
ObjectReference Property myClock01 Auto Const Mandatory
GlobalVariable Property GameHour Auto Const Mandatory
EVENT OnActivate(ObjectReference akActionRef)
if akActionRef == Game.GetPlayer()
GameHour.SetValue(12 as float)
myClock01.PlayGamebryoAnimation("PlayIdle01", afEaseInTime = 1.0)
endif
EndEVENT
Link to comment
Share on other sites

Problem with clocks is, if they are to be at least somewhat accurate, you'll have to update them often - Especially so because gametime passes 20x faster than realtime by default.

And the fact that timescale is not a constant in the game environment -and may even vary at runtime- only compounds the problem. Me, for example, I play at timescale 3. And one of the mods I use would let me have timescale automatically adjust to zero whenever I'm in workshop mode (even tho I don't use this function).

 

And even though you could probably use Animation Variables for syncing and regulation purposes, NIF- and/or Havok based anims are unfortunately not very suitable to deal with all of this. Mainly because their timings are extremely inaccurate and wobbly. Designed to animate things, not for timekeeping.

 

Easiest way out is not to have smooth hand movement, but use 60 discrete steps (the clock in SOE mod does this).

Less scripted updates required that way, twice every 3 seconds real time for timescale 20 (Shannon's theorem), ie once every 1.5 seconds real time.

Also, the update process itself is rather simple for this mode of operation: Play the appropriate GamebryoAnims, according to current gametime minute and hour.

 

But the result is not "aesthetically appealing", imho. And the refresh rate requirements scale up with faster timescales, quickly approaching and then surpassing the 1.0 seconds interval that yields splendid results with TranslateTo(), for timescales up to ~200. For example, using 60 discrete steps per hour gametime at timescale 40, Shannon says you'll need a 0.75 seconds realtime refresh interval already. Which is like, going really quite fast, in terms of Papyrus performance. And if you don't observe Shannon, you'll see quantization artifacts, ie the minute hand skipping minutes every so often.

 

 

Using TranslateTo() can solve most, if not all the problems - but it's quite involved.

Even placing a translateable hand on the clock face is not straight forward. If you try it, you'll find out why :smile:

Link to comment
Share on other sites

Problem with clocks is, if they are to be at least somewhat accurate, you'll have to update them often - Especially so because gametime passes 20x faster than realtime by default.

And the fact that timescale is not a constant in the game environment -and may even vary at runtime- only compounds the problem. Me, for example, I play at timescale 3. And one of the mods I use would let me have timescale automatically adjust to zero whenever I'm in workshop mode (even tho I don't use this function).

 

And even though you could probably use Animation Variables for syncing and regulation purposes, NIF- and/or Havok based anims are unfortunately not very suitable to deal with all of this. Mainly because their timings are extremely inaccurate and wobbly. Designed to animate things, not for timekeeping.

 

Easiest way out is not to have smooth hand movement, but use 60 discrete steps (the clock in SOE mod does this).

Less scripted updates required that way, twice every 3 seconds real time for timescale 20 (Shannon's theorem), ie once every 1.5 seconds real time.

Also, the update process itself is rather simple for this mode of operation: Play the appropriate GamebryoAnims, according to current gametime minute and hour.

 

But the result is not "aesthetically appealing", imho. And the refresh rate requirements scale up with faster timescales, quickly approaching and then surpassing the 1.0 seconds interval that yields splendid results with TranslateTo(), for timescales up to ~200. For example, using 60 discrete steps per hour gametime at timescale 40, Shannon says you'll need a 0.75 seconds realtime refresh interval already. Which is like, going really quite fast, in terms of Papyrus performance. And if you don't observe Shannon, you'll see quantization artifacts, ie the minute hand skipping minutes every so often.

 

 

Using TranslateTo() can solve most, if not all the problems - but it's quite involved.

Even placing a translateable hand on the clock face is not straight forward. If you try it, you'll find out why :smile:

Why is such precision needed? The clock is almost a decorative element in the game. But, let it be once every half an hour? 24 sequences instead of 12? It would be enough for me to sync once an hour. I'm always at x1 speed. I can make speed x3. The length of the sequence will be 20 minutes. Can I initiate an event call and the desired sequence once per hour / half an hour of game time? Between syncs, let the arrows move decoratively (simply because the fewer keys, the smaller the nif size). I chose x1 speed because it ensures that the clock does not stop at the minimum game speed. But you can do nif's at once for all speeds. For example x1, x3, x6, x12, x20.those just set the animation speed to 1 fps, 3 fps... or 20 fps. And the sequence, respectively, = 3600 frames / 1200 frames / ... 180 frames. Edited by South8028
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...