Dernière mise à jour : 22/06/2017 à 15h37

Current Project : ...

Index des tutoriaux

Les Karmas

Introduction

Les objets karma, lorsqu'on en parle, semblent surtout être un moyen de faire réagir les bouteilles et les lampes lorsqu'on leur tire dessus. Pourtant, il y a bien d'autres possibilités.

Karma est le moteur physique du jeu développé par MathEngine. Les objets karma, ou Kactors comme ils sont appelés par l'éditeur, sont des Static-Meshes qui, lorsqu'un objet les touche, réagissent selon divers paramètres physiques pour simuler un comportement normal de chute, de flottement ou de balancement. Il est possible de définir des contraintes à ces objets, pour qu'une ou plusieurs de leurs parties soient attachées à d'autres objets karma, Static-Meshes, ou même à la géométrie du monde. Les mouvements karma peuvent fonctionner sur internet. Malheureusement, tout comme les séquences de mort des joueurs, les mouvements karma ne seront pas les mêmes sur les machines des différents joueurs. Si un joueur voit un autre perdre une jambe sous un coup de roquette, un autre peu le voir s'envoler sous la force de l'explosion. Pour les objets karma, c'est un peu la même chose : si un joueur voit un bidon tomber d'une passerelle, il est possible qu'on autre le voit juste rouler le long du bord, ce qui peu entraîner de gros problèmes de jouabilité. Ce procédé de calcul propre de chaque machine est appelé Réplication (Ce mot ne sera pas utilisé ailleurs dans ce tutorial, mais ceux qui sont déjà découragés auront au moins appris ça). De fait, ils sont désactivés par défaut dans UT2004 lors du jeu en multi-joueurs, au même titre que certaines textures qui procèdent à un traitement en temps réel, ou ils seront considérés comme de simples Static-Meshes (mais des petits malins ont bien entendu réussi à contourner le truc).

Avant de commencer, il faut savoir différentes choses sur les objets karma. En effet, lorsque l'objet en mouvement entre dans la collision d'un autre, le moteur physique vérifie les propriétés de cet autre objet. S'il trouve la fonction bBlockKarma activée, alors il fait un nouveau calcul de la suite du mouvement, en prenant en compte la collision de l'acteur touché. Si ce booléen est faux, alors l'objet continue son mouvement à travers l'autre (c'est ainsi qu'ils passent à travers les actors invisibles par exemple, les zones portals où les FluidSurfaceInfo). Les Blockings volumes ont par défaut, cette propriété à Vrai. Cela veut dire que si vous voulez que votre objet rentre en collision avec le Static Mesh et non avec le blocking volume qui l'entoure, vous devrez modifier cette propriété. Par ailleurs, il est conseillé pour pouvoir profiter des objets karma, de mettre dans les réglages du jeu, le paramètre "physique détaillée" à "élevé". Ainsi, vous ne manquerez aucun détail. Sachez tant que vous y êtes, qu'un vulgaire fusil d'assaut ne fera pas bouger votre objet d'un pouce, aussi, placez un lance roquette dans la pièce de test (les armes qui feront bouger un objet karma peuvent être les lance-roquette, les Link-gun (en tir secondaire), le canon Flak).

Objets Karma basiques :

A moins que vous ne sachiez précisément ce que vous voulez faire dans une map précise, vous devrez réaliser une map de test. Dans un coin, placez quelques armes. Pour tester le karma, je vous suggère de placer un lance-roquette, un canon Flak et un Link-Gun au minimum.

Pièce de test

Nous allons voir ici, l'objet karma le plus simple qui soit : le tonneau qui tombe quand on lui tire dessus, exemple éculé des tests sur le sujet. Ouvrez le Static-Mesh browser, et ouvrez le package CP_MechStaticPack. Cherchez le Static en forme de tonneau nommé "Cp_Sg_MechTechBarrel3" et sélectionnez-le. Revenez à votre pièce, faites un clic droit normal, mais au lieu de cliquer sur "Add Static Mesh"[...]" Here, choisissez "Add Karma Actor".

Tonneau

Bon, premier constat, il est un peu grand. Qu'à cela ne tienne, réduisez sa taille de moitié. Ensuite, très important, placez-le Très légèrement au dessus du sol. Vous verrez par la suite pourquoi c'est important.

Vous pouvez déjà tester votre map et le faire tomber à grand coup de lance-roquette, à condition d'avoir rebuildé. Si rien ne se passe lors du tir sur votre baril, assurez-vous que la propriété "Physique détaillé", de votre configuration, est bien mise à "Haute". D'ailleurs si vous réglez ce paramètre au cours du jeu, vous serez obligé de recharger votre carte pour pouvoir en profiter (quitter la partie et la relancer, au lieu de juste revenir à la carte pour que ce soit actif).

