How to animated models with collision to Skyrim from 3ds max


7 posts in this topic

Posted (edited)

Important! This is still a WIP. Example 1 is recorded, but I need a microhpone. Example 2 has not been started yet. The images are also rough. It should be possible to understand everything from this, but remember it is still not done! I post this now so those interested can start trying to get it to work, and so I can get feedback on which part is unclear or difficult to do!

Software used:

3ds max 2012 for animation - UPDATE; We can do it without 2012! 

3ds max 2014 for collision

Nifskope 2

Creation Kit

________________________________________________________________________________________________________________________________

In this tutorial we will try to create a simple animated object with collision. We'll be using 3ds max 2012 for the animation and 3ds max 2014 with the 2013 plugin for the collision. With that in mind, it is possible to not use 3ds max 2014 if you can get your collision working any other way, and you don't even need any 3d software; as you can animate in nifskope itself. If you are able to get animations to nifskope and collisions working, then your software of choice is irrelevant. I will try to highlight areas that is prone to crash, so you are aware of issues. All right! Let's get started! 

 

*Intro - why, what and how?*

yes, yes. I can hear you say it: "What on earth am I talking about? Animated models with collision? But Skyrim uses havok physics!". You are indeed correct! Bethesda started using Havok Physics and Havok Animation for their animations and collision in Skyrim. However, you will notice this transaction was done sometimes in the middle of development! There are plenty of models using the legacy gamebryo animation setup, whereas all animations in the DLCs are pure Havok. This means that we can still use gamebryo animations! If you are a tech wiz and know some C++, you can cook up some amazing things with Havok Physics as well!

Anyways. The workflow here is generally straight forward. I'll give you the rough rundown before we go into a few examples:

 

*Animation Setup in 3ds max 2012*

1) We set up an animations in 3ds max 2012. This can be as complex as you want; it doesn't matter. The only thing you might want to care about is the time. 100 frames equals to 3.333(repeating). 25 frames equal to 0.8333. As you can see, 25/0.8333 = 30.0 and 100/3.333 = 30.0. This means 30 frames equals  roughly 1 second. I tell you this because changing the time inside of Nifskope can be tricky on complex animations. You'd have to multiply every set keyframe with the desired increase or decrease. So if you got a complex animation spanning 50 different keys times 25 different animated objects, you got a lot of work ahead of you. This isn't as big of a problem on simple animation. If the animation goes from point A to point B, you can increase and decrease the animation by simply editing the timer on the last key.

2) We add a bone in the scene. We make sure the rotations are all at 0, the scales are all at 100% and the position is at 0.0.0. We then link all the animated meshes to the bone. That's it for the animations! As noted before, you can do the animation purely in nifskope, and if you can get working animations into nifskope with Blender(or any other software), then you can continue!

3) We export the animation using  these settings. The important thing to note is that we export with animation and not with manager. The latter simply doesn't work. We'll need to set that up manually. The goal is to get each animated model within its own NiNode containing the NiTriShape and the animation.

4) We set up the NiControllerManager and link up each of the animated object and the animations. We set it up to a keyword. At this point it's also possible to copy the sequence we made and revert the animation on another keyword. Very useful for lifts and the like!  This tutorial goes in-depth in how to set it up!

 

EDIT: We can do this in 3ds max 2014 as well, making this a lot more accessible! When using 3ds max 2014, there is no need to add the bone. Simply export with animation. Now go into NiTransformInterpolator --> NiTransformData on each of the animated object. If there is no rotation in your animation, make Num Rotation Keys = 0. Then check the Translations and Scales. If any of the Interpolations is set to random numbers, change them to QUADRATIC_KEY. This is what's causing the crash!

 

*Collision*

5) We import the same nif into 3ds max 2014, create the collision models(as simple as possible), center the pivot of the collision meshes and add a bhkrigidbodymodifier set to Stone and AnimStatic. The type depends on the model. If you reset the Xform before exporting the main nif, then you can export out any of the collisions. If you forgot, then you can only use Packed Strips Shape(Which is the most complex of the bunch). That is because the packed strips shape exports using the current transformations, while all the others does not. If you try to reset the xform on the collision, but did not do it on the nif itself, the collision will most likely be bigger than the nif. I have yet to test this throughout, but I can tell you this: On the Ayleid stairs I used both Axis Aligned Box and Packed Strips Shape without a problem. On the collapsing bridge I could not use the Axis Aligned Box, and was limited to Packed Strips Shape. So, reset the Xform people! It saves annoying collision misalignment! 

* Image of the modifier, if you haven't seen it before *

6) We export using these settings:  The goal here is simply to get the collision out. I recommend you use Nifskope 2 since it allows you to see the collision by pressing the "bouncing ball" icon on the toolbar! Do note that you can only export 1 collision out at a time. That means you generally set up the static collision as a single Packed Strips, then you save out one for each animated object in the scene.

