Développement d'un monde mobile

*Ce contenu est traduit en utilisant l'IA (Beta) et peut contenir des erreurs. Pour consulter cette page en anglais, clique ici.

Créer un mouvement dans n'importe quel environnement dans une expérience aide à le ressentir instantanément plus immersif et réaliste dans notre monde, que ce soit grâce à la déplacement d'arbre ambiant, à la réactivation de portes du joueur ou même aux boîtes qui se déplacent lorsqu'elles se heurt

Créer la tempête

La tempête a traversé de nombreuses itérations avant que nous nous soyons mis d'accord sur ce qui est en direct dans The Mystery of Duvall Drive. Au début, nous avons pensé à la tempête comme un pilier d'obsidienne géant, et dans les itérations suivantes, nous l'avons considérée comme un portail géant vers l'espace corrompu. Après avoir expérimenté avec de nombreux types de tempêtes avec des sentiments uniques, nous avons décidé d'un type de tempête avec un "œil" central plus petit car

  • La tempête devrait donner aux joueurs un sens de l'impact de cet événement sur le monde, y compris les arbres qui volent et les débris qui volent autour.
  • Le vortex tourbillant des nuages eux-mêmes devrait donner aux joueurs un coup d'œil sur le portail central sans révéler tout . Cela pourrait encourager les joueurs à enquêter plus près pour voir ce qui se passe.
  • Le point de lumière plus serré nous permettrait de nous concentrer sur la composition de la maison , qui est à la fois le personnage principal et l'endroit où la plupart du jeu se trouve.

Pour faire en sorte que la tempête se sente dynamique, agressive et toujours changeante dans son environnement, nous avons utilisé les systèmes et les fonctionnalités suivants :

  1. TweenService > - Pour le mouvement des nuages.
  2. Changements d'éclairage - Pour créer le cloud à l'éclair.
  3. Faisceaux) > - Pour la « lumière volumétrique » et les boulons de foudre.
  4. Émetteurs de particules > - Pour les débris volant vers le portail et volant autour en raison du vent soufflant.
  5. Animations > - Pour les arbres qui soufflaient dans le vent.

Ajouter des nuages avec des textures

Bien que les nuages dynamiques soient parfaits pour les nuages de haute altitude, réalistes, nous avons besoin de quelque chose qui se sente dram

Un seul réseau de maillagede cloud.
Mailleurs nuages en plusieurs niveaux sans leurs textures !

Puisque chaque maillage de cloud nécessaire pour être énorme pour entourer la maison et transmettre à quel point la tempête était énorme, nous savions que nous avions besoin de tuer la texture que nous voulions utiliser sur les maillages de cloud individuels afin qu'elle soit lourdement répétée sur la surface du maillage. Nous avons testé les matériaux que nous avons faits pour le cloud sur ces simples parties, puis appliqués à la vortex !

Contrairement aux émetteurs de particules ou aux rayons, les mailles nous ont permis d'être en mesure de refléter la lumière de chaque maillage, ce qui était important lorsque nous voulions implémenter le tonnerre entre nuages. Nous avons également modélisé dans le tordant afin que le tonnerre rebondisse de celui-ci pour qu'il ressemble à s'il avait de la profondeur ! Ceci était important surtout dans les situations où les exigences de performance de l'expérience ont fait tomber les niveaux de surface de nos objets d

Une fois que nous avons commencé à ajouter de la lumière dessus, nous avons dû ajouter des détails aux maillages pour les rendre réactifs à la lumière!

Missions de nuages tournants

Après avoir été satisfaits de l'apparence visuelle globale des nuages, nous avons dû le mettre en mouvement ! Nous avions les formes générales de chaque couche de nuage en emplacement, mais il a pris beaucoup de temps pour s'assurer que l'effet de rotation ressemblait bien dans la pratique. Nous avons d'abord essayé d'utiliser contraintes pour introduire la vitesse qui conduirait

Nous voulions un méthode facile à utiliser pour faire pivoter des instances qui étaient soit trop loin pour être interagibles, telles que les nuages, soit trop petites ou décoratives pour être importantes pour le

