Armes personnalisées

L'éditeur d'armes (Créer → Armes) crée des armes à balles, de corps à corps, des lance-projectiles et des grenades. Tu importes ton modèle 3D, ou un viewmodel complet avec ses bras et ses animations, puis tu règles le tir, la précision, le recul, les munitions, la visée, les effets et les sons. Les animations humanoïdes en 3e personne (Mixamo, Unreal…) sont adaptées automatiquement au personnage du jeu.

En jeu

ToucheAction
Clic gaucheTirer, frapper ; grenade : dégoupiller en maintenant, lancer en relâchant
Clic droit (maintenu)Viser (zoom, lunette) ; grenade : lancer bas
RRecharger (chargeur ou balle par balle)
BChanger de mode de tir (coup par coup, rafale, automatique)
TInspecter l'arme
1 à 6Emplacement : chaque arme a le sien ; appuyer à nouveau passe à l'arme suivante du même emplacement

Les armes des addons sont dans l'onglet Armes du menu de spawn (le gamemode décide avec GM:PlayerGiveWeapon). Comme les armes du jeu, le tireur voit son tir tout de suite et le serveur vérifie chaque coup : arme possédée, cadence, munitions et visée. C'est aussi le serveur qui calcule les dégâts et la trajectoire des projectiles.