7) We change the collision settings and set up some flags around the nif. Do note that many bad collision setting will crash the game and the CK. A simple trick is to copy the bhkCollisionObject node from any animated nif from bethesda that used bhkRigidBodyT, then delete the shape(node underneath the bhkRigidBodyT). Then simply add the shape of your collision. I'll go through both methods later!

8) We add it in the CK as a movable static, put it in-game and we enjoy it :) Now we can add a quick script to play the animation, or we can loop it. The function we use is called "reference.PlayGamebryoAnimation("keyword"). I also add a ("keyword", 0.1). You'll find out why!

 

*Examples of working animations*

Here are some examples of this in motion. Take second to notice the issue the game got when moving the play up or down. That's an engine problem, sadly.

1) Lift

2) Ayleid stairs

3) Collapsing bridge

4) Castle Gate - https://gyazo.com/d0ec40c794e0f045d4f5f9e39aed22d0

This is how a working animation with collision works in nifskope. Notice the Block List and notice. The green is the collision.

And finally, this is the same animation inside of 3ds max. 

*What next?*

So. Now that you know the rough recipe, I will take my leave! ... no, not really. We'll run through two examples here. I will provide images and once I find the microphone splitter for my Kraken headset - I will provide video with commentary. Our first example will be a medieval gate opening and closing. A single animation and a single collision. Then we will make something with multiple animations. The latter I won't go into too many details; I will provide a timelapse of me doing it without commentary and we'll go through it. The first I will take very slowly and we will get it right! I will provide both nifs so you can take a look. I will not spend much time on modeling and texturing. Generally you'd want to do the animation after the modeling part is done. 

 

 

Example 1: Medieval Castle Gate

 

*The Animation*

All right! Including the video, here is a written tutorial on how to do this! I will go in depth into everything but the NiControllerManager, as that is well documented in the aforementioned tutorial. I will however go through the settings I change very quickly. All right? All right!

This is our scene. The texture is just a placeholder so we got something other than a black mesh to look at! 

zcMw6hn.png

First we want to animate something. I am not going to go into how you do it. Mostly because I am not an expect on animations, but also because that's now what this tutorial is about! The animation done is a very simple one; it opens and it closes. Two sequences set to two keywords. 

All right. You got it animated? Sweet. Next up we need to create a bone(Create -> Systems --> Bones) and set it to 0,0,0 with no rotation or scaling. Then we want to select all our animated meshes and link them to the bone. 

MtiCNJx.jpg

 

Finally we export the whole scene as "nif with animation".  Use these settings. When you open the nif, using Nifskope 2, it will be invisible. So copy a BSLightingShader node from any other nif and link your textures (I expect you know how to do that if you are attempting this). It should now be visible.

0QA3gs4.png

You should now be able to play the animation in Nifskope. It should look like this:

3QYOctA.png

We got a few things we want to do right now. We want to organize the nif and set up the NiControllerManager. Let's worrya bout the collision after we got the animation working! The first thing to do is to set the BSXFlags to "139". Then we want to group up static and animated objects into NiNodes.(This is optional for Static, but 100% required for animated objects). I know this can be confusing when you look at your nif. Yes, you are suppose to put the NiNode animated objects into a secondary NiNode. Otherwise the collision will not fit correctly later. I create 2 NiNodes called "Anim" and "Static." Then go into the BSFadeNode, scroll down the block details for "Children" and change the current ones for the 2 NiNodes created. Then I fill up the niNodes with the respective NiNodes/NiTriShapes. So, for the static I got "NiNode(Static) --> NiTriShape(StaticMesh)" and for anim I got "NiNode(Anim)" --> NiNode(AnimMesh1) --> NiTriShape(AnimMesh1:2)". And lastly the new NiNodes needs to have their flag changed from "0" to "14" (Under Block Details). Make sure the BsFadeNode is still at 0. Otherwise CTRL + ArrowUp until it is. It should look like this: 

*Note*: A NiNode is  a grouping node. It doesn't affect anything directly, and will not cause any crashes. It does increase the file size by ever so little. It's also absolutely required to get the animation to fit unless you animate with the pivot at 0.0.0. This is because of how the collision works; It will base its local coordinates from a source. This source will be the root bone unless there is an additional NiNode in between. 

9Xuvu5W.png

It might not seem like a big deal to order the nif when there is only 2 objects. But trust me; When you got over 20 different meshes in a single nif, where only certain are animated, it's very well worth the time to  both sort them into NiNodes, but also get them named and ordered. This will save you time once we start working on the NiControllerManager. 