Votre premier objet Karma fonctionne

Ouvrez les propriétés de l'objet karma, et regardez un peu les paramètres disponibles. Pour ce faire, allez dans l'onglet "Karma", c'est là que nous allons préparer les petites choses qui font la différence. Cliquez sur le sous onglet "KarmaParams MyLevel. KarmaParams0", puis sur la partie "Karma Params".
Voici les effets des propriétés disponibles de cette partie :

Propriétés des objets Karmas

La partie KarmaParamsCollision contient trois propriétés supplémentaires qui s'avéreront cruciales pour modifier le comportement de votre objet lorsqu'il est touché, déplacé ou éjecté :

Notre tonneau réagit simplement pour l'instant. Pour que ce soit plus réaliste, nous allons mettre la propriété KstartEnabled à vrai. Ainsi, dès le début, le comportement de l'objet sera immédiatement calculé, ce qui ne nous pose pas de problème vu le faible nombre d'objet dans notre map. Comme il n'y a pas d'eau dans la map, nous ne modifierons pas KBuoyancy, mais si vous envisagez de rajouter un liquide, je peux vous suggérer 1, qui est très bien pour un objet de ce genre, ou même une valeur inférieure pour qu'il coule, ce qui serait plus approprié. Je vous suggère également d'augmenter la valeur de Kfriction vers quelque chose du type 0.4.

Interaction avec la géométrie

Ouvrez le package Humanoïd hardware, et dans le group "miscellaneous", vous devez avoir un Static nommé "MChain01HA", qui représente quelques maillons d'une chaîne. Ajoutez-en trois en tant qu'objet karma, et posez les uns en dessous des autres, en faisant en sorte que le plus haut soit en contact avec le plafond. Ensuite, dans le package "AWHadware", trouvez le Static "sh_Light01_jm", qui représente une lampe et un cône de lumière. Ajoutez-les en tant qu'objets karma, et placez-les en dessous des chaînes. Votre résultat doit ressembler à ceci :

Lampe

Pour l'instant, le comportement n'est pas vraiment au point :

Attention, chute de lampes

Tout ce sur quoi vous tirez tombe, ce qui n'est pas exactement le but recherché (encore qu'avec des morceaux de plafond, on pourrait croire que le toit par en miette). Bref, nous avons besoin d'actors spéciaux pour faire comprendre au moteur physique que les chaînes sont attachées entre elles, que celle du bas est attachée à la lampe et que celle du haut est accrochée à la géométrie de la map. Cet actor, c'est le KBSjoint.

Vous le trouverez dans l'Actor Browser, Actor=>Kactor=>KConstraint=>KBSjoint. Sélectionnez le, et placez-en un au sommet de la chaîne, entre la chaine et la lampe, et entre chaque section de chaine :

Ajout de KBSjoint pour attacher les éléments ensemble

Le pivot de votre KBSjoint (le point rouge) doit être placé exactement là où l'attache sera située. Soyez donc assez précis, pour ne pas avoir une chaîne attachée au vide. Ouvrez donc les propriétés du KBS Joint. Qui se trouve entre le plafond et la première section de chaine. Dans la catégorie "KarmaConstraint", cliquez sur le champ à coté de KconstraintActor1. Cliquez sur "Trouv." à coté, et cliquez sur la chaîne. Ne faites pas l'erreur de cliquer sur KConstraintBone1. Si vous attachez votre objet physique sans préciser de deuxième actor, il sera automatiquement relié de manière absolue au point où se trouve votre KBSjoint. Comme votre KBSjoint est connecté naturellement à la géométrie, laissez KConstraintActor2 vide. Faites de même pour chaque KBSjoint, et à chaque fois, mettez pour KConstraintActor1, l'objet du dessus, et à KconstraintActor2, l'objet au dessous du KBSJOINT.
Rebuildez, testez, tirez un peu sur la lampe et observez :

Lors du tir, la lampe se débat au bout de sa chaine

Vous allez apercevoir malgré tout, un problème de taille : si vous tirez assez sur la lampe, elle peut faire un tour complet sur elle-même et passer à travers la chaine. En effet, KBSjoint signifie Karma Ball and Socket Joint, c'est-à-dire un joint très simple réalisé avec un point d'attache sans limite. Il faudrait faire en sorte que la lampe ne puisse pas effectuer plus qu'un certain angle autour de la chaine pour éviter ces problèmes. Pour cela, nous allons avoir besoin d'autres contraintes.

