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.
Görev
OrtaTowerDataiçindemaxLevel,upgradeCostvedamagePerLevelgenel tam sayılarını, ayrıcarangePerLevelgenel kayan noktalı sayısını ekle.int DamageAt(int level)vefloat 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 olanint UpgradeCost(int level)metodunu ekle:upgradeCostile seviyenin çarpımı.Toweriçinde, 1'den başlayan özel birleveltam sayı alanı tut; bu değerpublic int Level => level;olarak okunabilsin.DamageAt(level)ile ateş et veRangeAt(level)içindeki hedefleri hedef al. Seviyeye 1 ekleyenpublic void Upgrade()metodunu ekle.BuildManageriç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ştowerPanelyalnızca bir kule seçiliyken görünür;towerNameTextiçindeArrow level 1,towerStatsTextiçinde iki satırdaDamage 2 > 3veRange 4.5 > 5,upgradeLabeliçinde iseUpgrade 40gösterilir.maxLevelseviyesinde istatistiklerde yalnızca mevcut değerler gösterilir, etiketMax levelder veupgradeButtonetkileşime kapalı olur.- 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.Updateiç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);
}
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.