As I mentioned earlier, for the manager use http://forums.nexusmods.com/index.php?/topic/984792-tutorial-working-with-the-nicontrollermanager/ . It goes into everything you need to know. I will not cover it. I will, however, give you some tips:

1) Have things ordered. 

2) When setting up multiple animatons, you might end up having to set up hundreds of objects in the NiDefaultAVObjectPalette. Try to figure out the number difference between nodes. For instance, look at this image. Notice the pattern? 97 - 102 - 106 - 111. it increases by 5 each time. That way I was able to set up 34 objects in no time. The same thing goes for the Sequence when setting up the Controller blocks. Find out the difference from the NiNode to the Interpolator, then from the Interpolator to the next NiNode. Some basic math and you'll save yourself a lot of time.

3) if you want to edit the time on any of the sequence, you'll need to change a few things. First you must change the end time of the NiTextKeyExtraData. You most likely need to -1 the keys and add them back again to update it. Then you need to update the timer on the NiControllerSequence. Finally you must edit the animation itself, which is found within the NiControllerSequence(NiTransformInterpolator is the name of the animations). If you got a simple animations it's very quick. If you got a very big one, it might not be a bad idea to do the animation in 3ds max, then just update the interpolators.

4) Animate within Nifskope is not difficult, but it's very tedious. You can edit and add new NiTransformInterpolators. Under NiTransformData is where you'll do the animations. You can rotate, move and scale the animations. Just set up different keys, and give them values. Each key translate to a keyframe. 

5) You need a NiTextKeyExtraData node for the keyword! That's how you will call the animation from a script. I will give examples of 2 scripts so you can quickly test them out. 

6) You can copy wole sequences and link them up to the manager. Just rename the sequence. I did this to have both "open" and "close" sequences. For simple animation you can revert your animation within nifskope itself, but I opted for a simple reverted animation within 3ds max and exported it. Then link up the NiTransformInterpolators to the Controller Blocks within the  NiControllerSequence.

Now that the animation is in order, we want to test things out. First try to get the nif into the creation kit --> Movable static. If nothing crashes, yay! otherwise it's time for some debugging. I'll list some common issues:

- Having multiple BSLightingShaderProperty on a single NiTriShape.

- Under the NiTransformData the "Rotation Type" is set to something not viable. It should be XYZ_ROTATION_KEY or QUADRATIC_KEY and not random numbers.

- You have linked something wrong somewhere. Just look through every place you have linked something and see what's up. Refer to vanilla animated nifs, or the ones I provide.

 

Now that you got it working and nothing crashes, we will need to actually play the animation somehow. Genrally you'd want to use an activator or a triggerbox. Here are very simple animations on both:

*Via activator*

1) Double click your new animated model in the render window and give it a reference ID. I ran with MAT85CastleGateAnimRef. Copy it.

2) Find any activator. I ran with the lever. Add it near your animated nif, double click it and go to "scripts". Add a new script. This is my script:

Scriptname MAT85TutExample1GateScript extends objectreference

Objectreference property MAT85Ex1GateRef auto

Bool property Activated = true auto

Event OnActivate(ObjectReference akActionRef)

	If Activated == True
		MAT85Ex1GateRef.PlayGamebryoAnimation("open", 1.0)
		utility.wait(2)
		Activated = False

	elseIf Activated == False
		MAT85Ex1GateRef.PlayGamebryoAnimation("close", 1.0)
		utility.wait(3)
		Activated = true
	endif
	
EndEvent

if you got a single animation, you could get by with a simple:

scriptname -YourScriptName- extends objectreference

Objectreference property -TheAnimatedNifRef- auto


Event OnActivate(ObjectReference akActionRef)

		TheAnimatedNifRef.PlayGamebryoAnimation("Sequencekeyword", 1.0)

	
EndEvent

Make sure you then click on the same script and fill the properties!

Test it in-game!

*Via Triggerbox*

1) Double click your new animated model in the render window and give it a reference ID. I ran with MAT85CastleGateAnimRef. Copy it.

2) Click on your animated model in the render window. Then click on the "T" at the Toolbar in the CK. I then use "DefaultActivateSelfTRIG". Alter the size to fit the zone you want, and place it.

Scriptname -YourScriptName- extends Objectreference

objectreference property -AnimatedModelReference- auto


Event OnTriggerEnter(ObjectReference akActionRef)

	-AnimatedModelReference-.PlayGamebryoAnimation("start", 1.0)

EndEvent

Once you walk into that zone(This only works for the player), the animation will play. if you set up a bool to be true and false, as in with the activator, then it will switch between the animations as you walk in and out of the zone.

 

*The collision* 

