Code viewer
Enhanced Play Animation
#Kismet
Custom Play Animation that works with the player!
This is a custom kismet node, based off the vanilla Play Animation with a few key differences:
- Animations can now be played on players and/or any controller references in kismet, as long as that controller has a pawn with a skeletal mesh.
- Animsets can now be added and removed at runtime, allowing for custom animations on players without the use of custom playables or restricted to just cutscenes.
- In the same tangent, this can also be used to override current animations, allowing for custom idles, walk cycles, jumps, etc, per map.
- The restart option now correctly restarts animations that play in the custom node of an AnimTree (which will be most of the time if using the original or this version of the node)
class Hat_SeqAct_EnhancedPlayAnimation extends SequenceAction; /* This custom kismet node is an upgraded version of the Play Animation node that exists in the editor. It allows for the addition of custom animations to a selected object, by adding a new Animset, and also the removal of them at runtime. This node also allows you to directly play animations onto the player and other controller controlled actors. UltraBoo 2024 */ var() Name Animation<ToolTip=The name of the animation to be played, located in a AnimSet.>; var() bool Loop<ToolTip=Should the animation loop?>; var() bool Restart<ToolTip=If this animation is already playing and this kismet node is triggered, the animation will restart to the beginning.>; var() float PlayRate<ToolTip=How fast the animation should play.>; var() float AnimationDuration<ToolTip=Overrides the animation duration. Only applies for animations in an AnimTree>; var() AnimSet CustomAnimSet<ToolTip="Play" adds a new AnimSet to the object, while "Stop" removes it. Even if no animation is played, this function will go, making this useful to temporarily override default animations that use the same name as the one in this AnimSet.>; static event int GetObjClassVersion() { return Super.GetObjClassVersion()+1; } defaultproperties { ObjName="Enhanced Play Animation" ObjCategory="Anim" //HandlerName="PlayAnimationAct" bCallHandler = false; Animation = "Idle" Loop = true; Restart = false; PlayRate = 1.0; AnimationDuration = 0.0; InputLinks(0)=(LinkDesc="Play") InputLinks(1)=(LinkDesc="Stop") } event Activated() { local Object t; foreach Targets(t) { if (Hat_NPC(t) != None) PlayAnimation(Hat_NPC(t).SkeletalMeshComponent, InputLinks[0].bHasImpulse); else if (SkeletalMeshActor(t) != None) PlayAnimation(SkeletalMeshActor(t).SkeletalMeshComponent, InputLinks[0].bHasImpulse); else if (Pawn(t) != None) PlayAnimation(Pawn(t).Mesh, InputLinks[0].bHasImpulse); else if (Controller(t).Pawn != None) PlayAnimation(Controller(t).Pawn.Mesh, InputLinks[0].bHasImpulse); } } function PlayAnimation(SkeletalMeshComponent c, bool IsPlay) { local float dur; local AnimNodeSlot slot; if(IsPlay && CustomAnimSet != none && c.AnimSets.Find(CustomAnimSet) == -1) { c.AnimSets.AddItem(CustomAnimSet); c.UpdateAnimations(); } else if(!IsPlay && CustomAnimSet != none && c.AnimSets.Find(CustomAnimSet) != -1) { c.AnimSets.RemoveItem(CustomAnimSet); c.UpdateAnimations(); } if (c.AnimTreeTemplate != None) { foreach c.AllAnimNodes(class'AnimNodeSlot', slot) { if (Animation == '' || !IsPlay) slot.StopCustomAnim(0.1); else { if(Restart) slot.StopCustomAnim(0); slot.PlayCustomAnim(Animation, PlayRate, 0.1, 0.1, Loop); } break; } return; } dur = 0.0; if (PlayRate > 0 && AnimationDuration > 0) dur = AnimationDuration / PlayRate; c.PlayAnim(Animation, dur, Loop, Restart); }