Parfois, je passe des heures sur des détails. En ce moment, je butte sur un problème plutôt … « négligeable », mais toutefois embêtant. Je n’aime pas négliger, alors j’essaie de trouver la solution. Mon but : je cherche à tirer là où je clique. Mon problème est d’origine mathématique, les angles calculés sont faux …
Le problème est le suivant : mon canon est orienté tout droit. Pour tirer là ou je clique, il faut donc lui faire une rotation sur un axe (ici Z). Le canon doit donc suivre ma souris et s’orienter en direction de celle ci. La ligne obtenue entre la souris et le canon peut être convertie en angle grâce à Unity (et moins de calcules à faire du coup !)
J’ai changé l’aspect graphique du jeu en utilisant une camera en « perspective ». Cela modifie les repères et les calcules, mais cela donne un aspect nouveau au jeu. Un aspect que je recherche. Cela change le ratio pixels et position relative mais par chance Unity dispose d’un outil pour convertir ces données. Comprendre ça m’a déjà pris des heures.
La position du canon est une position « relative », indépendante de la résolution, exprimée en unitées propre au jeu. La position de la souris est une position en pixels, dépendante de la résolution. Je dois donc la convertir en position relative. C’est ce que « Camera.main.ScreenToWorldPoint » me permet de faire.
L’addition de ces infos permet donc de créer un canon qui suit la souris et qui tourne en fonction de celle ci. Cependant, mon problème est le suivant : plus le joueur est loin du centre de l’écran, moins le canon est précis. Et ça, je comprends pas …
Et le code pour les curieux :
public void FixedUpdate()
{
if (playerStatistic.isAimingActive == false)
{
isAiming = false;
return;
}
if (playerStatistic.isAimingActive == true)
{
//rotation de la souris autour du joueur.
Vector3 mouseposition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 50); // avec la camera en perspective, il faut préciser la profondeur, sans quoi les coordonnées sont celles de l’origine de la camera
var newMouseposition = Camera.main.ScreenToWorldPoint(mouseposition);
Ray ray = new Ray(transform.position, newMouseposition);
Debug.DrawRay(transform.localPosition, newMouseposition, Color.white);
Debug.DrawRay(transform.position, newMouseposition, Color.yellow);
Debug.DrawLine(transform.position, newMouseposition, Color.blue);
Debug.DrawLine(transform.localPosition, -newMouseposition, Color.red);
Quaternion rotation = Quaternion.LookRotation(transform.position, -newMouseposition);
transform.rotation = rotation;
float angle = transform.localEulerAngles.z – 90;
transform.eulerAngles = new Vector3(0, 0, angle);
}
}
Et cela doit bien faire 8h que je butte là dessus. Je vous laisse avec une nouvelle démo du jeu dont voici le changelog :
- Ajout du champ d’astéroïdes !
- Au bout d’un certain nombre de points, un événement se produit … à vous de deviner lequel !
- Réintroduction du bonus de visée : les tirs peuvent de nouveau être dirigés.
- Les tirs ne sont plus bloqués par les bonus
- Les bonus sont attirés par le joueur
- Un bug de mémoire pouvait survenir :
- Normalement les tirs et les ennemis qui sortent des limites du jeux sont effacés (sans donner de points au joueur), évitant ainsi des erreurs de mémoire.
- Les ennemis qui tiraient en dehors du champ de vision de la camera ne disparaissaient pas et continuaient de tirer, ces tirs s’accumulant inlassablement, entrainant un lag progressif du jeu sur de longues parties.
- C’est corrigé !
- Changement du rendu graphique global par l’introduction d’une caméra en perspective ! Les fonds défilent à des vitesses et profondeur différentes !
- Changement de la gestion des étoiles : création d’un « StarField ». Dorénavant les étoiles sont créées sur une sphère qui pivote au rythme du fond galactique …
Le jeu peut être testé ici : SpacePiouPiou 0.0.9.2