Phew. So far so good! We now got a working animation in-game that is triggered by either an activator or by walking into a triggerzone. Not bad! now comes the tricky part. if you get the wrong settings on the collision; shit crashes. If you do things a bit wrong on export, the collision won't fit. If you don't do it right, the collision won't animate. Very annoying stuff! In this example I got 2 meshes that needs a collision. For the static mesh I used Packed Strips Shape, as it conforms the collision perfectly to the mesh. This is the most complex collision, and also the one taking the most performance to use. I recommend using it on complex shapes, but try to avoid using it if other options works. For the animated object I used the AxisAlignedBox, since the gate itself would be outlined as a box. Let's go through it quickly:

1) Import your animated nif (IMPORTANT!). 

2) Pivot to 0.0.0 and reset Xform.

3) Add new models for new collision, or just use the base model as a collision.

4) add the bhkrigidbody modifier to the collision meshes. 

5) Set the material to stone, the type to whatever fits best and the Layer to whatever you are working on (Static, AnimStatic, Weapon, Clutter, etc). We will change the material inside of Nifskope, and the layer style we can change as well if we picked the wrong one.

U5fG4rW.png

6) export using these settings  one at a time:

Nwc3jQS.png

7) Here we got some choices. If you got multiple statics, you should've put them into a NiNode earlier. You can then just paste in the static collision and link it up by clicking on the NiNode and scrolling down to "Collision Object". https://gyazo.com/fc45454bbf8f820f551f81493d8a98b0 . Do the same for the animation objects, but make sure you link the collision to the NiNode containing the NiTriShape!

7,a) Now that we got a bhkCollisionObject set up, there is a few settings we must change. Let's go from the top:

bhkCollisionObject --> Set flag to 137 (from 129) for animated objects. For statics keep it at 129. Then make sure the target is the NiNode the collision is linked. 

bhkRigidBodyT --> Make sure the SkyrimLayer are set to whatever you are working on. This means Static for statics and AnimStatic for animations. Then change the following values:

 Then go into the shape of the collision (Whatever is under bhkRigidBodyT) and set SkyrimMaterial to whatever you want(This is for sound) and finally, if you used Packed Strips Collision, set the target to the NiNode you are under.

You now got everything working!

7,b ) Instead of dealing with all these settings, you can do a little trick of copy and pasting the collision from an existing model which uses the bhkRigidBodyT and then simply adding your shape in. So, open up any model with said collision (like the ones I got). Click on the bhkCollisionObject and -1 the "target". Then expand down to bhkRigidBodyT and -1 the "Shape". Now copy and paste this into every animated NiNode you got, and link each one up by changing the "target" to the NiNode. Finally copy and paste the shape(underneath the bhkrigidbodyT) of your own collision and add it to the respective bhkRigidBodyT. Viola! You just copied all the settings and saves a lot of work!

* note: I recommend making a preset nif for animations and collision. An empty nif with a bhkCollisionObject without a shape for both static and animated objects, and a NiControllerManager setup for reference.

Xqg0WpS.png

 

Example 2: ???

*??*

N/A

 

*And we're done!*

Test in-game now. Everything should work just fine! You can now add more sequences, edit the model or whatever you want. The only really annoying thing is if you need to scale the meshes up, as the collision does not scale inside of Nifskope(I am at least 50% certain of this!)

 

Example1 - Castle Gate Nif - Download

Edited by Matth85
8 people like this

Share this post


Link to post
Share on other sites

Posted

This is awesome work Matth, thanks for sharing!

Share this post


Link to post
Share on other sites

Posted

Hope you can find some use for it!
Oh, and big news! I found the issue regarding max 2014 not doing animations. It was simply the Interpolation keys being fucked up! They were set to random numbers. If one manually changes them to QUADRATIC_KEY , the animations work fine!

This means we can remove the whole bone-thing and 2012 from this. Sweet!

3 people like this

Share this post


Link to post
Share on other sites

Posted

This means we can have more varied traps and better scenes :) 

1 person likes this

Share this post


Link to post
Share on other sites

Posted (edited)

Managed to animate it, but the file now crashes the game and creation kit. seems like everything is fine in the model too.

Edited by TFCGWolf
Figured the tutorial out without the images.

Share this post


Link to post
Share on other sites

Posted

Hi guy's,

Thank for the tutorial and i was wondering if this could work for a custom tree since it has always bother me to see that there was no trunk flexibility to make the trees gently swaying in the wind.

I already made a looping animation for my tree that span over 300 frames to get some decent variations and i don't know if performance could be an issue with a completely independent rig from vanilla?

I did some test and so far i cannot make my custom tree with 54 bones to work with the tutorial here : https://www.darkcreations.org/forums/topic/4249-100-custom-tree-pyandonean-islands-tuto02/?page=2

Today i am going to replicate the exact bones rig they did for vanilla trees and see if it work since i suspect that they just grab a bunch of branches and skin them to specific bones.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now