Aller au contenu principal

Chargement de modèle

GTA V contient plus de dix mille modèles 3D différents : passants, bolides, feux de circulation et poubelles. Le moteur ne peut évidemment pas tout garder en mémoire vidéo simultanément. À la place, il charge les ressources (streaming) depuis le disque vers la mémoire uniquement lorsqu'elles deviennent nécessaires à proximité du joueur.

Si ton script tente de faire apparaître un personnage dont le modèle 3D n'est pas encore en mémoire, le jeu affichera une entité invisible buggée ou plantera purement et simplement.

Le contrat de streaming

Faire apparaître une entité respecte toujours un rituel en quatre étapes :

  1. Vérifier la validité : Le nom du modèle existe-t-il vraiment dans les archives du jeu ?
  2. Demander le chargement en mémoire : Solliciter le gestionnaire de streaming pour rapatrier le maillage et les textures, avec un délai maximal (timeout).
  3. Créer l'entité : Faire apparaître le ped ou le véhicule maintenant que la ressource est prête.
  4. Libérer le modèle : Indiquer au gestionnaire de streaming que ton script n'a plus besoin de verrouiller cette ressource en mémoire vive.

Voici le modèle blindé utilisé en pratique :

using GTA;
using GTA.Math;

public void CreerPersonnageEnSecurite()
{
Model model = new Model(PedHash.Trevor);

// 1. Vérifier la présence dans les archives du jeu
if (!model.IsValid || !model.IsInCdImage)
{
model.MarkAsNoLongerNeeded();
return;
}

// 2. Demander avec un délai d'attente strict (2000 millisecondes)
if (!model.Request(2000))
{
// Délai dépassé : le modèle n'a pas pu être chargé à temps
model.MarkAsNoLongerNeeded();
GTA.UI.Notification.PostTicker("Échec du chargement du modèle de personnage.", false);
return;
}

// 3. Créer dans un bloc try-finally
try
{
Ped player = Game.Player.Character;
Vector3 pointApparition = player.Position + player.ForwardVector * 2.5f;
World.CreatePed(model, pointApparition, player.Heading);
}
finally
{
// 4. Toujours libérer le modèle, même en cas d'erreur
model.MarkAsNoLongerNeeded();
}
}

Pourquoi Request(timeout) plutôt qu'une boucle infinie

Les anciens tutoriels montraient souvent ceci :

// DANGEREUX : peut bloquer définitivement ton script
model.Request();
while (!model.IsLoaded)
{
Script.Yield();
}

Si le modèle est corrompu, absent d'une archive ou si la mémoire est saturée, model.IsLoaded ne devient jamais vrai. Ton script entre dans une boucle infinie, gèle sa fibre et cesse de répondre pour toujours.

En passant un délai maximal à model.Request(2000), SHVDN attend de façon coopérative jusqu'à 2 secondes. Si la ressource n'est toujours pas prête, la méthode renvoie false, ce qui permet à ton code d'échouer proprement, d'informer le joueur et de continuer à tourner.

Le bloc finally est non négociable

Appeler model.MarkAsNoLongerNeeded() indique au moteur que ton script n'a plus besoin de verrouiller ce modèle en mémoire. Une fois le ped créé dans le monde, c'est l'entité elle-même qui maintient le modèle en vie. Maintenir le verrou ouvert gaspille la mémoire de streaming. Enfermer cette libération dans un bloc finally garantit que le modèle sera déverrouillé quoi qu'il arrive.

Maintenant que tu maîtrises les coordonnées, les vecteurs, les entités, leur validité et leurs modèles, tu es prêt pour le Projet 02 : Ped spawner.