Speech bubbles

  • #1, by UraalSunday, 23. March 2014, 18:07 10 years ago
    Time that I give something back to community for all the help smile. Here's my speech bubble script:

    function setTextPosHook(text)
    
    local Bubble = getObject("Interfaces[Speechbubble]")
    local Character = getObject("Characters[pallo]")
    local Characterposition = Character:getPoint(VCharacterPosition)
    
     if text:getLink(VTextOwner):getId().tableId == eCharacters 
     and text:getLink(VTextOwner):getName() == "NAMEHERE" 
     then
      Bubble:setValue(VInterfaceVisible, true)
      Bubble:setValue(VInterfaceOffset,{x=Characterposition.x-155, y=Characterposition.y - 200})
      text:setValue(VTextPosition, {x=Characterposition.x -30, y=Characterposition.y-160 })
        return true
     end
    end
    
    
    function OnStopText(text)
    getObject("Interfaces[Speechbubble]"):setValue(VInterfaceVisible, false)
    end
    
    
    registerHookFunction("setTextPosition", "setTextPosHook")
    registerEventHandler("textStopped","OnStopText")
    


    All you have to do is copy paste that whole code into script file and make it a definition script from properties. You also need to change "NAMEHERE" to whatever character you want to view the speechbubbles when they talk. Name can be found from character list in Visionaire editor (the one at left once you open characters tab). You will also need a interfacelement (I recomend setting it up as a secondary interface element) this item will be your speech bubble.

    Bubble:setvalue has x coordinates and number and y coordinates. You can use this to change speechbubble position to fit the character position. There's also text:setvalue that defines where the text is drawn. It's also good idea to have Max. line width [pixel] set to your font to whichever pixel fits the bubble graphics width.

    Newbie

    93 Posts


  • #2, by afrlmeSunday, 23. March 2014, 18:25 10 years ago
    nice one mate smile

    any chance you could provide a template/demo .ved for it?

    P.S: I believe this could be edited a wee bit to make it a bit more global - also it needs a bit of math to adjust offset values based on character scale I think?

    Imperator

    7278 Posts

  • #3, by UraalSunday, 23. March 2014, 20:00 10 years ago
    Yeah I noticed the scaling problem and currently working on it, but for some reason I don't seem to be able to
    use the following
    
    
    local scale = getObject("Characters[hero]"):getInt(VCharacterSize)
    local positionmodifierx = scale+500
    
    


    Any ideas?

    Newbie

    93 Posts

  • #4, by afrlmeSunday, 23. March 2014, 20:13 10 years ago
    no, because VCharacterSize was added to v3.8 which means you will have access to it in the upcoming 4.0 release.

    The next issue is that not all characters are the same height & the VCharacterSize returns scale % value not the actual image size in px or anything like that.
    your math is not quite right.

    it would more likely than not consist of divide & multiply I think. then the answer you get would then be added or subtracted from the offset value. Not sure off the top of my head.

    Imperator

    7278 Posts

  • #5, by UraalSunday, 23. March 2014, 20:30 10 years ago
    Ah yes, knew about math part not being correct I was just wondering why I can't add up two already declared variables to form a third variable but since VCharacterSize is not in use yet, that explains a lot.

    Is there currently any work around for accessing scale?

    Newbie

    93 Posts

  • #6, by afrlmeSunday, 23. March 2014, 20:36 10 years ago
    no, it was something I asked to be added to the data structure sometime last year, as I needed it for a dynamic character sound script I was working on for Thomas.

    the upcoming release should be ready for the end of this month though... they are just fixing bugs at the minute & getting it ready for release.

    If you provide me with a .ved to test then I can figure out the rest of the script or whatever is needed.

    Imperator

    7278 Posts

  • #7, by afrlmeMonday, 24. March 2014, 15:15 10 years ago
    Ok there's another issue here... during cut scene the interface is hidden.

    Hide/Show cursor action can be used instead of cutscene action parts but hide/show cursor kills all input methods meaning you can't skip the cutscene, displayed texts or perform any key input actions.

    Imperator

    7278 Posts

  • #8, by UraalMonday, 24. March 2014, 19:49 10 years ago
    Yes, beginning to think that having a speech bubble as an character that's toggled to player position in his current scene might be more flexible and working idea. Interface also broke with bigger than default resolution (panning) scenes. I'll post new version using character bubble as fast as I am finished with it smile

    Newbie

    93 Posts

  • #9, by afrlmeMonday, 24. March 2014, 19:56 10 years ago
    local var = game:getLink(VGameCurrentScene):getName()
    


    I have been reworking your code slightly myself.
    instead of repositioning the text you could get text position & then offset the speech bubble to that instead.

    also some of your variables should be added outside of the function.

    Imperator

    7278 Posts

  • #10, by UraalMonday, 24. March 2014, 20:53 10 years ago
    Here's my code for character speechbubble that follows scaling bit better. So all you gotta do is make the character named bubble1 to scale and place animationpoint thing accordingly.

    function setTextPosHook(text)
    
      local Speaker = getObject("Characters[hero]")
      local Speakerpos = Speaker:getPoint(VCharacterPosition)
      local Speakerscene = Speaker:getLink(VCharacterScene)
      local Speechbubble = getObject("Characters[bubble1]")
      local Bubblepos = Speechbubble:getPoint(VCharacterPosition)
    
      if text:getLink(VTextOwner):getId().tableId == eCharacters and text:getLink(VTextOwner):getName() == "hero" then
        Speechbubble:setValue(VCharacterActive, true)
        Speechbubble:setValue(VCharacterVisibility, 100) 
        Speechbubble:setValue(VCharacterScene, Speakerscene)
        Speechbubble:setValue(VCharacterPosition,{x=Speakerpos.x, y=Speakerpos.y})
        text:setValue(VTextPosition,{x=Speakerpos.x, y=Speakerpos.y})
        return true
      end 
    end
    
    
    function OnStopText(text)
      
      local Speechbubble = getObject("Characters[bubble1]")
      local Speaker = getObject("Characters[hero]")
      Speechbubble:setValue(VCharacterActive, false)
      Speechbubble:setValue(VCharacterVisibility, 0)
    end
    
    registerHookFunction("setTextPosition", "setTextPosHook")
    registerEventHandler("textStopped","OnStopText")
    


    Unfortunately this code has few bugs:

    1. Instantly pressing on same object results into this code not running for some reason
    2. I still haven't figured out how to access scaling, regardless of all sort of point and trick attempts and even some algorithms that didn't work all that well.
    3. In one scene this bubble doesn't appear at all, I suspect it has something to do with scene's narrow way system.

    Bit out of ideas unfortunately. Starting to have a feeling that having speech bubbles as part of the talk animation might be the way to go smile

    Newbie

    93 Posts

  • #11, by afrlmeTuesday, 25. March 2014, 02:16 10 years ago
    grin

    you could just add a single object to each scene containing the speech bubble image inside of an animation with infinite loop set. you can then reposition & fade in the animation as needed. it will bypass the cuts scene issue that way.

    As for characters you can store the owner of the text into a variable which can then be included inside of the getObject characters square brackets thing like so...
    char = text:getLink(VTextOwner):getName() -- get name of text owner
    char = getObject("Characters[" .. char .. "]") -- replace char with getObject Character instead.
    


    As for all of your local variables... you either want to define them outside of the function or create a temporary table instead as each time you call local variable inside of a function you are creating a new table as opposed to overwriting the old one.

    here is a temporary table example...
    -- incrementing table
    table_name = {}
    table_name["_temporary_"] = ""
    table_name[1] = getObject("Characters[hero]") 
    table_name[2] = {x = 300, y = 500}
    
    -- example on how you would include this data in something.
    table_name[1]:setValue(VCharacterPosition, table_name[2])
    -- or
    table_name[1]:setValue(VCharacterPosition, {x = table_name[2].x, y = table_name[2].y})
    
    
    -- key_name table
    table_name = {}
    table_name["_temporary_"] = ""
    table_name["char"] = game:getLink(VGameCurrentCharacter)
    table_name["a"] = ...
    
    -- example on how you would include this data in something
    print("name of current character: " .. table_name["char"]:getName())
    


    the other thing I was talking about would be done by setting up the variables that will contain data that will always be the same at the beginning of your script, above the function & anything that will contain data that gets updated as an empty variable.

    you can define blank variables like so...
    local var, char, a, b, etc -- these are empty but can now be used inside of functions
    

    Hopefully some of this will help you a little bit.

    & about the character scaling thing. you can not access the VCharacterSize data entry until you have upgraded to V4.0 & it will be accessed like so...
    getObject("Characters[name]"):getFloat(VCharacterSize) -- returns character size including .decimal value - you would need to use the Lua string function to trim out the decimal point & characters after it - if required.
    

    Imperator

    7278 Posts