Menu
CoddyTech

Geçişler

Coddy'nin Unity Journey'sinin Unity'de Oyun Mimarisi bölümünün bir parçası. Ders 30 / 50.

Durumun ne zaman değişeceğine kim karar verir? Kararı sahibi verirse, switch'te olduğu gibi tüm kurallar yeniden tek bir Update içinde toplanır. Genellikle her durumun kendi çıkış yolunu bildiği kabul edilir: Tick içinde koşulunu denetler ve makineden sonraki duruma geçmesini ister. Bu bomba, oyuncu yaklaşana kadar bekler, ardından fitilini yakar ve oyuncu kaçarsa bekleme durumuna geri döner:

public class Bomb : MonoBehaviour
{
    public Transform player;
    public StateMachine machine = new StateMachine();
    public IState idle;
    public IState fuse;

    void Start()
    {
        idle = new IdleState(this);
        fuse = new FuseState(this);
        machine.ChangeState(idle);
    }

    void Update() { machine.Tick(); }

    public bool PlayerNear()
    {
        return Vector3.Distance(transform.position, player.position) < 3f;
    }
}

public class IdleState : IState
{
    private Bomb bomb;
    public IdleState(Bomb bomb) { this.bomb = bomb; }

    public void Enter() { }
    public void Exit() { }

    public void Tick()
    {
        if (bomb.PlayerNear()) bomb.machine.ChangeState(bomb.fuse);
    }
}

public class FuseState : IState
{
    private Bomb bomb;
    private float timer;
    public FuseState(Bomb bomb) { this.bomb = bomb; }

    public void Enter() { timer = 2f; }
    public void Exit() { }

    public void Tick()
    {
        if (!bomb.PlayerNear())
        {
            bomb.machine.ChangeState(bomb.idle);
            return;
        }
        timer -= Time.deltaTime;
        if (timer <= 0f)
        {
            Debug.Log("Boom!");
            Object.Destroy(bomb.gameObject);
        }
    }
}

Her durum, yapıcısında bombayı alır ve onun üzerinden makineye, oyuncu denetimine ve diğer durumlara erişir. Bomba, Start içinde her durumu bir kez oluşturur; böylece bir durum new kullanarak başka bir durum oluşturmaz: yapıcılarında birbirlerini oluşturan iki durum, yığın taşana kadar döngüye girer. Bombanın Update'i yalnızca makineyi tick eder ve kurallar ait oldukları durumlarda yer alır: 2 saniyelik fitilin yönetimi yalnızca FuseState'e aittir.

ChangeState, FuseState'in Exit ve IdleState'in Enter metotlarını hemen çalıştırır; ancak çağrıdan sonra FuseState'in Tick metodunun geri kalanı yine de çalışır. return bunu durdurur; aksi takdirde fitil, çoktan sona ermiş bir durum için bir kare daha yanardı. Destroy, Object.Destroy olarak yazılır: bir MonoBehaviour bunu Unity'nin Object sınıfından miras alır, düz bir sınıfta ise sınıfın adını belirtmek gerekir.

challenge icon

Görev

Orta

Bir sinekkapan, yanına gelen herkese kapanır. Flytrap.cs hazır: makineyi ve üç durumu (open, snap ve chew genel alanlarını) oluşturur, Open durumuyla başlar ve makineyi her karede çalıştırır; PlayerInReach() ise oyuncunun zeminde 2 birimden daha yakında olup olmadığını belirtir. FlytrapStates.cs dosyasında her Enter yazılmıştır (renkler, zamanlayıcılar ve Chomp! günlüğü). Her durumun Tick metodunda geçişleri yaz:

  • Open: oyuncu menzildeyse tuzak kapanır.
  • Snap 0.5 saniye sürer. Ardından oyuncu hâlâ menzildeyse tuzak çiğner; oyuncu kaçtıysa tekrar açılır.
  • Chew, çevrede kim olursa olsun, 3 saniye sürer ve ardından tuzak tekrar açılır.

Ok tuşları Player'ı hareket ettirir. Play'e bas, tuzağa doğru yürü, ardından ondan kaçmayı dene ve sonra Check'e bas.

Kendin dene

using UnityEngine;

public class OpenState : IState
{
    private Flytrap trap;

    public OpenState(Flytrap trap)
    {
        this.trap = trap;
    }

    public void Enter()
    {
        trap.Paint(new Color(0.3f, 0.8f, 0.2f));
    }

    public void Tick()
    {
        // Oyuncu menzile girdiğinde kapan
    }

    public void Exit()
    {
    }
}

public class SnapState : IState
{
    private Flytrap trap;
    private float timer;

    public SnapState(Flytrap trap)
    {
        this.trap = trap;
    }

    public void Enter()
    {
        timer = 0f;
        trap.Paint(new Color(1f, 0.55f, 0.1f));
    }

    public void Tick()
    {
        // 0.5 saniye sonra: oyuncu hâlâ menzildeyse çiğne, değilse yeniden açıl
    }

    public void Exit()
    {
    }
}

public class ChewState : IState
{
    private Flytrap trap;
    private float timer;

    public ChewState(Flytrap trap)
    {
        this.trap = trap;
    }

    public void Enter()
    {
        timer = 3f;
        trap.Paint(new Color(0.5f, 0.05f, 0.1f));
        Debug.Log("Chomp!");
    }

    public void Tick()
    {
        // 3 saniye sonra: yeniden açıl
    }

    public void Exit()
    {
    }
}
quiz iconKendini test et

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

Unity'de Oyun Mimarisi bölümündeki tüm dersler