Ascenseurs et trains dans Hammer : de func_door à func_tracktrain
Ascenseurs et trains dans les maps Source et GMod : quelle entité choisir, keyvalues, boutons d’appel, parcours path_track, causes d’écrasement et de saccades.
Tu construis un ascenseur à deux arrêts à partir d’un func_door ou d’un func_movelinear, et plusieurs étages ou des trains à partir d’un func_tracktrain qui suit une chaîne d’entités path_track. Les joueurs se font écraser quand une valeur de dégâts de blocage est définie et que l’entité continue de pousser alors qu’elle est bloquée. Les saccades pendant le trajet sont décrites par le wiki de Valve comme une caractéristique générale des plateformes à déplacement vertical dans les jeux Source multijoueurs. Il n’indique aucun correctif, alors teste l’ascenseur tôt. Un ascenseur reste en général bloqué parce que quelque chose se trouve sur son chemin ou que le parcours est mal chaîné.
Quelle entité pour quel usage
| Entité | Mouvement | Convient pour | Limites |
|---|---|---|---|
func_door | entre deux positions, distance = taille du brush moins Lip | ascenseur simple à deux arrêts | ne peut pas s’arrêter entre les deux |
func_movelinear | le long d’une direction sur Move Distance, n’importe quelle position intermédiaire via SetPosition | ascenseur à deux arrêts, plateformes, portails | bugué d’après le wiki de Valve quand il est parenté à un autre func_movelinear |
func_tracktrain | le long d’une chaîne de path_track | plusieurs étages, trains, virages | plus de travail, s’arrête légèrement avant sa cible à vitesse plus élevée |
func_tanktrain est un train qui tire sur le joueur et qui peut être tué, il ne convient donc pas ici. func_train et func_plat ne figurent pas dans le FGD de GMod.
Un ascenseur à deux arrêts
Un func_movelinear est ce qui demande le moins de travail :
- Construis le plancher de la cabine sous forme de brush, appuie sur
Ctrl+Tet choisisfunc_movelinear. Nom :lift. - Règle
Move Direction (Pitch Yaw Roll)surUp. Le champ affiche alors-90 0 0. - Saisis sous
Move Distancela distance entre les deux sols, en unités, et sousSpeedla vitesse. - Construis les murs et le plafond de la cabine sous forme de
func_brushet saisis le nomliftsousParent. - Place un
func_buttonà chaque étage comme bouton d’appel et relie-le à l’ascenseur.
Entity My Output Target Entity Target Input
button_up OnPressed lift Open
button_down OnPressed lift Close
lift OnFullyOpen door_top Open
lift OnFullyClosed door_bottom Open
Open envoie l’ascenseur jusqu’à la position finale, Close le ramène à la position de départ. OnFullyOpen et OnFullyClosed signalent l’arrivée, et c’est avec eux que tu ouvres les portes palières. Le fonctionnement détaillé des outputs, des délais et des noms est expliqué dans l’article sur les inputs et outputs dans Hammer.
Avec un func_door, le calcul est différent : une porte se déplace toujours de la taille de son propre brush, moins Lip. Un plancher de 16 unités d’épaisseur qui doit monter de 256 unités a donc besoin d’un Lip de -240. Ajoute Delay Before Reset (-1 stay) réglé sur -1, le flag Toggle et Touch Opens décoché.
Portes et boutons sur la cabine
Tout ce qui doit accompagner le mouvement reçoit le nom de l’entité mobile dans son champ Parent. Un enfant garde son décalage par rapport au parent et suit chaque mouvement.
- Portes de cabine : deux entités
func_dooravecParent=lift. N’utilise pas un deuxièmefunc_movelinearici, à cause du bug de parenting du tableau. - Boutons dans la cabine :
func_buttonavecParent=lift. Avec le flagDon't move, le bouton ne s’enfonce pas dans le mur quand on le presse. - Verrouiller les boutons : Sur
OnPressed, envoie l’inputLockà tous les boutons (lift_button*), puis de nouveauUnlocksurOnFullyOpenetOnFullyClosed. - Outils Sandbox : Le FGD de GMod propose
Allow Physics GunetSandbox Tool Whitelistpour ces entités. Règle le premier surNopour que personne en Sandbox n’attrape l’ascenseur avec le Physics Gun.
Trains et plusieurs étages avec func_tracktrain
- Place le premier
path_tracket donne-lui un nom commetrack_1. Si tu le clones en maintenant Shift enfoncé, Hammer incrémente le nom et remplitNext Stop Targettout seul. - Construis le train de façon que son avant pointe le long de l’axe X, vers la droite dans la vue de dessus. Au spawn, il se tourne vers le
path_tracksuivant. - Transforme-le en
func_tracktrainet saisis le premierpath_tracksousFirst Stop Target. Le train spawne à cet endroit. Max Speed (units / second)plafonne toutes les vitesses.Initial Speed (units / second)à 0 signifie que le train est d’abord à l’arrêt.- Active le flag
No User Control. Pour un ascenseur, ajouteFixed Orientationafin que la cabine ne pivote pas. - Démarre-le avec l’input
StartForward. À un arrêt, lepath_trackenvoieStopau train viaOnPass.
Pour une boucle, saisis le premier path_track comme Next Stop Target du dernier. New Train Speed sur un path_track modifie la vitesse à partir de ce point, mais n’a d’effet qu’avec No User Control.
Dans GMod, func_tracktrain possède aussi l’input MoveToPathNode. Il se rend au path_track indiqué sur le même parcours et s’y arrête. Un ascenseur à nombreux étages devient ainsi simple :
Entity My Output Target Entity Target Input Parameter Delay
button_floor3 OnPressed lift_door Close 0.00
button_floor3 OnPressed lift MoveToPathNode floor_3 1.00
lift OnArrivedAtDestinationNode lift_door Open 0.00
Le wiki de Valve mentionne deux autres particularités : un func_tracktrain ne met à jour sa direction que dix fois par seconde, si bien que les trains rapides dépassent le tracé dans les virages serrés. Et Reverse ou StartBackward peuvent échouer si New Train Speed vaut 0 sur les entités path_track concernées.
Pourquoi les ascenseurs écrasent, saccadent ou restent bloqués
Écrasement. Chacune des trois entités a sa propre valeur de dégâts : Blocking Damage sur func_door, Block Damage sur func_movelinear, Damage on Crush sur func_tracktrain. La valeur par défaut est 0 partout. Pour la porte et func_movelinear, le FGD indique la valeur par frame, de petits nombres tuent donc vite. Le comportement de l’entité quand elle est bloquée se lit dans le code public du Source SDK : un func_door repart en sens inverse, sauf si Delay Before Reset est négatif ou si Force Closed est activé. Un func_movelinear ne repart jamais en sens inverse et continue de pousser. Avec 0, l’ascenseur n’inflige aucun dégât de blocage, mais un joueur dans la cage peut le retenir. Donc soit tu gardes 0 et tu fermes la cage avec des portes palières qui ne s’ouvrent qu’une fois l’ascenseur arrivé, soit tu définis une valeur de dégâts et tu laisses l’ascenseur gagner. Sur un func_door, tu peux réagir toi-même avec OnBlockedClosing et OnBlockedOpening.
Saccades. Le wiki de Valve indique que toute plateforme à déplacement vertical paraît saccadée à ses passagers dans les jeux multijoueurs, et donne comme raison la physique réseau des joueurs. Une astuce tirée de la page de discussion du tutoriel sur les ascenseurs du wiki de Valve, non documentée et que toutes les maps ne confirment pas : ne laisse pas les joueurs se tenir directement sur le func_tracktrain, mais sur un func_brush qui lui est parenté. Pour func_brush, le FGD décrit le keyvalue Solid BSP exactement pour ce cas, un brush dans la hiérarchie d’un objet mobile sur lequel des joueurs se tiennent. Vérifie le résultat sur un vrai serveur avec du ping, comme décrit dans tester une map GMod avec des joueurs.
Props à bord. Un prop_physics est simulé par la physique et, d’après le wiki de Valve, se comporte bizarrement quand tu le parentes. La décoration de la cabine a donc sa place sur l’ascenseur sous forme de prop_dynamic parenté. Des props physiques libres sur une plateforme en mouvement peuvent glisser et se coincer. C’est un retour d’expérience pratique, pas un comportement documenté. Les types de props sont comparés dans prop_static, prop_dynamic et prop_physics.
Blocage. Quelque chose se trouve-t-il sur le chemin ? Un path_track a-t-il le flag Disabled ou Disable train activé, ou un Next Stop Target vide ? Des boutons ont-ils été verrouillés sans jamais être déverrouillés, parce que l’ascenseur a été bloqué et que OnFullyOpen n’est jamais arrivé ? Sur un func_tracktrain, le flag Is unblockable by player aide contre les joueurs qui le bloquent.
Questions fréquentes
Pourquoi mon func_tracktrain ne s’arrête-t-il pas exactement au path_track ?
Le train s’arrête juste avant sa cible, de façon plus visible à vitesse plus élevée. Réduis la vitesse avant l’arrêt, ou déplace le path_track de la distance manquante jusqu’à ce que la cabine soit à niveau.
Pourquoi la cabine est-elle mal éclairée pendant le trajet ?
Les entités brush portent des lightmaps précalculées depuis leur position de départ, qui ne correspondent plus dès que la cabine entre dans une zone éclairée différemment. Le remède : construis la cabine visible sous forme de prop_dynamic et parente-la à un brush invisible. Plus de détails dans le guide de l’éclairage du Source Engine.
Les joueurs peuvent-ils conduire un train eux-mêmes ?
Oui, tant que le flag No User Control du train est désactivé. D’après le wiki de Valve, un joueur qui se tient sur un func_tracktrain peut alors le contrôler. Un func_traincontrols dont Train Name et Parent pointent tous deux vers le train limite cela à son brush : le joueur doit se tenir à l’intérieur de celui-ci et sur le train.