Comme dans de nombreux cas dans la démo, nous avons utilisé une balise LocalSpaceRotation pour que nous puissions gérer les instances affectées dans Studio en utilisant un plugin de balisage d'instances. Nous avons utilisé un seul LocalScript qui gère toutes les instances taguées en utilisant le plugin de balisage d'instances CollectionService afin que nous n'ayons pas à avoir une tonne de scripts à


local function Init()
for _, obj in CollectionService:GetTagged("LocalSpaceRotation") do
if obj:IsDescendantOf(workspace) then
SetupObj(obj)
end
end
end
CollectionService:GetInstanceAddedSignal("LocalSpaceRotation"):Connect(function(obj)
objInfoQueue[obj] = true
end)
CollectionService:GetInstanceRemovedSignal("LocalSpaceRotation"):Connect(function(obj)
if objInfo[obj] then
objInfo[obj] = nil
if objInfoQueue[obj] then
objInfoQueue[obj] = nil
end
end
end)
Init()

objInfo est une serveurqui a des informations pour tous les objets pertinents, tels que leur vitesse de rotation et leur axe. Notez que nous ne appelons pas immédiatement SetupObj à partir de CollectionService.GetInstanceAddedSignal

Nous avons roté les instances dans la fonction Update connectée au battement cardiaque. Nous avons obtenu le


local parentTransform
if parentObj:IsA("Model") then
if not parentObj.PrimaryPart then
-- la partie principale pourrait ne pas être diffusée encore
continue -- attendez que la partie principale se réplique
end
parentTransform = parentObj.PrimaryPart.CFrame
else
parentTransform = parentObj.CFrame
end
curObjInfo.curAngle += dT * curObjInfo.timeToAngle
local rotatedLocalCFrame = curObjInfo.origLocalCFrame * CFrame.Angles( curObjInfo.axisMask.X * curObjInfo.curAngle, curObjInfo.axisMask.Y * curObjInfo.curAngle, curObjInfo.axisMask.Z * curObjInfo.curAngle )
if obj:IsA("Model") then
obj.PrimaryPart.CFrame = parentTransform * rotatedLocalCFrame
else
obj.CFrame = parentTransform * rotatedLocalCFrame
end

Nous avons vérifié qu'un Model.PrimaryPart valide soit défini pour gérer le streaming. Si une mise à jour est appelée sur notre objet pendant qu'un Model.PrimaryPart (qui peut point à un maillage enfant) n'a pas été diffusé encore, nous sauterions la mise à jour. Le système

Concevoir des coups de foudre

Comme Studio n'offre pas d'outil de génération de foudre en boîte, et que le système de partie avait quelques limites qui ne fonctionneraient pas pour les coups de foudre du héros, nous avons dû être créatifs avec une solution pour les coups de foudre du héros. Nous avons décidé sur deux systèmes principaux pour faire partie des coups de foudre : des rayons texturés pour les coups de foudre du héros qui vien

Brouillons texturaux

Nous utiliserions généralement un séquenceur ou une chronométrie pour diriger le timing d'un effet de griffes de lumière comme celui-ci, mais comme Studio ne fournit pas encore cette fonctionnalité, nous avons décidé d'écrire des scripts qui contrôleraient le timing d'un effet de griffes de lumière. Le scripting de cet effet est assez simple, mais il atteint les objectifs suivants :

  1. Les éléments des coups de foudre, tels que leurs textures, leur brillance et leurs délais, sont aléatoires avec chaque coup.
  2. Les changements audio et post-FX sont en synchronisation avec les frappes FX.
  3. Les joueurs qui sont soit à l'intérieur, soit dans la zone corrompue ne pourraient pas les voir ou les entendre.

Nous avons un Script côté serveur qui calcule divers paramètres et délais, les envoie à tous les clients et attend un nombre aléatoire de temps :


local function LightningUpdate()
while true do
task.wait(rand:NextNumber(3.0, 10.0))
local info = CreateFXData()
lightningEvent:FireAllClients(info)
end
end

À l'intérieur de CreateFXData, nous remplissons la structure d'information afin que tous les clients obtiennent les mêmes paramètres.

Sur le côté client ( LightningVFXClient ) nous vérifions si ce client doit exécuter le FX :


local function LightningFunc(info)
-- pas d'effets visuels à l'intérieur
if inVolumesCheckerFunc:Invoke() then
return
end
-- pas de FX quand il n'est pas dans le monde « normal »
if not gameStateInfoFunc:Invoke("IsInNormal") then
return
end

