Animations

You can get game characters to play specific animations from a larger database of different possible movements. To do this you can use the native function TASK_PLAY_ANIM. Script Hook V Dot Net is a wrapper for the C++ ScriptHook, calling the functions in Scripthook to do things in the game. However, there are some functions that are not in Script Hook V Dot Net or for other reasons you might want to use the native functions instead. In order to use these, you have to use the native calling from Script Hook.

Native functions are called with Function.Call followed by their corresponding hash name and parameters. They use this structure:

Function.Call(Hash.HASH_NAME, input_params);

The function TASK_PLAY_ANIM takes a lot of parameters (some of them still not exactly known), but here is the full function and a breakdown of each parameter.

Native.Function.Call(Native.Hash.TASK_PLAY_ANIM, Ped ped, string animDictionary, string animationName, float blendInSpeed, float blendOutSpeed, int duration, int flag, float playbackRate, BOOL lockX, BOOL lockY, BOOL lockZ);
  • ped The Ped that will play the animation
  • animDictionary The dictionary where the anim is located
  • animationName The animation name
  • blendInSpeed The play start speed (This is important to make smooth changes between animations)
  • blendOutSpeed
  • duration -1 is default, 0 doesn't play at all, a small value slows down the animation speed
  • flag Parameters that you can set for the playback:
    ANIM_FLAG_NORMAL = 0,
    ANIM_FLAG_REPEAT = 1,
    ANIM_FLAG_STOP_LAST_FRAME = 2,
    ANIM_FLAG_UPPERBODY = 16,
    ANIM_FLAG_ENABLE_PLAYER_CONTROL = 32,
    ANIM_FLAG_CANCELABLE = 120,
  • playbackRate values are between 0.0 and 1.0
  • lockX 0 in most cases 1 for "rcmepsilonism8" and "rcmpaparazzo_3", > 1 for "mini@sprunk"
  • lockY 0 in most cases, 1 for "missfam5_yoga", "missfra1mcs_2_crew_react"
  • lockZ 0 for single player, can be 1 but only for MP

You need to request the animation dictionary before starting using it in your script: use the function REQUEST_ANIM_DICT. After that, wait for the animation to load (or you could check if it’s loaded with the boolean HAS_ANIM_DICT_LOADED), before playing the animation.

Once you have requested your animation dictionary and it is loaded, you can play and stop the specific animation using TASK_PLAY_ANIM and STOP_ANIM_TASK.

//store the animation dictionary and the animation name in two strings
string animationDictionary = "mini@strip_club@pole_dance@pole_a_2_stage";
string animationName = "pole_a_2_stage";
//request animation dictionary
Function.Call(Hash.REQUEST_ANIM_DICT, animationDictionary);

//wait until animation is loaded
if (Function.Call<bool>(Hash.HAS_ANIM_DICT_LOADED, animationDictionary))
{
        Wait(100);
 }

//play animation once using the player character
Function.Call(Hash.TASK_PLAY_ANIM, Game.Player.Character, animationDictionary, animationName, 8.0, 8.0 * -1, -1, 0, 0, false, false, false);

if you want to stop the animation before it's over (or if it's looping) you can use the native function STOP_ANIM_TASK

//stop the animation
Function.Call(Hash.STOP_ANIM_TASK, Game.Player.Character, animationDictionary, animationName, 1.0);

There are more than 100,000 animations available in GTA V. You can see some of the possible animations in the game here. Here you can find a list of available dictionaries and animations.

Animations can be assigned to any entity: here is a deer tasked with a pole dance animation.

Example code
using System;
using System.Windows.Forms;
using GTA;
using GTA.Native;

namespace Animation
{
    public class Animation: Script
    {
        string animationDictionary = "mini@strip_club@pole_dance@pole_a_2_stage";
        string animationName = "pole_a_2_stage";

        public Animation()
        {
            this.KeyUp += onKeyUp;
        }

        private void onKeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.J) //press J
            {
                //request animation dictionary
                Function.Call(Hash.REQUEST_ANIM_DICT, animationDictionary);

                //wait until animation is loaded
                if (Function.Call<bool>(Hash.HAS_ANIM_DICT_LOADED, animationDictionary))
                {
                    Wait(100);
                }

                //play animation once using the player character
                Function.Call(Hash.TASK_PLAY_ANIM, Game.Player.Character, animationDictionary, animationName, 8.0, 8.0 * -1, -1, 0, 0, false, false, false);

            }

            if (e.KeyCode == Keys.K) //press K
            {
                Function.Call(Hash.STOP_ANIM_TASK, Game.Player.Character, animationDictionary, animationName, 1.0);
            }
        }
    }
}