Créer une arme

  1. Créer → Armes → Nouveau pack, avec le type de la première arme : arme à balles, corps à corps, lance-projectiles ou grenade. Un pack d'armes est un addon local, publiable sur le Workshop.
  2. Un pack, plusieurs armes : la liste à gauche de l'éditeur montre les armes du pack. Nouveau en ajoute une, Dupliquer copie celle sélectionnée avec ses réglages (pratique pour une variante), Supprimer la retire (son fichier part à la corbeille à l'enregistrement). Le nom se change dans les réglages ; à son premier enregistrement, un nouvel élément prend un fichier à son nom (weapons/fusil_2.json).
  3. Importer le modèle… (glTF, GLB ou FBX) : il sert pour la 3e personne, l'icône et, en mode « arme seule », la vue 1re personne. La poignée doit être à l'origine et le canon pointer vers -Z. Sinon, corrige dans Modèles (rotation, décalage, échelle ; un modèle exporté en centimètres est mis à l'échelle tout seul).
  4. Dans la vue Modèle, place les repères : bouche du canon (orange), éjection des douilles (jaune) et poignée avant (vert, où se pose la main gauche). La main transparente montre la prise en main.
  5. Choisis la vue 1re personne (voir plus bas) et associe les animations dans Animations. Le bouton ▶ montre chaque animation dans la vue.
  6. Règle le tir, la précision, les munitions, la visée et les sons. La fiche à gauche donne les dégâts par seconde, les coups pour tuer et le temps pour vider le chargeur.
  7. Tester : une partie solo démarre avec l'arme en main et des cibles alignées devant toi. Quitter la partie ramène dans l'éditeur. Prends la miniature avec Photo Workshop, puis Publier….

Vue 1re personne

ModeCe qu'il fautAnimations
Arme seule + bras du jeuLe modèle de l'arme. Les mains du jeu la tiennent, et la main gauche se pose sur la poignée avant si l'arme se tient à deux mains.Les mouvements du jeu (recul, rechargement, coup, sprint). Les animations du modèle (culasse, chargeur…) peuvent s'y ajouter.
Arme + bras du jeu animablesLe modèle de l'arme. Les bras du jeu (avec leurs doigts) la tiennent comme le fusil du jeu, à taille réelle, et suivent par IK.Les tiennes, faites dans l'éditeur d'animation : sortie, rangement, rechargement, inspection… Sans animation, les mouvements du jeu.
Viewmodel completUn fichier avec les bras et l'arme sur un squelette, caméra à l'origine, regard vers -Z. La bouche et les douilles suivent un os ou une pièce au choix.Les tiennes : sortie, repos, tir, rechargement…

Règle la position dans Modèles (position, rotation et échelle dans la vue) en regardant la vue 1re personne. La position en visée se règle avec le curseur Visée de la barre du haut : les organes de visée doivent être au centre de l'écran.

Animations

Les animations du modèle (ou du viewmodel) sont proposées d'office. Importer des animations… ajoute d'autres fichiers .glb ou .fbx animés sur le même squelette : un fichier par animation, ou plusieurs dans un seul fichier. Les pistes sont rattachées par nom d'os et de pièce. Chaque emplacement a sa vitesse de lecture ; le rechargement est calé sur la durée réglée dans Munitions. Sans viewmodel (le jeu tient le modèle lui-même), un clip prévu pour des bras qui déplace toute l'arme par son os de tête (accroché à la main) n'en garde que les pièces : chargeur, culasse, détente… L'arme reste à la place réglée dans l'onglet Modèles.

Emplacements 1re personneSi elle manque
Repos, Repos (chargeur vide), Marche, SprintRepos (sprint : l'arme est baissée par le jeu)
Sortie, Première sortie, Rangement, Inspection (T)Sortie
Tir, Dernier tir, Tir à videTir (sinon le recul du jeu)
Rechargement, Rechargement à videRechargement (sinon l'arme descend hors de l'écran)
Balle par balle : début, insertion (une par balle), finLe mouvement du jeu
Visée : entrée, sortie, repos, tirRepos et tir
Coup, Coup qui touche (corps à corps)Le coup du jeu
Dégoupiller, Lancer (grenade), Changement de mode (B)—

Éditeur d'animation (bras du jeu)

En mode Arme + bras du jeu animables (onglet Modèles), l'onglet Animations liste les emplacements 1re personne avec Créer / Modifier. Créer part d'un mouvement type à ajuster : l'arme qui monte pour la sortie, qui descend pour le rangement, qui pivote pour l'inspection, la main gauche qui va chercher un chargeur pour le rechargement. L'édition ouvre une timeline sous la vue 1re personne.

On n'anime pas les os un par un : on place quelques éléments et les bras suivent par IK (épaule, coude, poignet).

LigneCe qu'elle anime
ArmePosition et rotation de l'arme, depuis sa place de repos (la poignée).
Main droite / Main gaucheLe poignet, dans l'espace de l'arme : la main suit l'arme quand elle bouge. Au repos, la droite tient la poignée et la gauche la poignée avant (onglet Modèles).
Coude droit / Coude gaucheVers où pointe le coude (position, depuis sa place de repos).
Doigts droits / Doigts gauchesPliage de l'index, du majeur, de l'annulaire, de l'auriculaire et du pouce (0 tendu, 1 plié), et écartement. Poses toutes prêtes : tenue, doigt sur la détente, soutien, main ouverte, détendue, pince, poing, index tendu ; puis réglage fin doigt par doigt.
PiècesAnimer une pièce du modèle… : un objet ou un os du modèle (chargeur, culasse, levier…). Position et rotation depuis sa place, et tenue par l'arme, la main gauche ou la main droite : un chargeur retiré suit la main jusqu'à la clé où il revient à l'arme.
ÉvénementsVoir ci-dessous.

Dans la vue, un point de couleur marque chaque élément : blanc l'arme, orange la main droite, vert la main gauche, bleu les coudes, jaune les pièces. Clique sur un point, ou directement sur le modèle (l'arme, une main, une pièce animée), et glisse : l'élément suit la souris (dans le plan de l'écran). Un point sous la souris passe avant les flèches du manipulateur. Le manipulateur de l'élément choisi permet aussi de le déplacer sur un axe ou de le tourner.

Plusieurs à la fois : Maj ou Ctrl + clic sur des points, sur le modèle ou sur des lignes de la timeline les ajoute à la sélection ou les en retire (sans attraper le manipulateur), Ctrl+A les prend tous. Glisser l'un d'eux déplace tout le groupe ; le manipulateur se place au centre du groupe et le tourne autour de ce centre (chaque élément tourne aussi sur lui-même, les coudes ne font que suivre). Une clé est posée sur chaque ligne du groupe. Échap ne garde que l'élément affiché dans le panneau de droite.

