$bodygroup: Difference between revisions
m (Put it in the "B" letter of the QC Commands category content list.) |
(Removing deprecated Category) |
||
(22 intermediate revisions by 13 users not shown) | |||
Line 1: | Line 1: | ||
{{ | {{LanguageBar|title = $bodygroup}}{{tabsBar|main=gs|base=$bodygroup}} | ||
| | {{this is a|QC command|name=$bodygroup}} It defines a group of meshes that can be turned on or off, or changed entirely. Server code can change their state. | ||
}} | {{toc-right}} | ||
{{note| | {{note|Body groups '''cannot''' change [[skeleton|skeletons]] or [[collision model|collision models]].}} | ||
== Example == | == Example == | ||
This body group allows a weapon to have iron sights, laser sights, or no sights at all: | |||
<source lang=php> | <source lang=php> | ||
$bodygroup sights | $bodygroup sights | ||
{ | { | ||
studio "ironsights | studio "ironsights" | ||
studio "laser_dot | studio "laser_dot" | ||
blank | blank | ||
} | } | ||
</source> | </source> | ||
This | This body group defines the entire chest region of the model, which spans multiple bones: | ||
<source lang=php> | <source lang=php> | ||
$bodygroup chest | $bodygroup chest | ||
{ | { | ||
studio "chest_with_no_armor | studio "chest_with_no_armor" | ||
studio "chest_with_light_armor | studio "chest_with_light_armor" | ||
studio "chest_with_heavy_armor | studio "chest_with_heavy_armor" | ||
studio "chest_with_super_armor | studio "chest_with_super_armor" | ||
} | } | ||
</source> | </source> | ||
{{note|Since body group polygons never share vertices with the base mesh in Source models, there need not be seams between properly-made components.}} | |||
== Bodygroups in Level of Detail Meshes == | |||
Using [[LOD|Level of Detail]] meshes - ''especially for high-poly geometry'' - is '''highly recommended'''. Body groups can be used in <code>[[$lod]]</code> strings in the same method as normal geometry meshes: | |||
{{ | <source lang=php> | ||
$lod 12 | |||
{ | |||
replacemodel "chest_with_no_armor" "chest_with_no_armor_lod1" | |||
replacemodel "chest_with_light_armor" "chest_with_light_armor_lod1" | |||
replacemodel "chest_with_heavy_armor" "chest_with_heavy_armor_lod1" | |||
replacemodel "chest_with_super_armor" "chest_with_super_armor_lod1" | |||
} | |||
$lod 18 | |||
{ | |||
replacemodel "chest_with_no_armor" "chest_with_no_armor_lod2" | |||
replacemodel "chest_with_light_armor" "chest_with_light_armor_lod2" | |||
replacemodel "chest_with_heavy_armor" "chest_with_heavy_armor_lod2" | |||
replacemodel "chest_with_super_armor" "chest_with_super_armor_lod2" | |||
} | |||
$shadowlod | |||
{ | |||
replacemodel "chest_with_no_armor" "chest_with_no_armor_lod2" | |||
replacemodel "chest_with_light_armor" "chest_with_light_armor_lod2" | |||
replacemodel "chest_with_heavy_armor" "chest_with_heavy_armor_lod2" | |||
replacemodel "chest_with_super_armor" "chest_with_super_armor_lod2" | |||
} | |||
</source> | |||
== Programming == | == Programming == | ||
Line 38: | Line 66: | ||
<source lang=cpp> | <source lang=cpp> | ||
int BodyGroup_Sights = FindBodygroupByName("sights"); // calculate this value once | |||
SetBodygroup( BodyGroup_Sights , 1 ); // laser dot | SetBodygroup( BodyGroup_Sights , 1 ); // laser dot | ||
</source> | </source> | ||
Line 46: | Line 74: | ||
To calculate how many combinations you need, multiply the size of all your bodygroups together. The examples on this page total 3 * 4 = 12...but add two more groups the same size and you're up at 144. The figure grows exponentially. | To calculate how many combinations you need, multiply the size of all your bodygroups together. The examples on this page total 3 * 4 = 12...but add two more groups the same size and you're up at 144. The figure grows exponentially. | ||
[[ | ==Switching bodygroup via $Sequence== | ||
It is possible to swap bodygroups during [[$sequence|sequences]], using the following event: | |||
* AE_CL_BODYGROUP_SET_VALUE <frame> "<bodyGroupName> <body>" {{note|So far only tested in {{l4d2}} and {{tf2}}. ''Seems'' to be fine but certain functions in the game can restart it to default making it somewhat "buggy".}} | |||
* AE_CL_ENABLE_BODYGROUP <frame> "<bodyGroupName>" | |||
* AE_CL_DISABLE_BODYGROUP <frame> "<bodyGroupName>" | |||
Examples: | |||
$bodygroup "travel" | |||
{ | |||
studio "delorean_Notravel" | |||
studio "Delorean_Yestravel" | |||
studio "Delorean_brokentravel" | |||
} | |||
$sequence "charger_escape_b" { | |||
"racecar_anims/charger_escape_b" | |||
{ event '''AE_CL_BODYGROUP_SET_VALUE 0 "travel 0"''' } // On frame 0 Sets model to show body 0 (first variant) of the "Travel" Bodygroup. Being "delorean_Notravel.smd" | |||
{ event '''AE_CL_BODYGROUP_SET_VALUE 50 "travel 1"''' } // On frame 50 Sets model to show body 1 of the same bodygroup. Being "Delorean_Yestravel.smd" | |||
{ event '''AE_CL_BODYGROUP_SET_VALUE 220 "travel 2"''' } // On frame 220 Sets model to show body 2 of the same bodygroup. Being "Delorean_brokentravel" | |||
} | |||
$bodygroup "Bodygroup_1" | |||
{ | |||
blank // Disabled state | |||
studio "myBodyGroup" // Enabled state | |||
} | |||
$sequence "Sequence_1" { | |||
"anims/Thing_1" | |||
{ event '''AE_CL_ENABLE_BODYGROUP 10 "Bodygroup_1"''' } // On Frame 10 Enables bodygroup_1 | |||
} | |||
$sequence "Sequence_2" { | |||
"anims/Thing_2" | |||
{ event '''AE_CL_DISABLE_BODYGROUP 50 "Bodygroup_1"''' } // On Frame 50 Disables bodygroup_1 | |||
} |
Latest revision as of 21:09, 16 July 2025
$bodygroup
is a QC command available in all Source games. It defines a group of meshes that can be turned on or off, or changed entirely. Server code can change their state.

Example
This body group allows a weapon to have iron sights, laser sights, or no sights at all:
$bodygroup sights
{
studio "ironsights"
studio "laser_dot"
blank
}
This body group defines the entire chest region of the model, which spans multiple bones:
$bodygroup chest
{
studio "chest_with_no_armor"
studio "chest_with_light_armor"
studio "chest_with_heavy_armor"
studio "chest_with_super_armor"
}

Bodygroups in Level of Detail Meshes
Using Level of Detail meshes - especially for high-poly geometry - is highly recommended. Body groups can be used in $lod
strings in the same method as normal geometry meshes:
$lod 12
{
replacemodel "chest_with_no_armor" "chest_with_no_armor_lod1"
replacemodel "chest_with_light_armor" "chest_with_light_armor_lod1"
replacemodel "chest_with_heavy_armor" "chest_with_heavy_armor_lod1"
replacemodel "chest_with_super_armor" "chest_with_super_armor_lod1"
}
$lod 18
{
replacemodel "chest_with_no_armor" "chest_with_no_armor_lod2"
replacemodel "chest_with_light_armor" "chest_with_light_armor_lod2"
replacemodel "chest_with_heavy_armor" "chest_with_heavy_armor_lod2"
replacemodel "chest_with_super_armor" "chest_with_super_armor_lod2"
}
$shadowlod
{
replacemodel "chest_with_no_armor" "chest_with_no_armor_lod2"
replacemodel "chest_with_light_armor" "chest_with_light_armor_lod2"
replacemodel "chest_with_heavy_armor" "chest_with_heavy_armor_lod2"
replacemodel "chest_with_super_armor" "chest_with_super_armor_lod2"
}
Programming
To change a body group's state:
int BodyGroup_Sights = FindBodygroupByName("sights"); // calculate this value once
SetBodygroup( BodyGroup_Sights , 1 ); // laser dot
By default, CBaseAnimating
supports 4,294,967,296 combinations (32 bits), and CBaseViewModel
supports 256 (8 bits). You can raise either of these by editing the relevant SendProp for m_nBody
.
To calculate how many combinations you need, multiply the size of all your bodygroups together. The examples on this page total 3 * 4 = 12...but add two more groups the same size and you're up at 144. The figure grows exponentially.
Switching bodygroup via $Sequence
It is possible to swap bodygroups during sequences, using the following event:
- AE_CL_BODYGROUP_SET_VALUE <frame> "<bodyGroupName> <body>"
- AE_CL_ENABLE_BODYGROUP <frame> "<bodyGroupName>"
- AE_CL_DISABLE_BODYGROUP <frame> "<bodyGroupName>"
Examples:
$bodygroup "travel" { studio "delorean_Notravel" studio "Delorean_Yestravel" studio "Delorean_brokentravel" } $sequence "charger_escape_b" { "racecar_anims/charger_escape_b" { event AE_CL_BODYGROUP_SET_VALUE 0 "travel 0" } // On frame 0 Sets model to show body 0 (first variant) of the "Travel" Bodygroup. Being "delorean_Notravel.smd" { event AE_CL_BODYGROUP_SET_VALUE 50 "travel 1" } // On frame 50 Sets model to show body 1 of the same bodygroup. Being "Delorean_Yestravel.smd" { event AE_CL_BODYGROUP_SET_VALUE 220 "travel 2" } // On frame 220 Sets model to show body 2 of the same bodygroup. Being "Delorean_brokentravel" }
$bodygroup "Bodygroup_1" { blank // Disabled state studio "myBodyGroup" // Enabled state } $sequence "Sequence_1" { "anims/Thing_1" { event AE_CL_ENABLE_BODYGROUP 10 "Bodygroup_1" } // On Frame 10 Enables bodygroup_1 } $sequence "Sequence_2" { "anims/Thing_2" { event AE_CL_DISABLE_BODYGROUP 50 "Bodygroup_1" } // On Frame 50 Disables bodygroup_1 }