Menu
CoddyTech

כוונון

שיעור 10 מתוך 25 בקורס משחק Unity: הגנת מגדלים של Coddy.

מגדל פונה לעבר המטרה שלו: לא המגדל כולו, שעומד על המשטח שלו, אלא הראש שלו, אובייקט-בן שנושא את הקנה. סיבוב של אובייקט-בן מסובב את כל מה שמתחתיו ומשאיר את אובייקט-האב כפי שהוא.

האויבים הולכים נמוך יותר מהראשים, ולכן הכיוון מראש אל האויב פונה מעט כלפי מטה, וראש שהיה פונה ישר לאורכו היה נוטה קדימה. הגדרת y של הכיוון ל-0 משאירה אותו אופקי, כך שהראש מסתובב רק סביב הציר האנכי. מנורת מגדלור שעוקבת אחרי ספינה:

Vector3 toShip = ship.position - lamp.position;
toShip.y = 0f;
lamp.rotation = Quaternion.LookRotation(toShip);
Quaternion.LookRotation(direction) היא הסיבוב שפונה לכיוון הזה, ולכן המנורה מסתובבת מיד לעבר הספינה. ראש של מגדל צריך להסתובב במהירות מסוימת במקום זאת: Quaternion.RotateTowards(from, to, maxDegrees) מפרק הסיבוב מסובבת לכל היותר ב-maxDegrees, ומהירות סיבוב במעלות לשנייה כפול Time.deltaTime נותנת את החלק של כל פריים.
challenge icon

אתגר

בינוני

סובבו את הראש של כל צריח כך שיפנה אל המטרה שלו.

  1. ב־Tower, הוסיפו [SerializeField] private Transform head; וגם [SerializeField] private float turnSpeed = 270f;.
  2. כאשר יש מטרה, סובבו את head לכיוונה סביב ציר y בלבד, לכל היותר ב־turnSpeed * Time.deltaTime מעלות, באמצעות Quaternion.RotateTowards.
  3. ירו מקנה הצריח: head.position + head.forward * 0.6f.

לחצו על "שחק": הראשים עוקבים אחרי האויבים ויורים מקנה הצריח. לאחר מכן לחצו על "בדיקה".

נסו בעצמכם

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);
    }
}

כל השיעורים ביחידה משחק Unity: הגנת מגדלים

תרגלו בעצמכם: Unity אונליין