Unity 2D Oyun Geliştirme: Karakter Hareket Mantığı

03.02.2026
Burak Erol
46 Görüntülenme
Unity 2D Oyun Geliştirme: Karakter Hareket Mantığı

Unity 2D Oyun Geliştirme: Karakter Hareket Mantığı

Unity ile 2D oyun geliştirirken en temel ihtiyaçlardan biri karakter kontrolü kurmaktır. Oyuncunun “sağa sola yürümesi” basit gibi görünse de, yanlış kurulan bir hareket sistemi ileride çarpışma problemleri, kayma hissi, zıplama tutarsızlığı ve mobilde FPS dalgalanmaları gibi birçok sorunu beraberinde getirebilir.

2D tarafta en sağlıklı yaklaşım genellikle Rigidbody2D bileşeni ile fizik tabanlı bir hareket sistemi kurmaktır. Böylece Unity’nin fizik motoru (Collider2D, sürtünme, yerçekimi) ile uyumlu, daha doğal ve akıcı bir kontrol elde edersiniz.

Hedef: Akıcı, Tutarlı ve Fizikle Uyumlu Hareket

İyi bir karakter hareket mantığı şu üç temel ayağa oturur:

  • Doğru Input Okuma: Tuş basışlarını yakalamak (Klavye, Gamepad, Dokunmatik).
  • Fizikle Uyum: Karakterin duvarlardan geçmemesi ve zeminle doğru etkileşimi.
  • Zamanlama (Timing): Kodun hangi döngüde (Loop) çalıştığı.

1) Kritik Soru: Update mi, FixedUpdate mi?

Unity geliştiricilerinin en sık yaptığı hatalardan biri, fizik kodlarını yanlış yere yazmaktır. Bu farkı anlamak hayati önem taşır:

Metot Ne Zaman Çalışır? Ne İçin Kullanılır?
Update() Her karede (Frame) bir kez. (FPS'e göre değişir) Input okuma, Timer işlemleri, Basit animasyonlar.
FixedUpdate() Sabit aralıklarla (Varsayılan 0.02sn). Rigidbody işlemleri (Velocity, AddForce), Fizik hesaplamaları.

Kural Şudur: Tuşa basıldığını Update içinde algıla, karakteri FixedUpdate içinde hareket ettir. Eğer fiziği Update içinde yaparsan, oyunu 30 FPS'de oynayan biri ile 144 FPS'de oynayan biri farklı hızlarda hareket eder.


2) Input System: Eski ve Yeni Yöntem

A) Klasik Yöntem (Input Manager)

Hızlı prototipler için hâlâ geçerlidir. Input.GetAxis size -1 ile 1 arasında bir değer döner.

// InputManager Kullanımı
void Update() {
    // -1 (Sol), 0 (Dur), 1 (Sağ)
    float moveInput = Input.GetAxisRaw("Horizontal"); 
}

B) Yeni Input System (Paket)

Unity'nin yeni nesil sistemi Event (olay) tabanlı çalışır. Gamepad takıldığı an algılar, tuş atamaları (remapping) çok kolaydır.

// Yeni Input System Kullanımı
// Input Action kütüphanesini eklemeyi unutmayın
using UnityEngine.InputSystem;

public class PlayerMovement : MonoBehaviour {
    
    Vector2 moveVector;

    // Unity Event üzerinden tetiklenir
    public void OnMove(InputAction.CallbackContext context) {
        // Tuşa basınca veya çekince değeri okur
        moveVector = context.ReadValue<Vector2>();
    }
}

3) Fizik vs Transform: Hangisi Kullanılmalı?

Karakteri transform.Translate ile hareket ettirmek, onu bir noktadan diğerine "ışınlamak" gibidir. Fizik motorunu devre dışı bırakır. Bu yüzden duvara gömülme sorunları yaşanır.

Doğru Yöntem: Rigidbody2D Velocity

Karakterin hızını doğrudan manipüle etmektir. Platform oyunları için en "tok" ve kontrollü hissi bu verir.


Örnek: Tam Teşekküllü Karakter Kontrol Kodları

Aşağıdaki kod bloğu; Input'u Update'de alır, hareketi FixedUpdate'de uygular ve karakterin yüzünü gittiği yöne çevirir.

// PlayerController.cs
using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
public class PlayerController : MonoBehaviour
{
    [Header("Ayarlar")]
    public float moveSpeed = 8f;

    private Rigidbody2D rb;
    private float moveInput;
    private bool isFacingRight = true;

    void Awake()
    {
        // Bileşeni otomatik bul
        rb = GetComponent<Rigidbody2D>();
    }

    // Inputları buradan okuyoruz (Her frame)
    void Update()
    {
        moveInput = Input.GetAxisRaw("Horizontal");
        
        // Karakteri döndürme kontrolü
        if (moveInput > 0 && !isFacingRight) Flip();
        else if (moveInput < 0 && isFacingRight) Flip();
    }

    // Fiziği buradan uyguluyoruz (Sabit zaman aralığı)
    void FixedUpdate()
    {
        // y eksenindeki hızı (velocity.y) koruyoruz ki yerçekimi bozulmasın
        rb.velocity = new Vector2(moveInput * moveSpeed, rb.velocity.y);
    }

    // Karakterin yönünü çeviren fonksiyon
    void Flip()
    {
        isFacingRight = !isFacingRight;
        Vector3 scaler = transform.localScale;
        scaler.x *= -1;
        transform.localScale = scaler;
    }
}

Neden GetAxisRaw?

  • GetAxis: Tuşa basınca değer yavaş yavaş 0'dan 1'e çıkar. Buzda kayıyormuş hissi verir.
  • GetAxisRaw: Değer direkt 0 veya 1 olur. Mario/Celeste gibi "zınk" diye duran, hassas kontroller için bu kullanılır.

Hareket Kalitesini Artıran "Pro" Ayarlar

  1. Interpolate (Rigidbody Ayarı): Eğer karakter hareket ederken titriyorsa, Rigidbody2D bileşenindeki Interpolate seçeneğini "Interpolate" yapın. Bu, kareler arasındaki geçişi yumuşatır.
  2. Collision Detection: Karakter çok hızlıysa ve ince duvarlardan geçiyorsa (tünelleme), bu ayarı "Continuous" yapın.
  3. Freeze Rotation Z: Karakterinizin top gibi yuvarlanmasını istemiyorsanız, Rigidbody2D > Constraints altından Freeze Rotation Z kutucuğunu işaretleyin.

Sonuç

Unity 2D oyunlarda karakter hareket mantığını doğru kurmak, oyunun “hissiyatını” belirleyen en temel adımdır. Kodunuzu yazarken Input ve Fizik döngülerini ayırmaya, Transform yerine Rigidbody kullanmaya özen gösterin. Unutmayın; iyi bir oyun, oyuncunun kontrolcüye verdiği komuta anında ve tutarlı tepki veren oyundur.