ShiVa Character Animation
From ShiVa Wiki
- It is a good idea to design the actual model and the animations separately, and also have each animation sequence separate. That means, do not do one big timeline strip with all animations from walking to shooting to jumping, but do a clip for each type of animation individually.
- Only bones animations are supported.
- The model needs to be one single object, do not try to animate groups. have a look at this tutorial if you want to learn more.
- You will probably need some sort of model/animation converter, especially if you are working with tools like blender. Look around the wiki, we recommend the ultimate unwrap converter for the really hard cases, but the Autodesk FBX converter might also be worth a look if you do not want to spend any money, but the results vary depending of the quality of the model you feed it.
Import into ShiVa
Model (UU3D workflow)
- 1. All rigging and skinning must be done in your favourite DCC tool, then export it (obj, fbx or dae are recommended).
- 2. Open the model up in Ultimate Unwrap Pro (if you don't have it in dae format already, nevertheless, it might be a good idea)
- 3. Make sure that the skeleton is showing. Delete all grouped items and any un-assigned bones (these are the empty gray squares under the bones section).
- 4. Export (Save As) the model as a collada file using the format MODELNAME_mesh_and_bones.dae
- 5. Import model into shiva (import->model). "Meshes" and "Materials" should be checked and, depending on your 3d modeller, "convert Z to Y". the scale might also be important to consider. 1 shiva grid unit is considered a meter in real life.
- 6. the materials will be possibly way off. Don't be alarmed, your next step is to go into the materials editor and open up all the materials associated with that model. You will notice that all of them will say OBJECT_VisualMaterialXX where XX is the number of the material. You simply go through each material one at a time and setup the lighting and textures and keep saving. It may seem like a lot of work, but this method works perfectly (and you only have to do it once, just make sure you dont overwrite the materials when you re-import the model or you will have to do it again).
Animation (UU3D workflow)
- 1. all animation should be done in your favourite dcc tool. yes, shiva supports basic animation editing through its animClip editor, but manipulating dozens of bones that usually come with a character model is an unsurmountable task inside shiva. don't try.
- 2. remember to do every animation in a different clip. export your animations using a format that supports animations, like fbx, dae or even directX model.
- 3. Open the model up in Ultimate Unwrap Pro, Make sure that the skeleton is showing. Delete all grouped items and any un-assigned bones (these are the empty gray squares under the bones section).
- 4. test your animation by selecting the menu (Animation->Play) and make sure it is running the same way you made it.
- 5. Export (Save As) the model as a collada file using the format anim_MODELNAME_ANIMATION-NAME.dae
- 6. Import AnimClip into shiva. make sure the scale values and Z to Y are the same as for the model-only import.
- 7. Click and drag the newly created animclip to your mesh in the scene and it will ask you to create an animbank if you haven't already created one - hit yes. If you already have an animbank, it will just add it to the list of animations in another position.
- 1. ShiVa animation mixing/scripting works a little like an audio track mixer. A music audio mixer (mixing console) is a device that allows a person to change the volume of various sound samples so that they can blend in various tracks at a time. Think of it like a DJ mixing 2 different songs together in a party or club. If you increase one channel to full volume, the other channel has no sound and you hear song 1 for example. If you increase another channel to full volume, and decrease the other ones, then that specific song will play full and loud. If you keep the music channels in middle volume, it will MIX the two songs and the songs will play at the SAME TIME. you must understand this basic concept in order to work with shiva's animation system.
- 2. If you put a fader to full and everything else to zero, only that specific fader will play music.
The ShiVa animation system
- 1. First, before you begin, you must bring in various animations in SINGLE format into the Shiva3D environment. This means that if you have all animations loaded into a SINGLE model file, you will have to break apart each animation into its various lower parts (run, walk, jump, etc. would all have to be INDIVIDUALLY created). If you have followed the tutorial above, you already have done so and the following will give you no issues.
- 2. Once you have each SINGLE animation in as an animClip, you will then have to click and drag any of the animation clips onto your character in the scene viewer that you wish to have as the first animation. If its the first time doing this, Shiva will ask you to create an animBank, hit YES and create a new animBank for the object.
- 3. Click and drag all the other animClips into the newly created animBank (Go to the animBank editor in another window so you can easily click and drag from the data explorer to the animBank) and as you do so, you will notice, that Shiva adds a NUMBER infront of each animation. this index number is very important, you will use those numbers to refer to each animation by script.
- 4. Add an AI controller to your object/character if you have not already done so. add two functions to the ai model: setupAnimations () and updateAnimations ().
- 5. Now save your scene and animBank and let's get into the setupAnimations () function code. Before you can have any animations running, you need to first load an animation into a specific mixing channel. We do this by using the animation.changeClip command:
animation.changeClip ( hObject, nBlendLayer, nClipIndex)
The hObject is the object which has the animBank you want to work with. The nBlendLayer is the animation channel (Like a music channel) that we are going to use. NOTE: there are only 8 channels available. if you need more, you have to dynamically remove unused clips form channels and replace them with you new ones. The nClipIndex is the specific index number in the animBank of that object
animation.changeClip (hGameScorpionObject, 1, 0)
The above example says to Shiva, load the FIRST animation channel (technically 0 is the first channel, but for this example we are using 1 so that the reader does not get confused) with animClip 0 which is attached to the hGameScorpionObject's animBank.
So now in channel 1 we have this animation locked in place ready to be used.
- 6. Next, let's fine-tune the animation itself. the API commands animation.setPlaybackKeyFrameBegin () and animation.setPlaybackKeyFrameEnd () commands will determin how much of the animation will be played, using animation.getClipKeyFrameRangeMin () and animation.getClipKeyFrameRangeMax () as helpers.
animation.setPlaybackKeyFrameBegin ( hObject, nBlendLayer, nKeyFrame ) animation.setPlaybackKeyFrameEnd ( hObject, nBlendLayer, nKeyFrame ) animation.getClipKeyFrameRangeMin ( hObject, nClipIndex ) animation.getClipKeyFrameRangeMax ( hObject, nClipIndex )
animation.setPlaybackKeyFrameBegin ( hGameScorpionObject, 1, animation.getClipKeyFrameRangeMin ( hGameScorpionObject, 0 ) ) animation.setPlaybackKeyFrameEnd ( hGameScorpionObject, 1, animation.getClipKeyFrameRangeMax ( hGameScorpionObject, 0 ) )
"The starting frame that I want the FIRST animation (animation clip 0) to start at is whatever Shiva finds is the BEGINNING FRAME of this animation." In this case, the beginning frame is 0. We could have alternatively also started the animation at frame 20 by doing the following:
animation.setPlaybackKeyFrameBegin ( hGameScorpionObject, 1, 20 )
In the previous example, we also said to Shiva, "The ending frame that I want the FIRST animation to END at (animation clip 0) is whatever Shiva finds is the ENDING FRAME of this animation." Similarly to Example 3 above, we could also set this frame manually if you know what it is as in the following example:
animation.setPlaybackKeyFrameEnd ( hGameScorpionObject, 1, 200 )
In most cases as you get many animations and objects, it becomes impractical to remember the final frames as you are changing animations or updating constantly so it is better to let Shiva figure out the frames and save you time in updating code rather than going to figure out exact frame numbers yourself.
Now we are going to create a second animation using a second clip and using the following code:
animation.changeClip (hGameScorpionObject, 2, 1) animation.setPlaybackKeyFrameBegin ( hGameScorpionObject, 2, animation.getClipKeyFrameRangeMin ( hGameScorpionObject, 1 ) ) animation.setPlaybackKeyFrameEnd ( hGameScorpionObject, 2, animation.getClipKeyFrameRangeMax ( hGameScorpionObject, 1 ) )
You just told Shiva to -> Place the second animation that is in the hGameScorpionObject's animBank (animClip 1) in the second animation channel (nBlendLayer 2) and make the animClip start at the beginning frame of the animation Clip and end at the final frame of the animation Clip.
Now we move from the setupAnimations() function to the updateAnimations() function. Here we are going to update on every frame (onEnterFrame handler in your AI model needs a call to this function, or it will not work).
Here we simply set the PLAYBACK level of the channels using the animation.setPlaybackLevel() command. The way it works is as follows:
animation.setPlaybackLevel ( hGameScorpionObject, 1, 0.5 ) animation.setPlaybackLevel ( hGameScorpionObject, 2, 0.5 )
What you are saying to Shiva is that you want Shiva to adjust the Animation Faders (Same concept as Mixer Faders in Audio, check the notes above to understand) to HALF strength each. This will MIX the 2 animations into 1 combined animation where both animations will play together. If I however just want the FIRST animation to play and not the second, I would do this:
animation.setPlaybackLevel ( hGameScorpionObject, 1, 1 ) animation.setPlaybackLevel ( hGameScorpionObject, 2, 0 )
In the above I now told Shiva that I want the Animation Fader for the first animation to be at FULL (Think of full volume in a mixer board) and the Animation Fader for the second animation to be off. This will play only the first animation in FULL.
The issue and confusion that comes in here is that when you are running an animation, usually you want to nicely have a FADE IN/FADE OUT from one animation to the other one. In order to do this, you need to have a variable for each fader (BlendLayer) that will be the "VOLUME" level.
Example: Let's say I want to play from animation 1 in the first animation channel and blend in to animation 2 from the second animation channel, well then I would have to slowly move the fader from the the first channel "down in volume" and the fader on the second channel "up in volume".
In the code I could accomplish something using variables:
animation.setPlaybackLevel ( hGameScorpionObject, 1, nCh1Volume ) animation.setPlaybackLevel ( hGameScorpionObject, 2, nCh2Volume )
where nCh1Volume and nCh2Volume are a maximum of 1.0 and a minimum of 0.0.
I could start out in my setupAnimations() and set the two channels as variables to 1.0 for nCh1Volume and 0.0 for nCh2Volume. Then I could do the following:
nCh1Volume = nCh1Volume - 0.1 nCh2Volume = nCh2Volume + 0.1
Put it all into IF statements to make sure that these values do not go below 0 or above 1.
Blending 2 animations without mixing unused channels
This method is useful for instance if you have an animation for the upper part of a character's body, but want fully independent control over the walking animation in the legs and hips.
this is possible if
- your legs AnimClip has to contain only legs joints tracks
- your body AnimClip has to contain only body joints tracks
- you have to turn on this option on both blending layers:
So that's it for animations, look at the provided examples in Shiva to learn how to do more advanced stuff, specifically look at the iPhone Character Control example in the Shiva samples. You will see all the code you need, but the concept is the hardest part to understand, however once you get it, it is VERY powerful and very useful :)
user gamescorpion and NiCoX