En outre, nous exécutons la séquence pour définir les textures, les positions et la luminosité, nous exécutons les tweens et nous utilisons task.wait(number) . Les paramètres aléatoires sont de la structure d'information que nous avons reçue du serveur, et certains chiffres sont fixés.


beam.Texture = textures[info.textIdx]
beamPart.Position = Vector3.new(info.center.X + og_center.X, og_center.Y, info.center.Y + og_center.Z)
-- Effacer
beam.Brightness = 10
ppCC.Brightness = maxPPBrightness
ppBloom.Intensity = 1.1
bottom.Position = top.Position
tweenBrightness:Play()
tweenPPBrightness:Play()
tweenPPBrightness:Play()
tweenBottomPos:Play()
tweenBrightness.Completed:Wait()
-- audio
if audioFolder and audioPart then
if audioFolder.Value and audioPart.Value then
audioUtils.PlayOneShot(audioObj, audioFolder.Value, audioPart.Value)
end
end
task.wait(info.waitTillFlashes)
-- and so on

Pour vérifier si un joueur est à l'intérieur, nous utilisons une fonction inVolumesCheckerFunc, qui couvre les volumes pré- placés dans les zones intérieures et vérifie si la position du joueur est dans l'un d'eux (PointInABox). Nous aurions pu utiliser la détection basée sur le toucher, mais nous avons constaté que lorsqu'un joueur prend place

Pour vérifier si un joueur se trouve dans des zones corrompues, nous invoquons une fonction d'aide gameStateInfoFunc, qui vérifie l'état du jeu actuel. Pour jouer un son aléatoire à partir d'un dossier, nous avons également utilisé une fonction d'aide PlayOneShot. Pour les boulons de foudre eux-mêmes, ces étaient super faciles à créer dans Photosh

Utiliser les systèmes d'émetteurs de particules

Les héros éclairs frappent sont soutenus par un système de particules qui suggère un éclair lointain en créant l'impression d'un couche de nuages dans le fond capturant la lumière d'un éclair lointain, ou un éclairage cloud-to-cloud. Nous avons atteint cet effet via un système de particules très simple qui clignote une nuage sur le períphé de nuage principal. Le système émet une nuage de particules periodiquement avec une courbe de transparence aléatoire :

Faire souffler des arbres dans le vent

Après que nous avions les nuages et le tonnerre fonctionner de la manière dont nous le voulions, nous avons ensuite dû ajouter deux autres composantes principales d'une tempête : le vent et la pluie ! Ces éléments ont présenté quelques défis, y compris le besoin de travailler dans les limites actuelles de notre système de physique et d'effets spéciaux. Par exemple, faire pousser des arbres avec des vents réels n'est pas possible

Nous savions vraiment vendre l'effet du vent et de la pluie, nous avions besoin que les arbres eux-mêmes se mouvement. Il y a quelques façons que vous pouvez le faire dans le moteur, en déplaçant des parties à l'aide de plugins qui sont publiquement disponibles, en utilisant TweenService ou en animant des modèles directement. Pour nos

Nous avons commencé en peluche plusieurs arbres du Pack de modèles Endorse - Forêt Assets. Puisque ces arbres existaient déjà, et notre expérience a eu lieu dans le Pacifique Nord-Ouest, cela nous a permis de gagner du temps au début de la création de chaque modèlisationd'arbre.

Le pack Forest contient plusieurs types d'arbres, ce qui peut vous faire gagner du temps dans vos propres expériences.

Après avoir choisi nos arbres, nous savions que nous avions besoin de les peaufiner. Peaufiner un maillage est l'acte d'ajouter des jointures (ou os) à un maillage dans une autre application de modélisation 3D, comme Blender ou Maya, puis d'appliquer l'influence à ces

Nous savions que nous voulions enregistrer du temps et réutiliser la même animations, alors nous avons construit notre premier rig et nous sommes assurés que les noms joints étaient génériques parce que nous voulions utiliser ces mêmes noms dans les rigs pour les autres arbres. Nous avons également créé un motion secondaire

Les arbres ont des jointures primaires, secondaires et tertiaires afin que nous puissions avoir un mouvement crédible du fait d'être soufflés par le vent.

