Menu
CoddyTech

Yükseltme

Coddy'nin Unity Oyunu: Kule Savunması kursunda ders 12 / 18.

Bir kuleye tıklandığında, seviyesini ve bir Yükselt düğmesini içeren bir panel açılır. Her seviye kulenin hasarını ve menzilini artırır ve her yükseltme bir öncekinden daha pahalıdır. Seviyeler bir kurala göre ilerler; bu nedenle varlık, bir sayı listesi yerine kuralı barındırır: 1. seviyedeki özellikler, her seviyenin ekledikleri ve bir yükseltmenin fiyatı. ScriptableObject üzerindeki metotlar gerisini hesaplar; böylece soran her betik aynı yanıtı alır. Bir çiftlik oyunundaki ürünün verimi:

public int YieldAt(int level)
{
    return baseYield + yieldPerLevel * (level - 1);
}

Kule yalnızca kendi level değerini tutar ve panel, oyuncunun parasının karşılığında ne alacağını görebilmesi için sonraki seviyenin sayılarını mevcut seviyeninkilerin yanında gösterir. Bir kuleye tıklamak, kulenin çocukları olan parçalarından birine, tabanına veya tepesine isabet eder; bu nedenle hit.collider.GetComponentInParent<Tower>(), bu parçaların ait olduğu kuleyi bulur: isabet edilen nesneye, ardından üst nesnelerine bakar.

Panel, 3D görünümün üzerinde yer alan bir kullanıcı arayüzüdür ve Yükselt düğmesine tıklamak, BuildManager'ın gördüğü bir fare basışıdır. Işın düğmeden geçerek arkasındaki zemine ulaşır ve BuildManager, düğme bırakılmadan önce paneli kapatır. İşaretçi kullanıcı arayüzünün üzerindeyken EventSystem.current.IsPointerOverGameObject() true olur; bu nedenle BuildManager erkenden geri döner ve bu tıklamaları düğmelere bırakır.

challenge icon

Görev

Orta
  1. TowerData içinde maxLevel, upgradeCost ve damagePerLevel genel tam sayılarını, ayrıca rangePerLevel genel kayan noktalı sayısını ekle. int DamageAt(int level) ve float RangeAt(int level) metotlarını ekle: 1. seviyede varlığın kendi hasar ve menzil değerleri kullanılır, bunun üzerindeki her seviye seviye başına ilgili miktarı ekler. O seviyeden bir üst seviyeye çıkmanın bedeli olan int UpgradeCost(int level) metodunu ekle: upgradeCost ile seviyenin çarpımı.
  2. Tower içinde, 1'den başlayan özel bir level tam sayı alanı tut; bu değer public int Level => level; olarak okunabilsin. DamageAt(level) ile ateş et ve RangeAt(level) içindeki hedefleri hedef al. Seviyeye 1 ekleyen public void Upgrade() metodunu ekle.
  3. BuildManager içinde, bir kuleye tıklamak onu seçer; başka herhangi bir şeye tıklamak seçimi kaldırır (boş bir inşa alanına tıklamak yine de orada inşa yapar). Serileştirilmiş towerPanel yalnızca bir kule seçiliyken görünür; towerNameText içinde Arrow level 1, towerStatsText içinde iki satırda Damage 2 > 3 ve Range 4.5 > 5, upgradeLabel içinde ise Upgrade 40 gösterilir. maxLevel seviyesinde istatistiklerde yalnızca mevcut değerler gösterilir, etiket Max level der ve upgradeButton etkileşime kapalı olur.
  4. Yükseltme düğmesinin çağırdığı public void UpgradeSelected() metodunu yaz: en üst seviyenin altındayken ve GameManager yükseltme bedelini ödeyebiliyorken kuleyi yükselt ve paneli yenile. Update içinde arayüz üzerindeki tıklamaları yok say.

Play'e bas, bir kule inşa et, kuleye tıklayıp yükselt ve ardından Check'e bas.

Kendin dene

using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;
using TMPro;

public class BuildManager : MonoBehaviour
{
    [SerializeField] private GameManager game;
    [SerializeField] private Tower[] shop;
    [SerializeField] private Button[] shopButtons;
    [SerializeField] private Color chosenColor = new Color(1f, 0.85f, 0.3f);

    private Tower chosen;

    void Start()
    {
        for (int i = 0; i < shop.Length; i++)
        {
            Tower prefab = shop[i];
            shopButtons[i].GetComponentInChildren<TMP_Text>().text = prefab.data.towerName + "\n" + prefab.data.cost;
            shopButtons[i].onClick.AddListener(() => Choose(prefab));
        }
        Choose(shop[0]);
    }

    void Choose(Tower prefab)
    {
        chosen = prefab;
        for (int i = 0; i < shop.Length; i++)
        {
            shopButtons[i].image.color = shop[i] == chosen ? chosenColor : Color.white;
        }
    }

    void Update()
    {
        if (!Mouse.current.leftButton.wasPressedThisFrame)
        {
            return;
        }

        Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue());
        if (Physics.Raycast(ray, out RaycastHit hit) && hit.collider.TryGetComponent(out BuildPad pad))
        {
            Build(pad);
        }
    }

    void Build(BuildPad pad)
    {
        if (pad.tower != null)
        {
            return;
        }

        if (!game.TrySpend(chosen.data.cost))
        {
            Debug.Log("Not enough money");
            return;
        }

        pad.tower = Instantiate(chosen, pad.transform.position, Quaternion.identity);
    }
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Unity Oyunu: Kule Savunması bölümündeki tüm dersler