Os, animations et effets
Lire et déformer le squelette des props, des joueurs et des PNJ, retrouver leurs points d'attache, jouer les animations d'un modèle, changer son rendu, l'enflammer ou le désintégrer, et secouer l'écran. Noms de Garry's Mod ; unités du jeu : mètres et degrés.
Os
Ces méthodes existent sur les props et entités scriptées (le squelette de leur modèle, s'il en a un), sur les joueurs (le mannequin ou leur playermodel) et sur les PNJ. Les os sont numérotés à partir de 0.
| Méthode | Côté | Renvoie |
|---|---|---|
ent:LookupBone(nom) | partagé | Numéro de l'os, ou nil. Les noms ValveBiped.Bip01_… de GMod marchent (voir plus bas). |
ent:GetBoneCount() | partagé | Nombre d'os (0 sans squelette). |
ent:GetBoneName(n) | partagé | Nom de l'os, ou "__INVALIDBONE__". |
ent:GetBoneParent(n) | partagé | Numéro de l'os parent, -1 pour la racine. |
ent:GetBonePosition(n) | partagé | Deux valeurs : position (Vector) et angles (Angle) de l'os dans le monde, ou nil. |
ent:GetBoneMatrix(n) | partagé | Une matrice (Transform3D de Godot) dans le monde : m:GetTranslation(), m:GetAngles(), m:GetScale(), m:GetForward(), m:GetRight(), m:GetUp(). nil si l'os n'existe pas. |
ent:ManipulateBonePosition(n, Vector) | serveur / client | Décale l'os (mètres, dans le repère de l'os), en plus de l'animation. |
ent:ManipulateBoneAngles(n, Angle) | serveur / client | Tourne l'os (degrés : pitch, yaw, roll), en plus de l'animation. |
ent:ManipulateBoneScale(n, Vector) | serveur / client | Multiplie la taille de l'os (Vector(1, 1, 1) = normale). |
ent:GetManipulateBonePosition(n), …Angles(n), …Scale(n) | partagé | Les valeurs données par le serveur (zéro, ou Vector(1, 1, 1) pour la taille, par défaut). |
ent:HasBoneManipulations() | partagé | Un os est-il déformé (par le serveur, ou par ce client) ? |
Côté serveur, ManipulateBone* est envoyé à tous les joueurs (y compris ceux qui arrivent plus tard). Côté client, la déformation ne se voit que chez ce joueur, en plus de celles du serveur. Décalage et taille sont bornés à ±50. Remettre zéro (ou Vector(1, 1, 1) pour la taille) enlève la déformation. ent:SetupBones() et ent:InvalidateBoneCache() recalculent tout de suite la pose des os (GetBonePosition à jour juste après un ManipulateBone*).
-- Serveur : grosse tête pour tout le monde.
local function grosse_tete(ply)
local tete = ply:LookupBone("ValveBiped.Bip01_Head1")
if tete then ply:ManipulateBoneScale(tete, Vector(2, 2, 2)) end
end
-- Client : une lumière qui suit la main droite d'un joueur.
local pos, ang = ply:GetBonePosition(ply:LookupBone("ValveBiped.Bip01_R_Hand"))
Noms ValveBiped
LookupBone cherche d'abord le nom exact, puis, pour un nom de GMod, l'os équivalent des squelettes du jeu (mannequin Rigify DEF-…, Character Creator CC_Base_…, Mixamo mixamorig:…, Unreal …_l / …_r). Noms reconnus :
| Partie | Noms ValveBiped. |
|---|---|
| Tronc et tête | Bip01_Pelvis, Bip01_Spine, Bip01_Spine1, Bip01_Spine2, Bip01_Spine4, Bip01_Neck1, Bip01_Head1 |
Bras (L / R) | Bip01_L_Clavicle, Bip01_L_UpperArm, Bip01_L_Forearm, Bip01_L_Hand (et _R_) |
Jambes (L / R) | Bip01_L_Thigh, Bip01_L_Calf, Bip01_L_Foot, Bip01_L_Toe0 (et _R_) |
Les doigts n'ont pas d'équivalent : utilise le nom réel de l'os (ent:GetBoneName(n) en boucle sur GetBoneCount() pour les lister).
Points d'attache
| Méthode | Renvoie |
|---|---|
ent:LookupAttachment(nom) | Numéro du point (à partir de 1), 0 s'il n'existe pas. |
ent:GetAttachment(n) | { Pos = Vector, Ang = Angle } dans le monde, ou nil. |
ent:GetAttachments() | { { id = 1, name = "…" }, … } |
Sur un prop, les points d'attache sont les pièces nommées de son modèle (celles de l'éditeur de modèles). Sur un joueur ou un PNJ, ce sont les noms de GMod, placés sur l'os correspondant : eyes (8 cm au-dessus de l'os de la tête), mouth, forward, anim_attachment_head (tête), chest (Spine2), anim_attachment_RH et anim_attachment_LH (mains).
-- Client : un chapeau sur la tête du joueur local.
local chapeau = ents.CreateClientProp("builtin:cone")
chapeau:Spawn()
hook.Add("Think", "chapeau", function()
local point = LocalPlayer():GetAttachment(LocalPlayer():LookupAttachment("eyes"))
if point then
chapeau:SetPos(point.Pos + Vector(0, 0.15, 0))
chapeau:SetAngles(Angle(0, point.Ang.y, 0))
end
end)
Animations des props (séquences)
Les animations d'un modèle importé (voir Éditeur de modèles) sont ses séquences, numérotées à partir de 0 dans l'ordre de GetSequenceList(). Les changements faits par le serveur sont vus par tous.
| Méthode | Côté | Rôle |
|---|---|---|
ent:LookupSequence(nom) | partagé | Numéro de l'animation, -1 si elle n'existe pas. |
ent:GetSequenceList() | partagé | Les noms, indexés à partir de 0 (for i = 0, ent:GetSequenceCount() - 1). |
ent:GetSequenceCount(), ent:GetSequenceName(n) | partagé | Nombre d'animations ; nom (ou "Unknown"). |
ent:SetSequence(n ou nom), ent:ResetSequence(n ou nom) | serveur | Joue cette animation en boucle, depuis le début. |
ent:GetSequence() | partagé | Numéro de l'animation en cours, -1 sans. |
ent:SetCycle(0 à 1), ent:GetCycle() | serveur / partagé | Saute à cet endroit de l'animation (0 = début, 1 = fin) ; où elle en est. |
ent:SetPlaybackRate(vitesse), ent:GetPlaybackRate() | serveur / partagé | Vitesse de lecture (1 = normale, de -10 à 10, négative = à l'envers). |
ent:SequenceDuration(n) | partagé | Durée en secondes (sans argument : l'animation en cours). |
Un prop n'a qu'un corps physique : ent:GetPhysicsObjectCount() vaut 1 et ent:GetPhysicsObjectNum(0) donne le même objet que GetPhysicsObject().
Matériaux et rendu
| Méthode | Côté | Rôle |
|---|---|---|
ent:GetMaterials() | partagé | Noms des matériaux du modèle, une entrée par surface (dans l'ordre des surfaces). |
ent:SetSubMaterial(n, id) | serveur | Met un matériau de l'outil Matériau ("metal", "gold"…, comme SetMaterial) sur la surface n seulement (à partir de 0). id = "" rend son matériau à cette surface ; ent:SetSubMaterial() sans argument les rend toutes. |
ent:GetSubMaterial(n) | partagé | Matériau mis sur cette surface, ou "". |
ent:SetRenderMode(RENDERMODE_…), ent:GetRenderMode() | serveur / partagé | Mode de rendu (voir ci-dessous). |
Les constantes RENDERMODE_* de GMod existent toutes (NORMAL, TRANSCOLOR, TRANSTEXTURE, GLOW, TRANSALPHA, TRANSADD, ENVIROMENTAL, TRANSALPHADD, WORLDGLOW, NONE). Seules deux familles changent l'apparence : RENDERMODE_NONE cache le modèle, et RENDERMODE_GLOW, TRANSADD, TRANSALPHADD et WORLDGLOW le dessinent en additif (lumineux, comme un hologramme). Les autres modes laissent le rendu normal.
Feu et désintégration
| Méthode | Côté | Rôle |
|---|---|---|
ent:Ignite(durée, rayon) | serveur | Enflamme un prop ou un joueur pendant durée secondes (5 par défaut, 3600 au plus). Rallumer prolonge le feu. rayon (0 par défaut, 50 m au plus) : les joueurs à cette distance brûlent aussi. |
ent:Extinguish() | serveur | Éteint. |
ent:IsOnFire() | partagé | En feu ? |
ent:Dissolve() | serveur | Désintègre un prop : il flotte sans gravité, brille en bleu électrique, s'efface en lançant des étincelles, puis est supprimé au bout de 1,6 s. |
Ce qui brûle perd 2 points toutes les 0,5 s : un prop reçoit des dégâts de type DMG_BURN (ENT:OnTakeDamage), un joueur perd de la vie (« a brûlé »), de même que chaque joueur dans le rayon. L'eau éteint le feu, comme la fin de la durée ou la mort du joueur. Les flammes et leur lumière se voient chez tous les joueurs.
-- Serveur : un baril qui prend feu au premier dégât, puis disparaît.
function ENT:OnTakeDamage(dmg)
if self:IsOnFire() then return end
self:Ignite(8, 3)
timer.Simple(8, function() if IsValid(self) then self:Dissolve() end end)
end
Secouer l'écran : util.ScreenShake
util.ScreenShake(pos, amplitude, fréquence, durée, rayon) fait trembler la caméra. Côté serveur, envoyé à tous les joueurs ; côté client, seulement chez ce joueur. amplitude de 0 à 16 (5 par défaut), fréquence en Hz (5 par défaut), durée en secondes (1 par défaut, 30 au plus). Avec un rayon (mètres), seuls les joueurs à cette distance de pos tremblent, de moins en moins loin du centre ; 0 = partout. La secousse faiblit jusqu'à la fin de sa durée.
-- Serveur : une explosion qui secoue les joueurs à moins de 30 m.
util.BlastDamage(pos, 6, 80)
util.ScreenShake(pos, 12, 20, 1.5, 30)
Voir aussi le dessin des entités (ENT:Draw, ent:DrawModel()), les entités cachées aux joueurs (ENT:UpdateTransmitState), les variables NetworkVar et ents.CreateClientProp dans Entités scriptées.