Viser
Leçon 10 sur 25 du cours Jeu Unity : défense de tours de Coddy.
Une tour se tourne vers sa cible : pas la tour entière, qui repose sur son socle, mais sa tête, un objet enfant qui porte le canon. Tourner un enfant fait tourner tout ce qui se trouve sous lui et laisse le parent tel quel.
Les ennemis marchent plus bas que les têtes, donc la direction d’une tête vers son ennemi pointe légèrement vers le bas, et une tête qui la suivrait droit devant basculerait vers l’avant. Mettre le y de la direction à 0 la maintient à l’horizontale : la tête tourne donc uniquement autour de l’axe vertical. Une lampe de phare qui suit un navire :
Vector3 toShip = ship.position - lamp.position;
toShip.y = 0f;
lamp.rotation = Quaternion.LookRotation(toShip);Quaternion.LookRotation(direction) est la rotation qui fait face à cette direction, donc la lampe se tourne aussitôt vers le navire. La tête d’une tour devrait plutôt tourner à une certaine vitesse : Quaternion.RotateTowards(from, to, maxDegrees), présenté dans le chapitre sur les rotations, tourne d’au plus maxDegrees, et une vitesse de rotation en degrés par seconde multipliée par Time.deltaTime donne la part de chaque image.Défi
MoyenTournez la tête de chaque tour pour qu’elle fasse face à sa cible.
- Dans
Tower, ajoutez[SerializeField] private Transform head;et[SerializeField] private float turnSpeed = 270f;. - Lorsqu’une cible est présente, tournez
headvers elle autour de l’axe y uniquement, d’au plusturnSpeed * Time.deltaTimedegrés, avecQuaternion.RotateTowards. - Tirez depuis le canon :
head.position + head.forward * 0.6f.
Appuyez sur « Jouer » : les têtes suivent les ennemis et tirent depuis le canon. Puis appuyez sur « Vérifier ».
Essayez vous-même
using UnityEngine;
public class Tower : MonoBehaviour
{
public float range = 4f;
public int damage = 2;
[SerializeField] private Projectile projectilePrefab;
private Enemy target;
private float nextShot;
void Update()
{
Enemy found = FindTarget();
if (found != null && found != target)
{
Debug.Log("Target: " + found.name);
}
target = found;
if (target == null)
{
return;
}
if (Time.time >= nextShot)
{
Fire();
nextShot = Time.time + 1f;
}
}
Enemy FindTarget()
{
Enemy nearest = null;
float nearestDistance = range;
foreach (Enemy enemy in Enemy.All)
{
float distance = Vector3.Distance(transform.position, enemy.transform.position);
if (distance <= nearestDistance)
{
nearest = enemy;
nearestDistance = distance;
}
}
return nearest;
}
void Fire()
{
Projectile shot = Instantiate(projectilePrefab, transform.position + Vector3.up, Quaternion.identity);
shot.Launch(target.transform, damage);
}
}
Toutes les leçons de Jeu Unity : défense de tours
Entraînez-vous par vous-même : Playground Unity