
Originally Posted by
Alex D
I've been wondering that myself lately. The player model for my mod does different animations depending on the weapon in use so doing it through UnrealScript isn't really that flexible and requires added code for each new weapon. Having an animnode for it would simplify the matter so much but I've not managed to figure out how to make a my own animnodes as the stock animnodes are almost completely native. Any help would be very appreciated.
Let me outline a simple example then. Since it is something I've done before and it is relevant to your interests, a node that has different branches for different weapons, with the active branch determined by the pawn's current weapon.
Firstly, the node itself:
Code:
class MyAnimBlendByWeaponType extends UTAnimBlendBase;
enum MyWeaponAnimType {
WAT_None,
WAT_Sword,
WAT_Mace,
WAT_Boomerang,
WAT_HandCrossbow,
WAT_Crossbow,
WAT_Bow,
WAT_Musket
};
var() Array<MyWeaponAnimType> WeaponTypeForSlot;
simulated function SetWeaponAnimType(MyWeaponAnimType weapAnimType) {
local int i;
for (i = 0; i < WeaponTypeForSlot.length; i++) {
if (WeaponTypeForSlot[i] == weapAnimType) {
SetActiveChild(i, BlendTime);
break;
}
}
if (i >= WeaponTypeForSlot.length) {
SetActiveChild(0, BlendTime);
}
}
DefaultProperties
{
Children(0)=(Name="Default")
WeaponTypeForSlot(0)=-1
}
So this node is a subclass of UTAnimBlendBase, which is a node that can have a number of children, and the active child can be programmatically set. The children can be created and assigned to a weapon type in the AnimTree editor.
But at this point it doesn't do anything, as nothing will be calling the node to set the weapon type.
Next I created a pawn subclass like so:
Code:
class MyAnimPawn extends UTPawn;
var array<MyAnimBlendByWeaponType> WeaponTypeAnimNodes;
simulated event PostInitAnimTree(SkeletalMeshComponent SkelComp)
{
local MyAnimBlendByWeaponType BlendByWeaponType;
super.PostInitAnimTree(SkelComp);
if (SkelComp == Mesh)
{
foreach mesh.AllAnimNodes(class'MyAnimBlendByWeaponType', BlendByWeaponType) {
WeaponTypeAnimNodes[WeaponTypeAnimNodes.Length] = BlendByWeaponType;
}
}
}
simulated function SetWeaponAnimType(MyWeaponAnimType weapAnimType) {
local int i;
for (i = 0; i < WeaponTypeAnimNodes.length; i++) {
WeaponTypeAnimNodes[i].SetWeaponAnimType(weapAnimType);
}
}
In the PostInitAnimTree function I get out a list of all the MyAnimBlendByWeaponType nodes. This means you can have as many as you want in the tree, the code will be able to find and update all of them when the held weapon changes.
Finally all my Weapons use custom WeaponAttachment classes for the third-person display mesh, which inherit from a UTWeaponAttachment subclass that looks like
Code:
class MyWeaponAttachment extends UTWeaponAttachment;
var MyWeaponAnimType WeaponAnimType;
simulated function AttachTo(UTPawn OwnerPawn) {
local MyAnimPawn AnimPawn;
super.AttachTo(OwnerPawn);
AnimPawn= MyAnimPawn(OwnerPawn);
if (AnimPawn != none) {
AnimPawn.SetWeaponAnimType(WeaponAnimType);
}
}
With each subclass setting the WeaponAnimType in its default properties. I set the pawn's weapon type from here because the WeaponAttachment class is already replicated and I can depend on the weapon type always matching the weapon the pawn is displayed as using on the client.
And that is pretty much that. I have a variety of other custom nodes, but they all work in a similar way - the pawn gets out a list of those nodes and calls a function on them to activate them or change their behaviour when necessary.
Bookmarks