Tuesday, June 17, 2014

Setting up an AnimTree for your Custom Playable Character

  Many of those that are familiar with Unreal Engine and any type of modeling program may be familiar with AnimSets as you import skeletal meshes into your levels. For those that aren't familiar, AnimSets is basically a set of animations a skeletal mesh can have. So for example, let's say we have a character model where we have an animation that the character is walking, upon exporting the skeletal mesh with the animation to the game engine Unreal, we get two things; the skeletal mesh, and an AnimSet of that animation. Now AnimSets can be very useful, for one you don't have to constantly re import an AnimSet for each animation you make in a modeling program. You could actually just import a new animation inside the AnimSet which makes scripting and the manipulations of AnimTrees much easier. Two, if you ever wanted to you could make animations in real time for your game using these AnimSets in Unreal's Matinee or even use AnimSet's for Cutscenes. Now with this being said, one of the main things AnimSets are good for are that you can implement them in a AnimTree. So you may be asking what is an AnimTree. Well for those that may not be familiar with the term, AnimTree's can be seen as a hierarchy tree that consists of different kinds of animations. So for some programmers out there...When Scripting your own custom playable character, having an AnimTree is pretty important. Without an AnimTree, you won't really see animations of your character going on in real time, such as the players moving animation. So if you were to script a playable character for a level or your game without an AnimTree, your player would definitely be able to move but animations won't be playing which is pretty unappealing.  Recently from one of the courses I've been taking, I had to create an AnimTree for one of the projects I was working on with my group called GirderJump. Basically you play as a construction worker who so happens to need to use the bathroom badly that you start jumping over obstacles such as girders to get to a porter potty. For this short game, I had to create an AnimTree for our playable character so that when the player actually moves the character, we can see animations playing.

 To start this off, I begun by actually creating a new AnimTree calling it "charaAnimTree" in my own package. Upon opening up the AnimTree your given basically everything blank, which is good if you like to start things new. So when I first begun making AnimTree's which was a course ago before me taking GSP340, I was lost. I honestly did not know where to begin and I remember being confused on why my skeletal mesh wasn't appearing in the previewer window. So to fix this was actually easy, all you have to do is click your AnimTree node and in the properties panel theres a preview mesh list. All you have to do is hit the green plus and insert your skeletal mesh in "preview Skel Mesh". Now upon doing this you'll get your skeletal mesh in but now you also want the AnimTree to recognize your AnimSet that contains all sorts of animations for the model. So just like what I did with the skeletal mesh, I placed in my AnimSet which was actually right beneath Preview Mesh List called Preview AnimSet List > Preview AnimSet.

  Upon me doing this I could now view my skeletal mesh and be able to play animations from that AnimSet. Now as a programmer and person that enjoys making 3D models, when making animations for skeletal mesh you have to think...What kind of mesh is this going to be? A character? And if so is he a playable character or AI? Thinking of things like these really do help out the thought process because then we get to narrow down what exactly needs to be down. For instance, this skeletal mesh was actually the main playable character for my group project called GirderJump. So the kinds of animations we would be needing is a character walking animation for front, back, right, and left, jumping animation, double jump animation if applicable, and down animation. For my game, things were much more simple considering it was a platformer side scroller game. So considering the camera angle, the only movements for the character walking animation I needed were front and back. And honestly, we could use the same animations for front and back. For my game, we actually had double jumping being applicable so there had to be some distinguishing from when the player first jumps to when the player double jumps. 
  Now after acquiring all animations (being done in 3ds Max) I was able to get starting with the AnimTree. As you can see above, what I started off with was called AnimNodeBlendByPhysics which connected the out UV from the AnimTree to the In UV of the new node. So to first explain things, any kind of model, whether its a static mesh or skeletal mesh can have physics apply to it. We can have walking physics, falling physics, interpolating which many game developers use when messing with matinee, and many more types. The AnimNodeBlendByPhysics which I got from right clicking anywhere in the grey area New Animation Node > BlendBy> AnimNodeBlendByPhysics basically has a set of physics that can be manipulated with your skeletal mesh. So for instance, in the PHYS_Walking UV we could put animations in for the character walking. So when actually playing the game, when the player were to move the physics would be set to walking. If the character jump, the character would have PHYS_Falling. So after having the AnimNodeBlendByPhysics I created a node called UTAnimBlendByIdle which I got from New Animation Node > BlendBy > UTAnimBlendByIdle, which is a node that blends with the state Idle and any type of moving state. So essentially we could connect a Idle state in the Idle UV which is when the player is staying still and add animations to the moving state, so when the player moves. Before going any further I made sure though to connect the PHYS_Walking UV with the input UTAnimBlendByIdle UV and then I created two things; an Animation Node sequence and a AnimNodeBlendDirection. The Animation Node sequence is where we will have our animations in. With our AnimSet in the AnimTree, we could easily call the name of the Animation we have inside the AnimSet in the Animation Node Sequence allowing the animation to work. The AnimNodeBlendDirection is pretty cool, with this node we can have movement in all directions being three hundred sixty degrees. So you'll have UV's for foward, backward, left and right. First, to get the Animation Node Sequence, I went to Animation Sequence > Animation Node Sequence. In the properties for this Node I name the Anim Seq Name to Idle and connected its input to the output to UTAnimBlendByIdle Idle output. So now we have our character in it's stationary state. Then I went to New Animation Node > Directional > AnimNodeBlendDirection and connected the input to the moving output of UTAnimBlendByIdle. After doing that I created two more Animation Node Sequence which are going to be placed in the foward and backward UV of the AnimNodeBlendDirection Node. Due to placing the AnimSet in our AnimTree we can literally just call our animation in the Anim Seq Name and the animation will go in. So for me, the animation for the character walking was charaWalk. Thus completing the character PHYS_Walking.


 
  Now for the project I was working on called GirderJump, we had jumping and double jumping being involved. So in total we were looking at three animations. So we know we will need three Anim Node Sequence. So what I did was create three Anim Node Sequence and name them the animations for jump, double jump and fall which were "charaJump", "charaDoubleJump", and "charaFall". After doing this I created something similar to UTAnimBlendByIdle but for PHYS_Falling which is called UTAnimBlendByFall and I got this from New Animation Node > BlendBy < UTAnimBlendByFall. With UTAnimBlendByFall we have a set of physics for falling, being jump, double jump, down, pre land, land ect. So we can take into account many animations for when the player is in the air. For my game, we only needed to take into account three. With the UTAnimBlendByFall input, I connected it to the output of PHYS_Falling and connected the charaJump node sequence to the UV of up, the charaDoubleJump node sequence to the UV of DoubleJump Up, and the charaFall node sequence to the UV's of  Down, PreLand, Double Jump Down, and Double Jump PreLand. Doing this completed the PHYS_Falling. So now the character can walk and fall.


  After doing this I had a few things left and the character was done. For one, I had to go to all Animation Node Sequence and in the properties panel I had to check off Playing and Looping and now we're down with the AnimTree.
  To actually implement the AnimTree in my game I had to place it into script along with the AnimSets. For this, it could be easily done in a few lines of four unreal classes; GirderJumpGame, GirderJumpPawn, GirderJumpFamilyInfo_Worker, and GirderJumpPlayerReplicationInfo. In my GirderJumpFamilyInfo_Worker I extended from UTFamilyInfo_Liandria_Male and in the DefaultPropeties I added the AnimSet that contains all animations of the character.


AnimSets(0)=AnimSet'GirderJumpModels.Walk'

In GiderJumpPlayerReplicationInfo I extended from UTPlayerReplicationInfo and in the DefaultProperties I added

CharClassInfo=class'GirderJumpGame.GirderJumpFamilyInfo_Worker'

which by doing that we now have all info from family worker, and we can now put replication info into the default properties of the game type.

Continuing this, I went into my GameType which was called GirderJump Game, and in the Default Properties, I added in

DefaultPawnClass=class'GirderJumpGame.GirderJumpPawn'
PlayerReplicationInfoClass=class'GirderJumpGame.GirderJumpPlayerReplicationInfo'

which takes into account now, my pawn class, and family info class.

Now we have mostly everything but we're missing one thing, which is the initialization for the character and the AnimTree. This, was simple. All I had to do was in the DefaultProperties of my pawn class;GiderJumpPawn. I added in these three lines:

  Begin Object Name=WPawnSkeletalMeshComponent
         AnimTreeTemplate=AnimTree'GirderJumpModels.charaAnimTree'
   End Object

What I did was create an object by the name of WPawnSkeletalMeshComponent and inside this object I initialize the AnimTree for the character. Thus doing this allows for my character animations to work in real time when playing.






No comments:

Post a Comment