Une fois que nous avions créé nos articulations/os, il était temps de créer une animation de test pour se déplacer autour de toutes les articulations et os dans Studio pour voir si elles se déplaçaient comme nous le voulions. Pour ce faire, nous avons dû importer le tree dans Studio via le paramètre Custom Rig dans le 3D Importer</

La même hiérarchie dans Studio.

Après que nous avons été heureux avec les résultats sur cet arbre, il était temps de tester la même animation sur un arbre différent ! Nous savions déjà que c'était la même animation entre les différents grands arbres pour chaque taperd'arbre, alors nous avons juste fait en sorte que notre animation ressemble à ce qu'il devrait être généralement entre un grand arbre de Redwood et un arbre de Beechwood robuste !

L'animation que nous avons importée sur le Redwood Tree.

Pour ce faire, nous avons pris l'arbre Beechwood de ce pack forestier et avons construit un plateformesimilaire, en utilisant le même nom exact pour les jointures. Cela a donc été l'animation que nous avions précédemment importée pouvait être appliquée à cet arbre aussi. Étant donné que les animations étaient toutes basées sur les articulations tournantes, il n'a pas importé de quel arbre !

L'arbre Beechwood a le même nom exact pour ses jointures, juste pas le même montant. Ceci est correct puisque le système d'animation ne s'appliquera qu'à ces jointures spécifiques qui correspondent au nom dans l'animation ! Pour cette raison, nous pourrions appliquer les mêmes animations à n'importe quoi qui correspond aux noms des jointures !

Après avoir rig et skin le Beechwood tree, nous pouvions alors l'importer et appliquer la même animation exacte. Cela a signifié que l'itération et l'édition ne nécessitaient que d'être faits sur un seul fichier, et il a également été sauvegardé sur la performance avec moins d'animations lors de l'exécution de l'expérience.

En utilisant l'éditeur d'animation, nous pourrions appliquer la même animation d'arbre rouge à l'arbre de Beechwood !

Une fois que nous avions tous les types de scripts souhaités, nous avons créé chacun en packages pour que nous puissions continuer à modifier et à mettre à jour pendant que nous jouons plusieurs des animations autour de la zone principale de l'expérience. Étant donné qu'ils avaient un coût de performance, nous les avons utilisés judicieusement autour de la maison où l'effet était le plus précieux ! Dans le futur, comme cela devient plus performant, vous pourrez ajouter plus et plus d

Nous avons utilisé des arbres animés immédiatement autour de la maison où le vortex était le plus fort et l'effet visuel le plus impactant pour les joueurs.

Fabriquer des débris de tempête

Nous voulions que la pluie apparaisse lourde, et que le brouillard et les débris soufflent à travers les arbres. Pour ce faire, nous avons configuré quelques parties invisibles pour agir comme des volumes de particules avec des enfants émetteurs de particules immédiatement en dessous des grandes nuages de tempête. En raison du nombre de particules limité dans Studio, nous ne pou

Nous avons utilisé plusieurs volumes pour obtenir à la fois le montant de pluie et la couverture spécifique de la pluie que nous voulions.

Les particules de pluie ont utilisé une nouvelle propriété d'émetteur de particules ParticleEmitter.Squash qui vous permet de rendre une partie plus longue, ou de la faire plus volumineuse.

Une valeur Squash de 3 commence à étirer la texture plus longtemps.
Une valeur Squash de 20 étire les particules beaucoup plus longtemps, mais nous avons également dû augmenter la valeur Taille.

Pour le brouillard, le brouillard et les feuilles qui volent, il était beaucoup plus simple d'ajouter un seul volume plus important couvrant moins d'aires parce que nous n'avions pas besoin d'un ton de particules à la fois. Nous avons commencé en configurant un volume et obtenu la fréquence des particules où ils voulaient.

Il y avait en fait quelques quantités de particules, donc nous n'avions pas de particules qui entraient dans la maison, et parce que nous ne sentions pas qu'elles avaient besoin de se déplacer à travers les arbres comme le brouillard l'a fait.
La partie du volume des particules brumeuses était beaucoup plus grande puisque les particules étaient grandes, et nous n'avons pas eu besoin d'être aussi précis avec le lieu.