Faire une clé : place la tête de lecture (règle en haut de la timeline, glisser), puis bouge l'élément dans la vue. Une clé est créée à cet instant s'il n'y en a pas. Le panneau de droite règle la clé choisie : instant, valeurs exactes, et la transition vers la clé suivante (linéaire, douce, accélère, ralentit, saut). Dans la timeline : clic sur une ligne pour la choisir, clic sur une clé pour la choisir, glisser pour la déplacer dans le temps, double clic pour une clé, clic droit pour la supprimer.

Caméra : au départ, on voit par les yeux du joueur, l'image cadrée sur les bras dans la partie de l'écran laissée libre par les panneaux et la timeline. Clic droit + glisser fait tourner la caméra autour des bras, clic molette + glisser la déplace, la molette zoome : la case Vue libre se coche toute seule. En vue libre, le clic gauche dans le vide tourne aussi la caméra et F la recadre sur les bras. Décoche Vue libre pour revenir à la vue du joueur.

ToucheAction
EspaceLire / pause (case Boucle pour rejouer)
KClé ici sur la ligne choisie
SupprSupprimer la clé ou l'événement choisi
W / EManipulateur : déplacer / tourner (Ctrl : par crans)
← →Image par image (1/30 s)
Maj / Ctrl + clic, Ctrl+AAjouter un point à la sélection, tout sélectionner (Échap : un seul)
Ctrl+C / Ctrl+VCopier la clé / la coller à la tête de lecture (même ligne)

Événements

