Salut tout le monde !
Quatrième et dernière partie du tutorial. Si vous arrivez en cours de route, ça commence par-là.
Dans cette partie on va apprendre à déclencher un évènement sur le réseau. En l’occurrence l'activation d'un ascenseur.
Vous vous demandez peut-être pourquoi on ne se contente pas de synchroniser la position de l'ascenseur via une NetworkView. Si on fait ça, l'ascenseur ne saura pas s'il est en position haute ou en position basse. Le mouvement de l'ascenseur sera également plus fluide avec notre façon de faire et ça économisera de précieuses ressources réseau. Mais il y aurait bien entendu moyen d'obtenir le même résultat en jouant avec une NetworkView et en observant la position.y de l'ascenseur pour savoir s'il est en haut ou en bas.
Mise en place de la scène
On va améliorer un peu notre arène. Je vous laisse faire ça comme vous voulez mais en gros il faut une partie surélevée qu'on ne pourra atteindre qu'avec l'ascenseur.
Placez au moins un ascenseur (un simple cube plat) muni d'un levier/bouton ou truc quelconque pour l'activer. Je vous conseille de lui mettre un pied de support comme moi, ça nous permettra d’appeler l'ascenseur si on est en bas et lui en haut.
Voila à quoi ressemble ma map:
Et voila mon ascenseur pour ceux qui veulent:
lift.fbx
Si vous l'utilisez voila comment régler les options d'importation.
Désactivez aussi l'animation de l'objet. et placez une BoxCollider sur chacune des parties.
Bien, on va régler rapidement l'ascenseur:
- Placez une BoxCollider en mode isTrigger qui englobe tout l'ascenseur (nacelle et pilier). C'est cette box qu'on activera.
- Créez un nouveau script en javascript et nommez-le Lift.js
- Assignez le script à votre/vos ascenseur(s)
On va aussi ajouter un composant essentiel à notre Cuby, un champs d'action. Voyez ça comme un espèce de bras virtuel, ça lui permettra d'activer les objets qui sont devant lui.
- Créez un nouvel Empty GameObject et appelez-le "ActionField".
- Ajoutez-lui une CollisionBox en mode isTrigger et donnez-lui une forme de lame verticale qui s'étendra devant Cuby.
- Attachez-là à Cuby.
Scripting
- Ouvrez le script Lift.js dans votre éditeur de code
var down:boolean; //L'ascenseur est il en position basse ou en haut?
var latence:float = 0.1; //plus elle est grande, plus l'ascenseur ira lentement
private var isMoving:boolean; //si l'ascenseur est en mouvement, on ne peux pas l'activer
var upPosition:float; //coordonnée y de la position haut de l'ascenseur
var downPosition:float; //idem mais position basse
function OnSwitched()
{
if(!isMoving)
{
isMoving = true;
if(down)
{
//monte
while(transform.localPosition.y < upPosition)
{
yield new WaitForSeconds(latence);
transform.position.y += 0.1;
}
down = false;
}
else
{
//descend
while(transform.localPosition.y > downPosition)
{
yield new WaitForSeconds(latence);
transform.position.y -= 0.1;
}
down = true;
}
isMoving = false;
}
}
function OnTriggerStay(col:Collider)
{
if(col.transform.name == "ActionField")
{
if(col.transform.root.networkView.isMine) //Evite de pouvoir activer l'ascenseur si c'est l'ennemi qui est dans la bonne position pour l'activer
{
if(Input.GetKeyDown(KeyCode.E) || Input.GetKeyDown(KeyCode.Return))
{
OnSwitched();
}
}
}
}
- Configurez ensuite le script dans l'inspector. Voila ma config, les coordonnées seront très probablement différentes dans votre projet.
Normalement, votre ascenseur doit fonctionner en local ("E" ou "Enter" pour l'activer).
Quelques conseils:
- Le script n'est pas très précis, c'est pourquoi la downPosition de l'ascenseur est différente de sa position de départ.
- Le mouvement de l'ascenseur n'est pas du tout fluide (si on vous demande, dites que c'est pour un effet ascenseur antique^^). Ça peut s'arranger en jouant avec la variable latence et le changement de position (ex: transform.position.y -= 0.1; ).
- Vous pouvez aussi utiliser la fonction transform.Translate plutôt que de changer directement la position.y
La partie réseau
- Commencez par ajouter une NetworkView à votre ascenseur. Cette NetworkView ne doit rien observer ("none").
Vos ascenseurs devraient maintenant fonctionner comme prévu.
Conclusion
- Synchroniser la position et l'orientation d'objets
- Instancier des objets tels que les joueurs ou les projectiles sur le réseau
- Appeler des fonctions locales à distance sur toutes les machines connectées
Télécharger
Aller plus loin
Je vous parlais de la synchronisation de variables, cela se fait via la fonction OnSerializeNetworkView().
Voila le passage de la documentation Unity parlant de ça. Et bien entendu voici le Network Reference Guide d'Unity où vous trouverez pas mal d'informations importantes.
Il ne me reste plus qu'à vous donner un dernier conseil: pratiquez ! Pratiquez, pratiquez et pratiquez encore. Rome ne s'est pas faites en un jour donc ne vous découragez pas si vous n'arrivez pas tout de suite aux résultats escomptés. Faire un jeu en réseau n'est pas la chose la plus simple du monde mais avec un peu de persévérance vous devriez y arriver.
N'hésitez pas non plus à demander de l'aide sur les forums où des gens plus qualifiés pourront vous aider. A ce propos je vous déconseille Unity Answers vu que vos messages doivent être validés pour apparaître ce qui vous fera perdre un temps précieux. Personnellement je demande généralement de l'aide sur Reddit/r/Unity3D. La communauté est très sympa et généralement de bon conseil.
Bonne continuation :)