cassius Posted October 8, 2012 Share Posted October 8, 2012 At the moment I have a single seperate animation function for each character and I was wondering how other people tackle this.Would it be feasible or advisable to have a single anim function for ALL characters? Quote amd quad core 4 ghz / geforce 660 ti 2gb / win 10 Blender,gimp,silo2,ac3d,,audacity,Hexagon / using c++ Link to comment Share on other sites More sharing options...
gamecreator Posted October 9, 2012 Share Posted October 9, 2012 Up to you but if all of the animation functions do the same thing (and will, for the foreseeable future) then yeah, no harm in combining them. Quote Link to comment Share on other sites More sharing options...
Road Kill Kenny Posted October 9, 2012 Share Posted October 9, 2012 With animations for characters I always make an "animator" class. This is generally how I do it. Like it or not it works for me The animator class lives within any character class in a "Has a" relationship. The animator class is given a pointer or reference to the mesh to be animated and stores each animation in an animation struct as shown below: struct Animation { float start; float end; float speed; int SEQ; //sequence std::string type; //name of the animation bool loop; float currentFrame; float blendVal; }; These structs are then stored in a std::map<std::string, struct Animation> STL map where the std::string is the name of the animation and the struct is... well the struct. The class has a number of functions to register animations, play animations, stop animations etc. and all that the character class has to do is 1. update the animator each frame and 2. initialize new animations based on what is happening. Anyway... This animator class I'm showing here is kinda suited to DDD but you could easily use it without, you'll just have to register each animation separately in hard code. Below is the class declaration. I'll let y'all figure out how to make the implementation. class Animator { public: Animator::Animator(LE::TEntity *pModel); Animator::~Animator(); void Update(); void RegisterAnimation(std::string type, float start, float end, float speed, int SEQ); void PlayAnimation(std::string type, bool loop); void StopAnimation(); void BlendAnimation(std::string type, float blendRate, bool loop); void PlayEmote(int); private: void LoopAnimation(struct Animation*); LE::TEntity *pModel; float blendRate; std::vector<int> AnimDelete; std::map<std::string, struct Animation> AnimBank; std::vector<struct Animation> EmoteBank; std::vector<struct Animation*> AnimActive; struct Animation *anim; }; - Update() - plays any animation that is active including animations that still have a blend value greater than 0. If the animation structs loop variable is true it will loop expired animations otherwise it will erase them from the AnimActive list. If the blend value of an active animation reaches 0 it will also be removed from the AnimActive list. If there are registered emotes and the "idle" animation is active this function will roll a dice for playing an emote. - RegisterAnimation() - creates a new animation struct based on the given data and inserts it at the end of AnimBank. - PlayAnimation() - plays the requested animation either looped or not... This will remove all other active animations prior to the call whether blended or full on. - StopAnimation() - Clears AnimActive which effectively stops all animation - BlendAnimation() - Adds a new animation to AnimActive with a low blend value. The blend value of this animation will continue to rise until it reaches 1.0f and all others in AnimActive are 0 and then removed. If BlendAnimation is called before the last BlendAnimation() anim finishes then the last one will be blended out from where ever it was. - PlayEmote() - plays a single emote at random. - LoopAnimation() - Edits the data in the Animation struct passed to it so that it will loop and not end. It is called only if an animation reaches its end and the loop boolean parameter is true. NOTE: This class was made specifically with my game in mind... Therefore, while idle, it will randomly play random emote animations (if registered). Therefore, some of the functions like PlayEmote(int) may not make sense to you. However, the way it works in my code is, if the animation called "idle" is playing then it rolls a dice (1 in 7 chance) and if it hits 7 it plays a random emote animation labeled "emote" from the EmoteBank (std::vector<struct Animation> all emotes are labelled "emote" while all other animations must be unique. Quote STS - Scarlet Thread Studios AKA: Engineer Ken Fact: Game Development is hard... very bloody hard.. If you are not prepared to accept that.. Please give up now! Link to comment Share on other sites More sharing options...
cassius Posted October 9, 2012 Author Share Posted October 9, 2012 Scarlet thread : Interseting, but a bit complex for me. I will paste that code into my "examples" folder for later study. At the moment I have a simple struct called actor which contains everything pertaining to characters including framebegin and frameend and health etc. Quote amd quad core 4 ghz / geforce 660 ti 2gb / win 10 Blender,gimp,silo2,ac3d,,audacity,Hexagon / using c++ Link to comment Share on other sites More sharing options...
Road Kill Kenny Posted October 9, 2012 Share Posted October 9, 2012 ahh ur using C not C++... right forgot about that. Quote STS - Scarlet Thread Studios AKA: Engineer Ken Fact: Game Development is hard... very bloody hard.. If you are not prepared to accept that.. Please give up now! Link to comment Share on other sites More sharing options...
Rick Posted October 9, 2012 Share Posted October 9, 2012 cassius with C you'll want to store an array of a structure that holds the animations of that character because it'll have more than 1 animation to it. Then you can have normal functions like: UpdateAnimations(characterStruct char); Where you process the animations of the character you pass into it. The thing you'll want to do is actually loop through every active animation each cycle. You do this because of blending. You'll most likely only have at most 2 active at a time (unless you are trying to do split animations) and mostly only 1 active. I say this because when you are blending between 2 animations they'll both be active and you'll call Animate() on both but they'll have different blend values. One will be blending in the other out. So you'll need a blend value for each animation and an active flag for each animation. Quote Link to comment Share on other sites More sharing options...
cassius Posted October 9, 2012 Author Share Posted October 9, 2012 Thanks Rick. Blending is another thing I don't fully understand. I have a value of 1 for all anims. There are never more than two anims at a time. Quote amd quad core 4 ghz / geforce 660 ti 2gb / win 10 Blender,gimp,silo2,ac3d,,audacity,Hexagon / using c++ Link to comment Share on other sites More sharing options...
Daimour Posted October 9, 2012 Share Posted October 9, 2012 Blending is another thing I don't fully understand. Blending means you can play 2 different animations simultaneously. Yes, they will be mixed. And you'll get something between them. But with "blending" parameter you can express one animation more then the second. So you can change "blending" from 0 to 1 through the time and your character will change one animation to the second seamlessly. Quote Link to comment Share on other sites More sharing options...
Rick Posted October 9, 2012 Share Posted October 9, 2012 The only thing I think you need to know about blending is that 1 will play the animation in full strength and 0 won't show the animation being played at all (even if you call Animate()). When you change animations from say idle to walk you don't want to fully just switch from idle to walk because it'll be choppy and look bad, instead you want to smoothly blend from idle to walk. The way you do this is by slowly decreasing the blend of idle from 1 to 0, and increasing the blend value of walk from 0 to 1. You need to call Animate() on both in the same frame to get this effect. This is why each animation needs it's own blend variable. It could also store it's own blend speed if you want to increase/decrease the blending of each animation at different rates. I'm not sure if you are using Josh's examples of animation but normally I, and some others I know, increase the frames ourselves with a timer. Just some pseudo type ideas void PlayAnimation(ActorAnimations anim, string animName) { // check to see if animName is already active and if so bail out of this function because we don't want to activate it twice // find the current active animation in anim and set it's blendMode value to BLEND_OUT, this active value should be true already // set it's currentFrame to startFrame, possibly some other init's // find the animName animation in anim and set it's blendMode value to BLEND_IN, and active to true selectedAnimation.lastTime = AppTime(); } void UpdateAnimation(ActorAnimations anim) { // loop through all animations of this actor foreach(a in anim) { // when we switch animations both will be active, until the blend out one is finished, then we'll set it's active to false if(a.active) { if(a.blendMode == BLEND_OUT) { // use a timer to increase a.blend value over multiple frames until it's >= 1 if(a.blend >= 1) a.blendMode = BLEND_NOTHING; } if(a.blendMode == BLEND_OUT) { // use a timer to decrease a.blend value over multiple frames until it's <= 0 // once we are fully blended out, deactivate this animation if(a.blend <= 0) a.active = false; // just resetting this variable, not 100% needed, but cleaner if(a.blend <= 0) a.blendMode = BLEND_NOTHING; } // animate if(AppTime() - a.lastTime > a.animationSpeed) { a.lastTime = AppTime(); a.frame++; if(a.frame > a.lastFrame) if(a.loop) a.frame = a.startFrame; else // maybe fire a callback function or something so we can handle 1 time animations and what to change to after it's finished } // something like this, can't remember param order Animate(a.model, a.frame, a.blend); } } } Quote Link to comment Share on other sites More sharing options...
cassius Posted October 9, 2012 Author Share Posted October 9, 2012 Got some good answers and learned a lot.Thanks to all Quote amd quad core 4 ghz / geforce 660 ti 2gb / win 10 Blender,gimp,silo2,ac3d,,audacity,Hexagon / using c++ Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.