Après cela, nous avons fait nos textures de feuilles et de vent, et avons configuré les particules pour qu'elles tournent/se déplacent à différentes vitesses et commencent à différentes vitesses. Cela a signifié que les plus grandes particules de brouillard interagiraient plus naturellement et ne ressembleraient pas tant à une texture répétitive, surtout en raison de leur taille.

Particule de brouillard
Particule de feuille

Le résultat a été une action incroyable entre les arbres se déplaçant, la fenêtre qui boume et l'éclair qui crée l'effet de la tempête autour de l'œil central de la tempête.

Configurer l'Œil de la tempête

L'œil de pierre fendu avec un noyau brillant est destiné à donner aux joueurs la première indication qu'il y a quelque chose de sinistre et d'arcane dans la maison qu'ils devraient explorer plus loin. Étant que notre scène est sombre et que l'œil est loin dans le ciel, il était important de créer une silhouette d'œil f

Configurer le dernier éclairage de votre scène early on peut vous sauver beaucoup de travail inutile. Vous ne pourriez pas voir les détails de surface sur les anneaux avec le dernier éclairage de notre scène, il n'y avait pas besoin de passer le temps pour les mettre là-bas !

La distance du joueur a également signifié que nous pouvions nous fier entièrement à une carte normale pour les détails de la surface de l'œil afin que le maillage soit simplement une sphère plane ! Nous avons sculpté les détails dans un maillage élevé et boulons sa carte normale sur une sphère beaucoup plus basse afin que nous puissions obtenir tous ces détails magnifiques sans le coût de performance massif.

Sculpture de haute poly
Maille de faible densité
La maille de faible densité avec les informations normales de la sculpture de haute densité cuite dans

Afin d'ajouter un sentiment supernaturel à l'œil et d'accentuer sa présence, nous avons décidé de créer un glissement de magma brillant et fluo qui s'infiltrerait dans ses rides. Bien qu'il n'y a

La peinture de vérité sur la sphère interne. Nous avons créé un gradient qui était le plus léger autour de l'œil pour donner un sens plus profond et visuellement intéressant.

Un autre défi que nous avons rencontré lors de la création de l'œil a été imposé par notre utilisation de streaming combinée avec la distance de l'œil du joueur. Don

Nous avons pu ajouter du mouvement à l'œil et ses anneaux grâce au même script que nous avons utilisé pour tourner les mailles du cloud. Pour un toucher final, nous avons décidé d'ajouter un indice

L'image que nous avons utilisée pour créer une image d'un monde au-delà des nuages. Lorsque les joueurs sont loin de quelque chose, une image simple peut être suffisante pour créer l'illusion de plus de profondeur et de complexité dans votre scène !

Faire le stockage étendu

L'une des choses les plus amusantes à produire étaient les espaces corrompus, dans lesquels nous pouvions subvertir les attentes des joueurs en changeant littéralement le monde autour d'eux. Par exemple, dans le puzzle du père, nous voulions imiter un moment similaire à un cauchemar où, peu importe la vitesse à laquelle vous lancer, la salle semble s'allonger. Nous avons décidé de produire une cuisine étendue qui s'éloignerait des joueurs

Nous avons configuré cela avec un simple mouvement des murs, et un layout intelligent de nos chambres qui apparaîtra sur l'un des deux côtés de la cuisine. Dans l'état normal de la chambre, la cuisine était un couloir simple, mais dans l'espace corrompu, il était en fait beaucoup plus long avec plusieurs ailes et un faux mur !

L'état corrompu de la cuisine pantry.
Le mur faux se déplace des joueurs.

Le faux mur était un groupe de modèles que nous déplaçions au moment où les joueurs entrent dans un volume déclencheur, ce qui était une partie transparente auparavant dans le panier qui ils marcheraient à travers. Ce déclencheur a également été utilisé dans un script similaire à ceux utilisés sur toutes nos portes, ce qui a appelé le TweenService pour déplacer l'opération de tweening où les positions de départ et d'arrivée étaient pour

Le volume de la partie déclenche un mur faux derrière elle pour se déplacer à son point de terminaison. Il est rendu visible dans cette image avec un teint de jaune.
Target_Closed était une partie de but générique que nous avons utilisée sur toutes nos portes pour où elles doivent tourner. Ici, il a été réaménagé pour dire au mur du couloir où aller.

