View unanswered posts | View active topics It is currently Wed Dec 25, 2024 5:23 pm



Reply to topic  [ 4 posts ] 
 Blinking 
Author Message
User avatar

Joined: Tue Jun 19, 2012 8:01 pm
Posts: 19
Reply with quote
Post Blinking
I wanted to make my actor's eyes blink infrequently, and preferably irregularly.

"SpriteAnimMode = 2" does randomize frames, but I didn't want to make (and have CC load) many frames of the same open eyes with one closed eyes frame.
I'm a total novice at programming, but I managed to hack together some Lua. If my approach is bad, I'd rather get feedback before sharing it in the Minor Mod Dump (if there's a Script Dump, I have no idea where it is).

At first I hacked together a while-loop. But since I had to add in a timer to keep it from blinking inhumanly fast (and a coroutine.yield to keep it from locking my computer), I rewrote it as two timers.
One is for the interval between blinks and the other for the duration of the blink.
Both use math.random to make it more naturally variable.

Here's my code:


I don't know if timers have to be checked every millisecond or if they're actually lighter on clock cycles than I suspect.
Would "coroutine.yield" and "coroutine.resume" be useful in this kind of "do something, then wait, then do something else" constructions? I'm not very clear on what they even are; they just sound cool. The CC wiki says nothing, but I breezed over the Lua coroutine documentation.

Anyone have feedback or suggestions?


Wed Apr 10, 2013 11:48 am
Profile
User avatar

Joined: Wed Feb 17, 2010 12:07 am
Posts: 1545
Location: That small peaceful place called Hell.
Reply with quote
Post Re: Blinking
Well first off your problem is the timer for the blink duration is already passed by the time the interval has passed. So really, you're not even getting a single frame for the blink to even happen.

This can easily be fixed by adding two lines fortunately, instead of all that coroutine nonsense.

Second, 0.18 - 2.7 seconds is a rather inhuman blink interval. Remember that MS stands for milliseconds, not seconds.

Code:
function Create(self)
   self.blinkIntervalTimer = Timer();   -- Time between blinks.
   self.blinkDurationTimer = Timer();   -- Time each blink takes.
end

function Update(self)

   if self.blinkIntervalTimer:IsPastSimMS(math.random(1000,4150)*1.2) then --Adjusted time
      self.Frame = 1;
      if self.blinkDurationTimer:IsPastSimMS(math.random(300,800)*0.92) then --Adjusted time
         self.Frame = 0;
         self.blinkIntervalTimer:Reset();
         self.blinkDurationTimer:Reset();
      end
   -- Reset blink duration until the interval is over
   else
       self.blinkDurationTimer:reset();
   end

end


Also you might be better off with IsPastSimMS instead of IsPastRealMS

SimMS counts for delta/simulation time whereas RealMS counts for real life time.


Wed Apr 10, 2013 1:59 pm
Profile
User avatar

Joined: Tue Jun 19, 2012 8:01 pm
Posts: 19
Reply with quote
Post Re: Blinking
Ah, thanks Coop. I had totally overlooked how the duration timer is still running during the interval between blinks. The script worked, but it only looked good after changing the millisecond values from what I started with from researching it. The timer problem explains why realistic values looked unreal.


Wed Apr 10, 2013 9:19 pm
Profile
User avatar

Joined: Tue Jun 19, 2012 8:01 pm
Posts: 19
Reply with quote
Post Re: Blinking
I got a lot of flickering with your version, Coop. I think math.random gets called every update and, by sheer repetition, it tends to eventually come up with a small value for each timer and run through the whole process.

So I set up counters to hold interval and duration values that get set once and only once in the blink process. Thanks for drawing my attention to what's happening with each timer as it updates each frame.

It's looking pretty good on my actor. May be useful for others wanting a meatpuppet (or robot) with a little more life on its face.

Code:
function Create(self)
   self.blinkIntervalCounter = 2800;   -- Holds randomized values for time between blinks.
   self.blinkIntervalTimer = Timer();   -- Counts milliseconds until time between blinks reached.
   self.blinkDurationCounter = 300;   -- Holds randomized values for time blink takes.
   self.blinkDurationTimer = Timer();   -- Counts milliseconds until blink length reached.
end

function Update(self)

   -- While the interval timer is over the interval limit...
   if self.blinkIntervalTimer:IsPastSimMS(self.blinkIntervalCounter) then
      self.Frame = 1;   -- ...switch to "eyes closed" frame...
      -- ...and let the duration timer run until it hits the duration limit.
      if self.blinkDurationTimer:IsPastSimMS(self.blinkDurationCounter) then
         -- Once the blink is over...
         self.Frame = 0;   -- ...return to the "eyes open" frame...
         self.blinkIntervalTimer:Reset();   -- ...and reset the interval timer.
         -- Set new random time until next blink, skews toward 2800ms but allows 500-10000ms intervals.
         self.blinkIntervalCounter = math.random(1785,35700)*0.28;
         -- Set new random length of next blink, skews toward 300-400ms but allows 100-400ms durations.
         self.blinkDurationCounter = math.random(66,285)*1.5;
      end
   -- Keep the duration timer suppressed during the interval between blinks.
   else
      self.blinkDurationTimer:Reset();
      self.Frame = 0;   -- Open the eyes, just in case something went wrong.
   end

end


Thu Apr 11, 2013 12:32 am
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 4 posts ] 

Who is online

Users browsing this forum: No registered users


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by STSoftware for PTF.
[ Time : 0.046s | 13 Queries | GZIP : Off ]