Dynamic Animations (Lip Sync)

  • #10, by afrlmeTuesday, 08. December 2015, 20:49 9 years ago
    Try creating a new function that contains the startAnimation() function.

    By the way, did you know that you can update the global pause value between frames during runtime with Lua script for each animation? It would essentially give you better control on how long an animation should play for.

    My suggestion though would be to force the frames because I'm not sure the talk animations unless you create them as manually started character animations will ever actually finish, as they are set to infinite loop while ever a character is talking. Forcing the frames & global pause value for the talk animation is easier.
    -- force the talk animation to loop the first frame only
    ActiveAnimations["talk"].AnimationFirstFrame = 1
    ActiveAnimations["talk"].AnimationLastFrame = 1
    

    ... & if you wanted to save time then write a work-flow function or use the one I added to the wiki ages ago.

    Imperator

    7278 Posts


  • #11, by darren-beckettThursday, 10. December 2015, 00:35 9 years ago
    Can the length of time a frame is shown of a character animation be set at runtime?

    Great Poster

    384 Posts

  • #12, by afrlmeThursday, 10. December 2015, 01:34 9 years ago
    The global pause value for all frames of an animation can be, yes. Not sure about individual animation frames though.

    During runtime you can also update the playback mode (forwards, backwards, random). You can also update the loop amount value. & you can force which frames it should play from & to. I can't remember if there's anything else you can change during runtime off the top of my head.

    Imperator

    7278 Posts

  • #13, by darren-beckettThursday, 10. December 2015, 15:00 9 years ago
    How can I detect what the character is about to say?

    Great Poster

    384 Posts

  • #14, by afrlmeThursday, 10. December 2015, 15:20 9 years ago
    You should be able to return the owner of the text &/or the id belonging to the active text using either the textStarted event listener of the registerEventHandler() function or the textPosition handler for the registerHookFunction().
    function txtStart(text)
     print( text.TextOwner, text:getId().id )
    end
    
    registerEventHandler("textStarted", "txtStart")
    


    Written that off the top of my head without checking the syntax, but it should print a message to the log each time a text is started that contains the owner of the text & the id belonging to the text. Anyway... take that as a basis then create some tables, like so...
    txt = {} -- declare global table called txt
    
    txt["English"] = {} -- add sub-table English to txt table
    txt["English"][117] = {1={d=1000, f=1}, 2={d=350, f=4},...} -- create id sub-table & add some data (d = delay in ms, f = animation frame to display)
    txt["English"][126] = {...} -- etc
    

    ... these tables are very rough, but should give you an idea. Technically you can add as many sub-tables as you like, but the general idea for looping purposes here is that the sub-tables after the id one should increment starting from 1, the reason being that we will want to access the data by iterating through it using the for loop operator or a loop created in the editor itself via the use of the jump to x action part. I recommend using the latter as you can control the delay with pause action parts. I believe that it should technically be possible to use a single display text action part & update the text by updating the string content of a value & by changing the path to the audio file belonging to the display texts current language - not 100% sure as I've not tested but in theory it should be possible - well, it's something to look into at some point (for me, I guess).

    Imperator

    7278 Posts

  • #15, by darren-beckettThursday, 10. December 2015, 15:54 9 years ago
    Nice, thanks.

    Great Poster

    384 Posts