ÉvénementEffet
SonJoue un son du jeu ou de l'addon (Importer un son…) chez le joueur qui tient l'arme.
Munitions rechargéesInstant où le chargeur est plein (rechargement et rechargement à vide). Annuler avant (changer d'arme) : pas de munitions ; après : elles sont gardées. On ne peut pas tirer avant la fin de l'animation. Sans cet événement : à la fin.
Douille éjectée, Flash, FuméeUne douille par la fenêtre d'éjection, le flash de la bouche, une bouffée de fumée à la bouche.
Événement LuaHook client WeaponAnimEvent(ply, id, nom) (voir Hooks).

Le rangement se joue avant de changer d'arme : l'arme suivante sort une fois l'animation finie. Les animations sont calées comme les autres : le rechargement dure le temps réglé dans Munitions. La visée, le recul, le balancement et la marche restent ceux du jeu. Pas encore de 3e personne : les autres voient la pose du jeu ou tes animations humanoïdes.

Prise des mains au repos (même onglet) corrige où les mains tiennent ce modèle quand rien ne les anime : position (m) et rotation (°) de chaque main, la gauche depuis la poignée avant.

Dans le JSON, les animations sont sous "fp_anims" (un clip par emplacement), en mètres et degrés :

"view_mode": "rig",
"fp_anims": {
	"reload": {
		"length": 1.8,
		"tracks": {
			"weapon": [{"t": 0, "pos": [0, 0, 0], "rot": [0, 0, 0], "ease": "inout"}, {"t": 0.3, "pos": [-0.02, -0.03, 0.02], "rot": [5, 5, 30], "ease": "inout"}],
			"hand_l": [{"t": 0.45, "pos": [0, -0.18, 0.12], "rot": [0, 0, 0], "ease": "inout"}],
			"fingers_l": [{"t": 0.45, "f": [0.55, 0.35, 0.6, 0.7, 0.6, 0], "ease": "inout"}],
			"part:node:Chargeur": [{"t": 0.4, "pos": [0, 0, 0], "rot": [0, 0, 0], "attach": "hand_l", "ease": "step"}]
		},
		"events": [{"t": 0.3, "type": "sound", "value": "mon_arme/chargeur_out.ogg"}, {"t": 1.1, "type": "ammo", "value": ""}]
	}
}

3e personne

Ce que les autres voient. La pose du jeu (pistolet, fusil d'assaut, fusil à pompe, mêlée, une main ou deux mains générique) sert par défaut. Importe des animations humanoïdes (Mixamo, Unreal, profil humanoïde de Godot, Rigify…) pour la tenue, le tir, le rechargement, la sortie, le coup et le lancer. Le jeu reconnaît les os par leur nom et adapte les mouvements au personnage, même si la pose de repos diffère (T-pose ou A-pose). Seuls les bras, les mains et les doigts sont repris : les jambes continuent de suivre la marche. Avec Main gauche sur la poignée avant, la main gauche reste sur la poignée pour les armes à deux mains.

Réglages

OngletContenu
ArmeNom, catégorie du menu de spawn, type, emplacement (1 à 6), vitesse de déplacement en main, viseur (celui du jeu, point, croix, cercle qui suit la dispersion, aucun).
TirModes (coup par coup, rafale de N balles avec sa cadence, automatique), cadence, dégâts par balle, plombs, portée et baisse des dégâts avec la distance, multiplicateurs tête et jambes, pénétration (les balles traversent les murs fins et les props jusqu'à une épaisseur, en perdant des dégâts), poussée sur les props. Corps à corps : délai avant l'impact et largeur du coup. Projectile : vitesse, gravité, durée de vie, effet à l'impact (explose, se plante, touche). Grenade : explosive, fumigène ou flash, retard, cuisson (le retard court dès qu'on dégoupille), vitesses de lancer, rebond.
PrécisionDispersion à la hanche et en visée, en courant, en sautant et accroupi ; dispersion ajoutée à chaque tir (avec un maximum et un retour). Recul vertical et horizontal, retour après la rafale, recul en visée, secousse de la caméra. Motif de recul : un décalage par tir, qui remplace le recul aléatoire (bouton Générer pour un motif typique de fusil d'assaut).
MunitionsChargeur, balle chambrée (+1), réserve donnée, munitions par tir, infinies. Type de munition : les armes du même type (ex. 9mm) partagent la réserve. Rechargement par chargeur (durée normale et à vide) ou balle par balle (tirer l'interrompt).
ViséePosition et rotation en visée, zoom, temps pour viser, vitesse et sensibilité en visée. Lunette : une image plein écran (réticule du jeu ou image importée, transparente là où on voit à travers) avec son propre zoom.
Effets & sonsFlash (taille, couleur), douilles éjectées, traceurs (un tous les N tirs), traînée et lumière des projectiles. Un son par action : tir, tir à vide, réarmement après le tir (pompe, culasse), rechargement, insertion, sortie, visée, coups, dégoupillage, lancer, rebond, explosion. Les sons sont ceux du jeu ou importés (ogg, wav, mp3).
ExplosionsLes dégâts baissent du centre au bord du rayon et ne passent pas à travers les murs. Le tireur peut se blesser lui-même ; les autres joueurs seulement si les dégâts entre joueurs sont activés sur le serveur. Les props sont projetés et la caméra tremble près de l'explosion.

Fichiers d'une arme

mon_arme/
├── addon.json
├── preview.png              miniature du Workshop
├── weapons/
│   ├── weapon.json          réglages de la première arme (WeaponConfig)
│   ├── fusil_2.json         une autre arme du pack
│   ├── mon_arme.glb         modèle (FBX et glTF sont convertis en .glb)
│   ├── viewmodel.glb        viewmodel complet (facultatif)
│   ├── recharge.glb         animations importées
│   └── lunette.png          image de lunette (facultatif)
└── sound/mon_arme/          sons importés

Id de l'arme : addon:<clé de l'addon>/weapons/weapon.json (affiché dans l'onglet Arme de l'éditeur). Chaque fichier JSON de weapons/ est une arme (addon:<clé>/weapons/fusil_2.json…), modifiable dans le même éditeur. Les chemins du JSON sont relatifs à son dossier. Les animations y sont notées "fichier.glb::Clip", avec un nom de fichier vide pour le modèle lui-même.

{
	"name": "Fusil d'assaut", "category": "Armes", "kind": "bullet", "slot": 4,
	"model": "fusil.glb", "muzzle": [0, 0.06, -0.45],
	"fire_modes": ["auto", "semi"], "rpm": 700, "damage": 22, "magazine": 30, "reserve": 120, "ammo_type": "5.56",
	"recoil_up": 0.9, "recoil_pattern": [[0, 1], [0.1, 1.1], [-0.2, 1]],
	"fp_clips": {"fire": "::Fire", "reload": "anims.glb::Reload"},
	"tp_pose": "rifle", "tp_files": ["mixamo_rifle.glb"], "tp_clips": {"reload": "mixamo_rifle.glb::mixamo.com"},
	"sounds": {"fire": "physicore/weapons/rifle_fire.wav", "reload": "mon_arme/recharge.ogg"}
}

En Lua

Pour écrire une arme entièrement en Lua (SWEP, avec SWEP.Base qui peut reprendre une arme de cet éditeur), jeter des armes au sol ou créer des outils de toolgun, voir Armes et outils en Lua.

FonctionCôtéRôle
ply:Give(id) / ply:StripWeapon(id)serveurDonne ou retire une arme (celles du jeu ou un id d'addon). La redonner remplit le chargeur et la réserve.
ply:GetActiveWeapon()partagéId de l'arme en main.
ply:GetAmmo(type)partagéRéserve d'un type de munition ("9mm") ou d'une arme sans type (son id). Côté client : seulement pour LocalPlayer().
ply:SetAmmo(nombre, type) / ply:GiveAmmo(nombre, type)serveurChange la réserve.
ply:RemoveAllAmmo() / ply:StripAmmo()serveurVide toutes les réserves (armes du jeu, de l'éditeur et Lua) ; les chargeurs restent.
ply:GetClip(id)partagéBalles dans le chargeur d'une arme personnalisée.
weapons.GetList()partagéArmes des addons : {id, name, category, slot, kind}.
weapons.Get(id)partagéTous les réglages d'une arme (table, mêmes noms que le JSON).
weapons.IsCustom(id)partagéEst-ce une arme d'addon disponible ici ?
weapons.Override(id, table)serveurChange des réglages pour tout le monde pendant la partie (ex. {damage = 40}). Remis à zéro au changement de map.
weapons.ResetOverride(id)serveurRevient aux réglages du fichier.

Hooks

Hook (serveur)ArgumentsRetour
PlayerFireWeaponply, idfalse annule le tir, le coup ou le lancer (armes personnalisées)
PlayerReloadply, idfalse empêche le rechargement
WeaponExplosionpos, rayon, attaquant, id— (après les dégâts d'une explosion)
WeaponAnimEvent (client)ply, id, nom— (un « Événement Lua » de l'éditeur d'animation, chez le joueur qui tient l'arme)
-- Pas de lance-roquettes pendant la trêve, et des munitions à chaque apparition.
local ROQUETTE = "addon:local_mon_lance_roquettes/weapons/weapon.json"

hook.Add("PlayerFireWeapon", "treve", function(ply, id)
	if id == ROQUETTE and GetGlobalBool("treve") then
		ply:ChatPrint("Trêve : pas de roquettes.")
		return false
	end
end)

hook.Add("PlayerSpawn", "munitions", function(ply)
	ply:Give(ROQUETTE)
	ply:GiveAmmo(60, "9mm")
end)

-- Mode « gros calibre » : toutes les armes d'addon font deux fois plus mal.
for _, w in ipairs(weapons.GetList()) do
	weapons.Override(w.id, {damage = weapons.Get(w.id).damage * 2})
end

Pour charger les modèles des armes en avance (écran de préchargement), util.GetModelList() les liste avec type = "weapon". Voir Précharger les modèles.