Variating Speech View Animations

Started by imagazelle, 11 Nov 2021, 19:25

« previous - next »

imagazelle

Hi folks,

I'd like to figure out (if possible) how to variate characters' speech views so that the player won't see the exact same animation every time they talk.

For example, in a game like CMI, you'll notice that the characters' heads bob and mouths move in a different pattern for each line, even if you repeat the same line of dialogue over and over. This small detail helps to break up the monotony and add pleasing variety to the talking portions of the game.

So how can something like this be achieved in AGS?

I was thinking maybe you could randomize which frame of a long speech view to start with each time a character speaks, but the SpeechView function doesn't have a parameter for the starting frame. I know that the Animate function does, but is that what we'd want to use here?


Getting even more advanced than that, there are also different animations depending on the mood of the dialogue. For instance, the character might be shocked, their eyes wide and arms outstretched, or angry, with a furrowed brow and hands on their hips. And these animations too appear to be varied in their patterns. I'd love to be able to look under the hood and see how they went about doing all of this back then.

But can these things also be done in AGS? I reckon it'll take a significant number of views to animate, but I'm up for it if the results can be as desired.

Thoughts?

Mandle

Replacing characters with several different sprites during such speech scenes?

Cassiebsg

Yes, but it'll require mode code and sprites.

One way is having several views and randomizing them.
You can also "split" the character in parts (as in a character for each part: head, body, left arm, left hand, etc...) and animate those independently.

The point being, you'll have to set a new speech view (randomized) before talking every single time.
There are those who believe that life here began out there...

newwaveburritos

I sort of do this mostly just by changing speech views a lot. 

imagazelle

Yeah, I figured it would come down to having a bunch of different views and changing SpeechView each time, I was just wondering if there was a more clever and efficient way of doing it that I wasn't aware of. Maybe I can throw a function under repeatedly_execute that randomizes the standard speech view automatically, so that I'd only have to write in a manual view change when the character takes on a specific mood, rather than with every single line of dialogue. I'll think on it some more.

Thanks for the feedback, all.

Khris

You don't need repeatedly_execute for that, writing in a manual view change is enough. You don't have to state the speech view when you call Character.Say, you can already easily do exactly what you're looking for.
When the character's mood changes, simply change their speech view, and all subsequent dialog lines will use the new view.

imagazelle

Hey, Khris. Maybe I'm not following what you're suggesting, but my idea for a function under repeatedly_execute was for randomizing the plain (moodless) speech view between, say, 3-4 different animations, so that each time the character says something, it won't be the same single view every time, without the need to manually write in a view change for every line of speech. The thought was that whenever the character speaks, it will play the currently assigned view animation, which is continuously, automatically randomizing in the background, without me needing to tell it to use a different view each time. Is there a better approach for such a result?

Khris

I see, I thought you were talking about changing the view between moods. Not sure how far along the custom .Say command is, but without it you indeed have to use repeatedly_execute exactly like you described it.

imagazelle

Yeah, the mood-specific view changes would be in addition to the normal view variations, and in those cases, you are exactly right.

timid_dolphin

I've got a bunch of general mood functions in a script file with all of my little character animations.
So all of the logic around changing character views is encapsulated in these, and they can be easily called from anywhere in the script, or within dialogue scripts.

eg:
  paulThinking();
PAUL: Hey, wait a second...
  paulAngry();
PAUL: That guy didn't pay for those bananas!
  paulShakeFist();
  paulSigh();
  paulNeutral();
PAUL: Oh well...

imagazelle

Quote from: timid_dolphin on 17 Nov 2021, 04:45
I've got a bunch of general mood functions in a script file with all of my little character animations.
So all of the logic around changing character views is encapsulated in these, and they can be easily called from anywhere in the script, or within dialogue scripts.

eg:
  paulThinking();
PAUL: Hey, wait a second...
  paulAngry();
PAUL: That guy didn't pay for those bananas!
  paulShakeFist();
  paulSigh();
  paulNeutral();
PAUL: Oh well...
Yeah, something like that is what I had in mind for the mood views. Did you just put all of the called functions in your global script or did you create a new script for all of them?

timid_dolphin

#11
I like to categorise my functions and keep them out of the main script where possible.

So I have a script which has all of my custom character animations, as well as costume changes, so all of the logic around that stuff is wrapped up in neat little functions.

I think it's a good idea to spend a bit of time sorting out these things at the start so when it comes to writing dialogue you can just drop in different gestures and expressions on the fly, it means you can get away with writing less when you can communicate something more directly with 'acting'!

If you can figure out how to do it (I'm not quite there yet!) these functions should be put inside the character object, so instead of paulAngry(); you would call cPaul.angry();

timid_dolphin

Ok, so here's how it works:

first you need to go into the character editor and add a custom property to the schema for your alternate views, eg angryView. For each character you can initialise this in the character editor with the view you want to use.

Then in your script file with all of your character animation stuff, add this function:
Code: ags

function angry(this Character*)
{
  this.SpeechView = this.GetProperty("angryView");

}


and in the header for this file:

Code: ags

import function angry(this Character*);


now you can just put cBob.angry(); so switch to the angry speechview. It won't switch back though so you need another function to go back to the default.
This is a lot better for me because previously i had separate functions for every character, which clutters up the autopredict menu. It's also a neater object orientated way of organising the code.

imagazelle

#13
Quote from: timid_dolphin on 22 Nov 2021, 19:26
Ok, so here's how it works:

first you need to go into the character editor and add a custom property to the schema for your alternate views, eg angryView. For each character you can initialise this in the character editor with the view you want to use.
Hey, timid_dolphin. I like the sound of this approach for the organization and streamlined scripting, but I'm a little unclear on how to set up the custom properties (i.e., what to set as the type and value, etc.). Are you simply setting the type to "number" and the value to the number of the appropriate view?

timid_dolphin

Quote from: imagazzell on 01 Dec 2021, 05:49
Hey, timid_dolphin. I like the sound of this approach for the organization and streamlined scripting, but I'm a little unclear on how to set up the custom properties (i.e., what to set as the type and value, etc.). Are you simply setting the type to "number" and the value to the number of the appropriate view?

Your instincts are absolutely correct!

imagazelle

#15
Great! Thank you. Seems obvious now, looking back at it.

And thanks again for the clever idea. I'll report back if I encounter any roadblocks implementing it.

timid_dolphin

Awesome! Glad you liked it - thanks for the motivation to figure out that object structuring stuff in AGS.

I'm learning to code for the first time so it's satisfying to apply some of the concepts I've been learning with webdev stuff in AGS!

SMF spam blocked by CleanTalk