Contraintes :

Si le KBSjoint est l'outil de contrainte le plus utilisé, il n'est pas le seul :

Le KConeLimit

Le KConeLimit est un actor qui permet de limiter le rayon du cône de mouvement d'un objet déjà soumis à des contraintes de type KBSjoint. Nous continuerons donc à base de cette jolie petite lampe karma que nous avons déjà faite. On va donc l'utiliser pour éviter que la lampe de puisse se mettre à la verticale et passer à travers sa chaine. Il se trouve dans l'actor browser un peu en dessous du KBSjoint :

ConeLimit dans l'actor browser

La flèche défini sur quel Axe la rotation est limitée, donc, pivotez la flèche (de la même façon que vous pivotez un Spotlight) vers le bas. Le placement de l'actor n'est pas très important, car c'est dans ses propriétés que tout va se jouer. Placez-le à proximité de votre chaîne. Maintenant, il faut dire à Unreal que nous voulons limiter la chaîne du haut. Donc, comme d'habitude, dans KConstraint, KConstraintActor1, "Trouv.", cliquez sur la lampe, et dans Kconstraintactor2, mettez la chaine.

Maintenant, il faut déterminer l'angle maximal de mouvement de cette chaîne. Dans KHalfAngle, on peut déterminer l'angle maximum en unités Unreal (ou 65536 = 360 degrés, 16384 = 90 degrés). Pour les besoins du test, je vous suggère de mettre une valeur très faible (comme 256) pour bien vérifier l'impact de la limite. En temps normal, je vous suggère pour un cas comme ça d'utiliser 16384 qui conviendra très bien. Notez que vous pouvez poser votre KConeLimit n'importe où tant qu'il est paramétré correctement. En revanche, vous devez laisser les KBSjoint qui attachent les actors entre eux, le KConeLimit n'est en aucun cas une attache en lui-même.

Si vous faites le test, vous remarquerez également que lorsque la chaine bouge, elle embarque avec elle le cône de mouvement raisonnable :

Limit au repos Limite en mouvement

A proximité de la propriété "KHalfAngle", vous avez d'autres propriétés :

Le KHinge

Le KHinge est au même endroit que les actors précédents:

KHinge dans l'actor browser

Son fonctionnement est très simple et combine ses les effets du KBSjoint et du KConeLimit. Comme le premier, il agit comme un joint, et comme le second, il limite le mouvement sur un seul axe. Il s'agit d'un joint qui possède en plus la propriété de pouvoir faire tourner l'objet auquel il est rattaché, si on le paramètre en tant que moteur. Il est donc théoriquement possible de créer des engrenages complets à l'aide de cet actor (pour être franc, ce serait plus difficile que ça n'en a l'air).

Cherchez dans le package de Static-Meshes Humanoïd Hardware, group Walkways, prenez le Static représentant un tronçon de passerelle. Ajoutez-en quelques-uns en tant que Karma Actors et faites leur décrire une courbe approximative. A ce stade, tirer dans le pont fera tomber les différentes sections, ce qui n'est pas du meilleur effet.

Paserelle effondrée

Placez un KHinge entre le mur et le pont, et un entre chaque morceau du pont en vous assurant que les flèches pointent toute la même direction.

KHinge à chaque point de liaison

Tout comme pour les KBSjoint, configurez les KConstraintsActor, en prenant pour le 1 l'actor à droite du KHinge, et pour actor 2, l'actor à gauche, dans le sens que vous voulez. Pour les deux Statics accrochés aux murs, laissez l'actor 2 vide, et ne prenez que l'actor1 qui sera l'objet karma. Votre pont est déjà prêt. Vous pouvez marcher dessus et tirer dans le tas. En revanche, il est possible que vous ayez un résultat étrange où chaque section tournera sur son axe central :

Mauvais axe de mouvement

Si le cas se présente, pivotez tout vos KHinge de 90 degrés dans le même sens. Cela signifie seulement que l'axe pointé par la flêche n'est pas le bon.

Bon axe de mouvement

L'avantage du KHinge, c'est qu'il possède différentes configurations dans KarmaConstraint : KHingeType :

KHingeType

La KHinge propose aussi plusieurs InitialStates, qui lui permettent d'être déclenché de la même façon qu'un mover, par un trigger ou un autre événement.

La plupart de ces InitialStates interagissent avec les propriétés KDesiredAngle et KAltDesiredAngle, qui se trouvent dans l'onglet KarmaConstraint, et seulement visibles chez le KHinge. KDesiredAngle et KAltDesiredAngle doivent être exprimés en unités Unreal : 16384=90°, 32768=180°, et donc 65536=360°.

