Créé le 09/11/2002
Dernière mise à jour le 09/11/2003
Dans les jeux Unreal®, les bugs sont écrient dans un fichier *.log, ce
fichier log porte le même nom que l'éxécutable du jeu en question (exemple:
UnrealTournament.log, UT2003.log).
Pas trés important quand on débute l'UnrealScript
avec des petits codes, mais un ou plusieurs bug(s) en passe rapide de code comme
dans la function Tick() ou dans un passage de la HUD peut énormément buggé.
Une
grosse accumulation de bugs peut faire grossir le fichier log jusqu'a plusieurs
mo, et même faire planté le jeu!
Donc il faut débugguer son code dés le début,
c'est à dire qu'a chaque test du code (aprés le rebuild (compilation) du
package), si on trouve un bug, mieux vaut le supprimer aussitôt sans continué
le code proprement dit, car quand il y en a plusieurs dizaines voir plus,
ca devient plus compliqué et plus long à débugguer.
Déja il est nécessaire de
comprendre le fichier log pour debbuguer.
On reconnais le type du message
par le mot clef qui la commence (ex: Init, Log etc...).
Les bugs commencent
par ScriptWarning pour la première génération du moteur (ex: UT)
et juste par Warning dans la seconde (ex: UT2003), mais dans ce dernier
il se peut que ce soit pas toujours un bug du a vôtre code mais parfois
par quelque petites erreurs du jeu, qui sont en principe pas vraiment importantes,
ne pas en tenir compte donc.
Quasiment tous les bugs sont des Accessed None, il
y en a d'autre mais le log précisera plus en temps voulu.
Comme par exemple
lorsqu'on utilise une variable d'une chaîne de variable qui dépasse la longueur de
la chaîne déclarée. (voir ce tutorial
pour comprendre de quelle type de variable je parle)
Le moteur veut dire par Accessed None qu'on s'est servi
d'une variable de type Actor-Référence, qui faisait référence a aucun acteur.
Une
fois qu'on a vraiment compris ce qu'il a voulu dire, c'est trés facile de corrigé
l'erreur, ca serra expliqué dans le chapitre suivant.
Il se peut que ce soit pas exactement ca, mais concentrons nous dans ce qu'il
y a entre les parenthèses et le type de bug (qui est écrit a la fin) pour
comprendre le principe.
Les quatre **** représente une valeur héxadicimale,
donc si c'est toujours la même valeur, il s'agit du même bug.
Exemple d'un bug dans une function:
Warning: MaClasse Package.MaClasseSupérieure.MaClasse (Function MonPackage.MaClasse.MaFonction:****) Accessed None
Exemple d'un bug dans un état:
Warning: MaClasse Package.MaClasseSupérieure.MaClasse (State MonPackage.MaClasse.MonEtat:****) Accessed None
Exemple d'un bug d'une function dans un état:
Warning: MaClasse Package.MaClasseSupérieure.MaClasse (Function MonPackage.MaClasse.MonEtat.MaFonction:****) Accessed None
Maintenant qu'on sais a peu prés où est le bug voici quelques exemples:
Exemple si c'est pas sur que la variable est une référence:
var MyActor A;
function
PostBeginPlay()
{
Super.PostBeginPlay();
A = Spawn(class'MyActor');
Test();
}
function
Test()
{
if(A != None)
// on vérifie que l'acteur existe bien
{
// mon code
}
}
L'exemple le plus facile, si on doit utiliser A, comme une de
ses functions, exemple: A.MyFunction(); et si a ce moment A
n'existe pas, il y aurra forcément un Accessed None,
mais pas dans l'exemple car on vérifie dabord que A (sa référence en
fait) existe.
Si au contraire c'est sur que A réfère l'acteur, alors
c'est pas nécessaire de vérifier A réfère un acteur.
Il faut savoir
que si la réfèrence est détruite, la variable n'aurra plus de référence, est
donc A redevient égal a None.
Mais si on détruit sa référence
manuellement, exemple: A.Destroy(); et qu'on veut ré-utilisé la variable par la
suite, mieux vaut mettre juste aprés: A = None;
Exemple pour vérifié si on a eu raison d'être sur:
...
function Test()
{
if(A != None) // on vérifie
que l'acteur existe bien
{
//
mon code
}
else
Log("Mon référence de la variable A n'existe pas!");
}
S'il se trouve qu'on c'était trompé, un message serra écrit dans le log.
Sachant
que les message écrit dans le log de cette façon commence par ScriptLog.
Exemple pour être sur que l'acteur est bien apparu:
...
function
PostBeginPlay()
{
Super.PostBeginPlay();
A = Spawn(class'MyActor');
if(A != None) Test();
else Log("Mon acteur n'est pas
apparu car A n'a pas de référence");
}
...
Ici on vérifi si déja l'acteur a bien été spawné, en principe oui, mais dans
certain cas, suivant la collision de l'acteur est l'endroit du spawn, si c'est hors
de la map l'acteur ne serra pas spawné.
Ou tout simplement si un mutator
empêche ce type d'acteur d'apparaîttre.
4) Débugguer en traquant le bug
Si vous ne comprennez pas où est le bug ou si vous ne le voyez vraiment
pas (c'est un peu la même chose en fait), ce qui peut arriver a n'importe qui,
surtout quand le log a repérer le bug dans une function ou un état de plusieurs
centaines de lignes.
On va se servir de la function Log() pour mieux
repérer l'emplacement du bug.
function Test()
{
Log("Test():1");
// mon code
Log("Test():2");
//
mon code
Log("Test():3");
}
Donc si par exemple l'Accessed None est écris entre
les messages 2 et 3, c'est sur qu'il y est, et non pas entre les
messages 1 et 2.
Si sa suffit pas et qu'on trouve toujours
pas, on refait pareil entre les messages 2 et 3, etc... jusqu'a
refermé la tenaille sur le bug!
Pour que sa saute plus vite aux yeux dans
le log, mettre plutot un message plus visible du type:
Log("================ Test():2 ================");
Note:
Une fois le debugging acqui, vous aurrez fait un petit pas de plus en
programmation d'UnrealScript.