Réalité virtuelle
PhysiCore se joue en VR (OpenXR : Meta Quest en Link / Air Link / Virtual Desktop, SteamVR). Le joueur VR a un corps entier : son playermodel suit son casque et ses manettes (tête, torse, bras, doigts), et tous les autres joueurs le voient bouger ainsi. Joueurs VR et joueurs sur écran jouent ensemble.
Lancer en VR
Ajoute l'option de lancement --vr (Steam : Propriétés → Options de lancement, ou après -- en ligne de commande). Le jeu active les shaders VR dans user://rendering.cfg et se relance tout seul avec OpenXR (en Vulkan). Le casque doit être prêt avant : Meta Quest Link / Air Link ou SteamVR lancé. Sans casque détecté, la partie continue sur l'écran. Un lancement normal n'active jamais la VR.
Pour les développeurs : --vr-sim simule un casque sans en avoir (pavé numérique : 4 / 6 / 8 / 2 tourner la tête, flèches : avancer, 0 : gâchette droite, 5 / 7 : grips droit / gauche). Les scènes tools/_vr_sim_test.tscn et tools/_vr_net_test.tscn testent le corps, les mains et le réseau.
Commandes
| Manette | Action |
|---|---|
| Joystick gauche | Se déplacer (vers où regarde la tête) ; poussé à fond : courir |
| Clic joystick gauche | Annuler (undo) |
| Joystick droit gauche / droite | Tourner par crans de 30° (réglable, ou rotation fluide) |
| Joystick droit haut / bas | Arme suivante / précédente (dans un menu : faire défiler) |
| Clic joystick droit | Chat vocal (maintenir) |
| Gâchette droite | Tirer, physgun, toolgun (dans un menu : cliquer) |
| Gâchette gauche | Tir secondaire (clic droit) |
| A / B | Sauter / recharger |
| X / Y | Utiliser (E) / menu de spawn (reste ouvert, Y le referme) |
| Menu (manette gauche) | Pause |
| Grips (gâchettes latérales) | Attraper avec la main |
| Les deux joysticks cliqués | Calibrer sa taille (se tenir droit) |
S'accroupir dans la vraie vie accroupit le personnage, se déplacer dans la pièce le déplace (un mur l'arrête). Les menus (pause, spawn, fenêtres Lua) s'affichent sur un panneau devant le joueur, visé avec le laser de la main droite ; le HUD (vie, munitions) apparaît au dos du poignet gauche quand on le regarde. La taille du joueur est mesurée au début de la première partie : son personnage a ensuite la même hauteur d'yeux.
Le corps et les mains
- Les armes, le physgun et le toolgun sont tenus dans la main droite et visent le long de son rayon : les tirs et les outils partent de la main.
- Les mains sont physiques : elles s'arrêtent sur les murs et les props, poussent et frappent les props. Le grip près d'un prop l'attrape (mêmes règles que le physgun : protection des props), relâché il garde sa vitesse (lancer). Chaque main a une force limitée : un objet lourd traîne ou ne se soulève pas, à deux mains on porte plus.
- Les doigts se ferment avec la gâchette (index) et le grip (les autres).
- Le joueur ne voit pas l'intérieur de sa propre tête : elle lui est cachée.
Lua
| Fonction | Où | Renvoie |
|---|---|---|
ply:IsVR() | partout | Le joueur joue en VR |
ply:GetVRHeadPos(), ply:GetVRHeadAngles() | partout | Position et angles du casque (monde), nil hors VR |
ply:GetVRHandPos(main), ply:GetVRHandAngles(main) | partout | Main "left" ou "right" (monde) |
ply:GetVRAimPos(), ply:GetVRAimVector() | partout | Rayon de visée de la main droite |
ply:GetVRHandGrab(main) | serveur | Le prop tenu dans cette main, ou nil |
vr.IsActive() | client | Cet ordinateur joue en VR |
Hooks serveur : PlayerVRGrab(ply, ent, main) (renvoyer false empêche d'attraper) et PlayerVRDrop(ply, ent, main). ply:GetEyeTrace() et ply:GetAimVector() d'un joueur VR suivent sa main droite.
-- Serveur : on ne soulève pas les props des autres équipes à la main
hook.Add("PlayerVRGrab", "equipes", function(ply, ent, main)
local proprio = ent:CPPIGetOwner()
if IsValid(proprio) and proprio:Team() ~= ply:Team() then return false end
end)
-- Client : une sphère sur la main gauche des joueurs VR
hook.Add("PostDrawOpaqueRenderables", "mains_vr", function()
for _, ply in ipairs(player.GetAll()) do
if ply:IsVR() then
render.DrawSphere(ply:GetVRHandPos("left"), 0.06, 8, 8, Color(0, 200, 255))
end
end
end)