Ragdolls :

Théoriquement, vous voyez les effets Ragdolls quand un joueur meurt : son corps devient flasque et réagit au tir. Unreal est d'ailleurs un des rares jeux (NDLA : en 2006) à proposer cet effet, avec les géants comme Half-Life 2 et doom3.
Il est pourtant possible d'utiliser cet effet dans le jeu comme décoration. Malheureusement, si le joueur n'a pas mis la physique détaillé au maximum, le corps gardera la position par défaut : droit, jambes écartées et bras en croix, ce qui limite cet effet à de la décoration pour ne pas avoir des joueurs désavantagés. A vrai dire, vous ne l'utiliserez certainement jamais. Cependant...

Commencez par dupliquer votre lampe au bout de sa chaine, puis ouvrez l'animation browser. Une fois dans le browser, faites File, Open, HumanMaleA. Une fois le package chargé, dans le champ "Mesh", choisissez un des modèles qui vous plait.

AnimationBrowser

Sélectionnez la lampe, et ouvrez ses propriétés. Dans l'onglet "Display", à "DrawType", changé Dt_StaticMesh" en "DT_Mesh" pour qu'il ne soit plus un simple objet doué de collision, mais un objet un peu plus complexe. Ensuite, dans le champ "Mesh", cliquez sur le petit "Util". Pour plus de sureté, dans le champ "Static-Mesh", mettez None : votre lampe change, c'est désormais le modèle qui apparait.

Installation actuelle

Pour l'instant, l'affichage est parfait, mais votre cadavre n'est pas contrôlé par des effets ragdoll. Pour ce faire, allez dans l'onglet "movement", pour changer "physics" de PHYS_Karma à "PHYS_KarmaRagdoll".
Pour finaliser l'effet, allez dans l'onglet "Karma" et supprimez ce qui s'y trouve. Ajoutez un objet en sélectionnant dans le menu déroulant, KParamsSkel. En effet, votre Mesh va devoir utiliser des données spécifiques aux Meshes de joueurs qui sont des Meshes Skeletals, c'est-à-dire qui utilisent un Squelette (notamment pour leurs animations).

En plus des onglets communs aux autres objets Karma, les Skeletals Meshes disposent d'un onglet KarmaParamsSkel. On va voir un peu les propriétés disponibles :

Onglet particulier aux ragdolls

Bien, pour terminer cet effet ragdoll, il faut définir le squelette qu'utilisera notre cadavre pour la gestion des collisions. Si nous lui mettons un squelette de juggernaut, tirer autour de lui risque de le faire bouger. A l'inverse, il n'aura pas le même squelette que les femmes humaines du jeu sous peine d'avoir l'air trop large pour ses collisions plus fines (et donc de s'enfoncer à moitié à travers la géométrie).
Ici, le squelette se nomme Male. Donc dans les propriétés du ragdoll, il faut trouver le champ KSkeleton et mettre Male. Si vous commencez maintenant, le Mesh sera bizarrement compacté tant que vous ne tirerez pas dessus. Pour éviter ça, activez KStartEnabled.

Là où c'est très amusant, c'est que les Mesh peuvent eux aussi être soumis aux contraintes des KBSjoint et KHinge :

Ragdoll soumis à des KBSjoints

KHinge comme moteurs :

Ajoutez n'importe quoi n'importe où. La seule exigence étant que ce soit à peu près rond où que vous ayez un moyen de voir si ça tourne. Au centre de votre Static-Mesh, ajoutez un KHinge qui relie votre objet à rien (c'est-à-dire à la géométrie). Mettez quelque chose dans les KDesiredAngle et KAltDesiredAngle et faites quelques tests avec les différents modes de fonctionnement et InitialStates. Je vous conseille aussi de placer quelque part un trigger qui enverra comme event, c que vous mettrez dans le Tag du KHinge pour faires des tests en plus. Comme il n'est pas très simple d'illustrer le mouvement sur un screenshot, je m'abstiendrais.

En revanche, si vous essayez de faire un engrenage, vous allez avoir des problèmes car cela nécessitera des roues dentées avec des collisions convexes (avec des creux) qu'UnrealEd ne peut pas générer. Il faudra donc passer obligatoirement par un import depuis Blender, 3DSmax ou Maya pour le faire fonctionner. Une fois ce problème réglé, il vous suffira d'attacher des roues à proximité avec des KHinge et de transformer le premier de la chaine en moteur.

2005-2016, by Hellkeeper.

Valid XHTML 1.1 CSS 2.1