Static helper that maps animation clip names to measured ground speeds in units/sec for zombie locomotion. It provides For(clip,tier) which returns a specific speed if known or a tier median fallback.
using System.Collections.Generic;
namespace NZombies;
/// <summary>
/// GENERATED by Tools/gen_ground_speeds.py - do not hand-edit.
///
/// How fast each locomotion clip actually carries the zombie, in units/sec,
/// measured from the source SMDs as (horizontal root travel / duration).
///
/// ⚠️ THIS is a zombie's movement speed - not the round curve. The original
/// derives speed from the playing animation (GetSequenceGroundSpeed, moo:454)
/// and uses the round number only to pick which tier of animation to play
/// (nz_zombie_walker_derriese:772 + its Threshold table). That is why a round-1
/// zombie still shambles forward at ~46 u/s even though its curve value is 0.
///
/// s&box has no ground-speed accessor - SkinnedModelRenderer.SequenceAccessor
/// exposes Duration/Time/PlaybackRate and nothing about root motion - so the
/// values are measured offline and baked in here.
/// </summary>
public static class WalkerGroundSpeeds
{
/// <summary>Ground speed for a clip, falling back to the tier median.</summary>
public static float For( string clip, string tier )
{
if ( clip is not null && Speeds.TryGetValue( clip, out var s ) ) return s;
return tier switch
{
"Walk" => 46f,
"Run" => 93f,
"Sprint" => 153f,
"SuperSprint" => 222f,
_ => 40f,
};
}
public static readonly Dictionary<string, float> Speeds = new()
{
["a_nz_run_ad11"] = 68.5f,
["a_nz_run_ad14"] = 121.1f,
["a_nz_run_ad2"] = 108.3f,
["a_nz_run_ad21"] = 87.0f,
["a_nz_run_ad8"] = 57.5f,
["a_nz_run_au1"] = 120.2f,
["a_nz_run_au2"] = 108.3f,
["a_nz_run_au20"] = 86.4f,
["a_nz_run_au21"] = 104.4f,
["a_nz_run_au23"] = 92.5f,
["a_nz_run_au4"] = 94.4f,
["a_nz_run_au5"] = 70.4f,
["a_nz_sprint_ad21"] = 170.7f,
["a_nz_sprint_ad22"] = 164.5f,
["a_nz_sprint_ad24"] = 172.3f,
["a_nz_sprint_ad3"] = 147.6f,
["a_nz_sprint_ad4"] = 144.2f,
["a_nz_sprint_ad5"] = 157.0f,
["a_nz_sprint_au3"] = 149.1f,
["a_nz_sprint_au4"] = 144.2f,
["a_nz_supersprint_ad10"] = 224.4f,
["a_nz_supersprint_ad12"] = 197.1f,
["a_nz_supersprint_ad13"] = 218.1f,
["a_nz_supersprint_ad3"] = 210.7f,
["a_nz_supersprint_ad4"] = 234.4f,
["a_nz_supersprint_ad5"] = 233.4f,
["a_nz_supersprint_ad6"] = 223.7f,
["a_nz_supersprint_au12"] = 230.7f,
["a_nz_supersprint_au3"] = 212.9f,
["a_nz_supersprint_au4"] = 220.9f,
["a_nz_walk_ad1"] = 37.6f,
["a_nz_walk_ad20"] = 45.9f,
["a_nz_walk_ad22"] = 46.5f,
["a_nz_walk_ad23"] = 43.7f,
["a_nz_walk_ad24"] = 37.2f,
["a_nz_walk_ad25"] = 47.6f,
["a_nz_walk_ad3"] = 37.5f,
["a_nz_walk_ad7"] = 52.9f,
["a_nz_walk_au1"] = 37.6f,
["a_nz_walk_au12"] = 35.2f,
["a_nz_walk_au20"] = 60.1f,
["a_nz_walk_au21"] = 46.9f,
["a_nz_walk_au3"] = 37.5f,
["a_nz_walk_au7"] = 51.9f,
["a_nz_walk_au8"] = 50.6f,
};
}