Puisque TweenService est un système si général, tous nos modèles de données de mur devaient contenir les mêmes composants. Par exemple, la image suivante est un exemple d'un script de porte générique qui appelle un son défini par un « value » sous le modèlisation«Grow_Wall».

Ce même script, avec quelques modifications dans l'exemple de code suivant, a également déclenché l'audio pour le mouvement de la réserve. Cela a ajouté beaucoup au mouvement !


local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local model = script.Parent
local sound = model.Sound.Value
local trigger = model.Trigger
local left = model.TargetL_Closed
local right = model.TargetR_Closed
local tweenInfo = TweenInfo.new(
model.Speed.Value, --Temps/vitesse de la porte Tween
Enum.EasingStyle.Quart, --Style d'atténuation
Enum.EasingDirection.InOut, --Direction de l'aération
0, --Répéter le compte
false, --Inverse vrai
0 --Délai
)
local DoorState = {
["Closed"] = 1,
["Opening"] = 2,
["Open"] = 3,
["Closing"] = 4,
}
local doorState = DoorState.Closed
local playersNear = {}
local tweenL = TweenService:Create(left, tweenInfo, {CFrame = model.TargetL_Open.CFrame})
local tweenR = TweenService:Create(right, tweenInfo, {CFrame = model.TargetR_Open.CFrame})
local tweenLClose = TweenService:Create(left, tweenInfo, {CFrame = model.TargetL_Closed.CFrame})
local tweenRClose = TweenService:Create(right, tweenInfo, {CFrame = model.TargetR_Closed.CFrame})
local function StartOpening()
doorState = DoorState.Opening
sound:Play()
tweenL:Play()
tweenR:Play()
end
local function StartClosing()
doorState = DoorState.Closing
--modèlisation["Door"] : Jouer()
tweenLClose:Play()
tweenRClose:Play()
end
local function tweenOpenCompleted(playbackState)
if next(playersNear) == nil then
StartClosing()
else
doorState = DoorState.Open
end
end
local function tweenCloseCompleted(playbackState)
if next(playersNear) ~= nil then
StartOpening()
else
doorState = DoorState.Closed
end
end
tweenL.Completed:Connect(tweenOpenCompleted)
tweenLClose.Completed:Connect(tweenCloseCompleted)
local function touched(otherPart)
if otherPart.Name == "HumanoidRootPart" then
local player = Players:GetPlayerFromCharacter(otherPart.Parent)
if player then
--imprimer ("触摸")
playersNear[player] = 1
if doorState == DoorState.Closed then
StartOpening()
end
end
end
end

Une fois que nous avions le mur faux se déplaçant à l'arrière de la pièce, nous avions besoin du reste du contenu pour se déplacer avec lui. Pour le faire, nous avions besoin de tous les objets lâchés sur le pantry pour être soudeurés sur le mur à mesure qu'il se déplaçait. En utilisant Weld Constraints, nous pouvions rapidement souder tous les objets sur le pantry pour les déplacer en

Faire la cabane arboricole corrompue

Studio est un moteur physiquement basé que vous pouvez utiliser pour créer tout, depuis un portail balançant à une plateformetournante. Avec notre démo, nous voulions utiliser la physique pour créer un sens de réalisme dans un ensemble d'environnements autrefois irréalistes. En utilisant quelques contraintes , vous pouvez créer des courses d'obstacles amusantes et difficiles dans vos propres expériences !

Conaintes sont un groupe de moteurs physiquement bas qui aligne les objets et limite les comportements. Par exemple, vous pouvez utiliser une contrainte de tige pour vous connecter aux objets afin de les garder à une distance fixe l'un

Le puzzle du fils a commencé avec les joueurs dans la même pièce, mais tout était sur le côté.

Une fois les joueurs descendus dans la zone principale du puzzle, ils ont été accueillis par un panorama familier sur Roblox : une course d'obstacles. Ce parcours d'obstacles en particular était composé de plusieurs plates-formes tournantes et de murs tournants, ainsi que d'« zones de sécurité » qui progressaient l'histoire. Nous nous concentrerons sur les éléments tournants/tournants.

L'apparence d'esprit cachait le fait que le gameplay ici était très simple.

