Revision Difference
custom_modeldoc_nodes#547889
<cat>Dev.Model</cat><title>Custom ModelDoc nodes</title>
<cat>Model.Nodes</cat><title>Custom ModelDoc nodes</title>
You can make a custom ModelDoc node. This is useful for any gamemode-specific data you want to attach to specific models.
These nodes are defined in C# code, and the FGD for these is automatically generated for you.
# Generic Game Data
1. Define a struct or class. Add the `ModelDoc.GameData` attribute.
```
/// <summary>
/// Spawn a particle when the model is used on an entity. Support for this depends on the entity.
/// </summary>
[ModelDoc.GameData( "particle", AllowMultiple = true )]
public class ModelParticle
{
[DisplayName( "Particle" ), ResourceType( "vpcf") ]
public string Name { get; set; }
[JsonPropertyName( "attachment_point" ), FGDType( "model_attachment" )]
public string AttachmentPoint { get; set; }
[JsonPropertyName( "attachment_type" )]
public ParticleAttachment AttachmentType { get; set; } = ParticleAttachment.AttachmentFollow;
[JsonPropertyName( "attachment_offset" )]
public Vector3 AttachmentOffset { get; set; }
}
```
2. Run your gamemode. The FGD for this node then gets auto-generated.
3. Assign the node in ModelDoc. If you don't know how to do that, you should probably read a ModelDoc guide like [this one](https://wiki.facepunch.com/sbox/Importing_a_new_model#thingsyouregoingtoneed).
4. Now you can use this data in code like so.
```
ModelParticle[] modelParticles = Model.GetData<ModelParticle[]>();
```
4a. or like so, which automatically checks of the data exists:
```
if ( Model.TryGetData( out ModelParticle[] modelParticles )
{
// Data exists on this model, use it..
}
```
# Break Commands
Break commands are a more specific alternative to GenericGameData which allows code to be ran when an entity with a model that has given node breaks via the <page>Breakables</page> class, such as doors, physics props and others.
They work identically to GenericGameData but the class markup looks a little different:
```
/// <summary>
/// Spawn a particle system when this model breaks.
/// </summary>
[Library( "break_create_particle" )]
public class ModelBreakParticle : IModelBreakCommand
{
/// <summary>
/// The particle to spawn when the model breaks.
/// </summary>
[JsonPropertyName( "name" ), ResourceType( "vpcf" )]
public string Particle { get; set; }
// ...
public void OnBreak( Sandbox.Breakables.Result res )
{
if ( !(res.Source is ModelEntity ent) ) return;
var part = Particles.Create( Particle, ent.Position );
// ...
}
}
```
The `OnBreak` callback will be called automatically when an entity breaks and has a model with (in this case) `break_create_particle` break command.
# Other things you can do with this
There are multiple attributes that you can use in order to make your own custom designers/helpers:
- `ModelDoc.Axis`
- `ModelDoc.Box`
- `ModelDoc.Sphere`
- `ModelDoc.Capsule`
- `ModelDoc.Cylinder`
- `ModelDoc.Line`
- `ModelDoc.HandPose`
- `ModelDoc.EditorWidget`