Pourquoi avons-nous utilisé des contraintes ici ? Parce que TweenService ou d'autres méthodes ne déplaceraient pas le joueur tant qu'ils étaient sur eux. Sans que l'objet déplaçant le joueur, quelqu'un pourrait sauter sur une plate-forme et il tournerait à partir d'eux. Au lieu de c

Vous pourriez regarder vos amis tourner autour de vous en essayant de naviguer dans le parcours d'obstacles aussi.

Pour ce faire, nous avons d'abord utilisé des ressources de notre kit actuel et ajouté n'importe quel contenu visuel pour un effet visuel. Nous avons fait quelques murs et plateformes incomplètes avec des trous dedans pour raconter l'histoire de la grand-mère qui a construit la cabane dans un arbre. Étant donné que nous ne voulions pas créer un tas de pièces de base et de pièces de railing uniques, nous avons créé 4 pièces de base

Nous savions que puisque nous utilisions des contraintes, nous ne pourrions pas ancrer ces mailles car elles ne bougeaient pas même avec la présence d'une contrainte/moteur les menant. La

Il était maintenant temps de configurer le comportement actuel de la contrainte de l'articulation, et d'ajouter les accessoires qui agiraient comme l'orientation de la pièce et la contrainte ensemble. Nous avons placé le faisceau de rotation sur le Motor_Turn, qui les pièces de marche étaient soudures à, et

Pour garder les plates-formes tournant à une vitesse constante, nous avons ensuite configuré les propriétés HingeConstraint.AngularVelocity, HingeConstraint.MotorMaxAcceleration, et HingeConstraint.MotorMaxTorque à des valeurs qui permettraient le déplacement et empêcheraient l'interruption si un joueur sautait dessus.

Attachment0 était en fait l'ancre pour la goupille et Attachment1 représentait la goupille elle-même. Nous avions la goupille en train de tourner constamment, mais vous pouvez également utiliser une contrainte de goupille pour les portes.

Maintenant, nous avions besoin de faire les murs pivotants. Les murs avaient besoin de pivoter sur leur centre apparent, et nous savions que nous voulions qu'ils puissent gérer n'importe quelle orientation par rapport au reste du niveau. Comme les plates-formes, nous avons construit ces murs pour qu'ils soient tous ancrés et soudeurs au Motor_Turn.

Nous voulions réutiliser autant de meshes de la vraie maison dans l'arbre pour économiser en performance, nous avons donc suivi un chemin similaire à celui des plates-formes. Plusieurs types de murs ont été créés qui pouvaient s'empiler dans différentes combinaisons pour une certaine variante.

Nous avons utilisé Texture objets au-dessus de SurfaceAppearance objets pour ajouter quelques modifications à nos matériaux de base. Les textures

Vous pouvez voir à la fois le comportement similaire et configurer pour la contrainte articulaire, et aussi comment nous avons utilisé Texture objets.

Une fois que nous avons testé quelques plates-formes et des murs tournants, nous avons fait plusieurs variantes et joué avec leur placement pour nous assurer que le parcours d'obstacles était difficile, captivant et aussi clair où le joueur avait besoin d'aller ! Il a fallu beaucoup de réglage sur leurs valeurs et leurs positions pour les mettre en œuvre correctement. Nous avons eu plusieurs points où les plates-formes et les murs se heurtaient l'un à l'autre

Si vous n'êtes pas sûr de ce que vos objets physiques touchent, vous pouvez activer la fidélité de la collision dans le widget Options de visualisation dans le coin supérieur droit de la fenêtre de jeu3D.

A close up view of the 3D viewport with the Visualization Options button indicated in the upper-right corner.
Lorsque la représentation de géométrie d'impact est désactivée, vous pouvez voir la représentation de géométrie normale qui s'affiche dans le jeu.
Lorsque la visualisation de collision est activée, vous pouvez voir que les feuilles d'arbre n'ont pas de collisions, ce qui n'affectera pas les plates-formes ou les murs tournants.

Comme vous pouvez le voir, les portes/fenêtres sont visibles, mais les détails plus petits comme les sub-panneaux ne le sont pas. C'est parce que la propriété CollisionFidelity pour les murs a été réglée sur Boîte. Nous n'avions pas besoin de la précision pour ces panneaux, donc pour économiser sur le coût des performances, c