Modern oyun geliştirme, oyunculara esneklik sunmayı gerektirir. Bu esnekliğin başında, oyun içi kontrolleri kendi tercihlerine göre ayarlayabilme, yani tuşları yeniden atayabilme (Unity Input Rebinding) ve farklı kontrolcü türlerini sorunsuz kullanabilme yeteneği gelir. Unity’nin eski giriş sistemi (Legacy Input Manager) bu konuda yetersiz kalırken, yeni Input System paketi, bu ihtiyaçları çok daha modern ve güçlü bir şekilde karşılamaktadır. Bu makalede, Unity’nin yeni Input System’ini kullanarak tuşları nasıl yeniden atayacağınızı, kontrolcü desteğini nasıl yöneteceğinizi ve bu süreçteki en iyi pratikleri öğreneceksiniz.
Giriş: Neden Yeni Input System?
Unity’nin eski giriş sistemi, basit projeler için yeterli olsa da, modern oyunların karmaşık ihtiyaçlarını karşılamakta zorlanıyordu. Özellikle çoklu platform desteği, gamepad’ler, dokunmatik ekranlar ve VR kontrolcüleri gibi farklı giriş cihazlarının yönetimi, eski sistemle oldukça zahmetliydi. Yeni Input System paketi ise bu sorunlara kökten bir çözüm getiriyor. İşte bazı temel avantajları:
- Cihaz Agnostik: Klavye, fare, gamepad, dokunmatik ekran veya özel kontrolcüler fark etmeksizin tüm girişleri tutarlı bir şekilde işler.
- Aksiyon Tabanlı: Tuş basımından ziyade, “Zıpla”, “Ateş Et” gibi aksiyonlar üzerinden çalışır. Bu, kontrol şemalarını değiştirmeyi kolaylaştırır.
- Asenkron ve Olay Tabanlı: Girişleri olaylar (events) aracılığıyla işleyerek daha performanslı ve tepkisel bir deneyim sunar.
- Gelişmiş Rebinding: Tuşları yeniden atama (Unity Input Rebinding) ve kontrol şemalarını özelleştirme için güçlü araçlar sağlar.
- Çoklu Oyuncu Desteği: Aynı anda birden fazla kontrolcüyü ve oyuncuyu kolayca yönetme imkanı sunar.
Input System Kurulumu ve Temelleri
Yeni Input System’i kullanmaya başlamak için öncelikle paketi projenize eklemeniz gerekir:
- Unity editöründe
Window > Package Manageryolunu izleyin. - Paket yöneticisinde
Unity Registryseçeneğini seçin. Input Systempaketini bulun veInstalldüğmesine tıklayın.- Kurulum tamamlandığında, Unity sizden eski giriş sistemini devre dışı bırakıp yeni sistemi etkinleştirmek isteyip istemediğinizi soracaktır. Bu soruyu kabul edin.
Input Actions Varlığı Oluşturma
Input System’in kalbi, Input Actions varlıklarıdır. Bu varlıklar, oyununuzdaki tüm giriş aksiyonlarını, bunlara atanmış tuşları (bindings) ve kontrol şemalarını (control schemes) tanımlar.
- Proje penceresinde sağ tıklayın:
Create > Input Actions. - Yeni oluşturulan varlığa çift tıklayarak Input Actions düzenleyicisini açın.
- Burada
Action Maps(örn: “Player”),Actions(örn: “Move”, “Jump”) ve bu aksiyonlara atanmışBindings(örn: “W” tuşu, “Space” tuşu) tanımlayabilirsiniz.
Her aksiyon için bir Action Type (örn: Button, Value, Pass-Through) ve beklenen bir Control Type (örn: Vector2, Float) belirlemeniz önemlidir. Örneğin, “Move” aksiyonu genellikle bir Value aksiyonu ve Vector2 kontrol tipi olurken, “Jump” aksiyonu bir Button aksiyonu ve Button kontrol tipi olacaktır.
PlayerInput Bileşeni
Bir GameObject’in girişleri işlemesi için ona PlayerInput bileşenini ekleyebilirsiniz. Bu bileşen, oluşturduğunuz Input Actions varlığına referans verir ve aksiyonları kodunuzda dinlemek için kullanabileceğiniz olayları (events) sağlar.
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerController : MonoBehaviour
{
private PlayerInput playerInput;
private InputAction moveAction;
private InputAction jumpAction;
void Awake()
{
playerInput = GetComponent<PlayerInput>();
moveAction = playerInput.actions.FindAction("Move");
jumpAction = playerInput.actions.FindAction("Jump");
moveAction.performed += OnMove;
jumpAction.performed += OnJump;
}
void OnMove(InputAction.CallbackContext context)
{
Vector2 inputVector = context.ReadValue<Vector2>();
Debug.Log("Hareket: " + inputVector);
}
void OnJump(InputAction.CallbackContext context)
{
Debug.Log("Zıplama!");
}
void OnEnable()
{
playerInput.actions.Enable();
}
void OnDisable()
{
playerInput.actions.Disable();
}
}
Unity Input Rebinding: Tuşları Yeniden Atama
Oyuncuların tuşları yeniden atayabilmesi, modern oyunların vazgeçilmez bir özelliğidir. Unity Input System, bu süreci oldukça kolaylaştırır. Temel olarak, bir aksiyonun belirli bir binding’ini interaktif olarak değiştirmek için InputActionRebindingExtensions.PerformInteractiveRebinding() metodunu kullanırız.
İnteraktif Rebinding Uygulaması
Bir tuşu yeniden atamak için aşağıdaki adımları izleyebilirsiniz:
- Yeniden atanacak binding’i belirleyin. Bu, bir
InputActioniçindeki belirli birInputBindingobjesi olabilir. PerformInteractiveRebinding()metodunu çağırın. Bu metod, kullanıcının yeni bir giriş yapmasını bekleyen bir işlem başlatır.- Kullanıcı bir giriş yaptığında, metod bu girişi yakalar ve binding’in
overridePathözelliğini günceller.
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;
public class RebindingManager : MonoBehaviour
{
public InputActionAsset actionsAsset;
public Text bindingDisplayText;
public Button rebindButton;
private InputAction rebindAction;
private int bindingIndex;
void Start()
{
// Yeniden atamak istediğimiz aksiyonu ve binding'i bulalım.
// Örnek: "Player" action map'indeki "Jump" aksiyonunun ilk binding'i.
rebindAction = actionsAsset.FindActionMap("Player").FindAction("Jump");
bindingIndex = rebindAction.bindings.IndexOf(x => x.action == rebindAction.id.ToString());
UpdateBindingDisplay();
rebindButton.onClick.AddListener(StartRebind);
}
void UpdateBindingDisplay()
{
if (rebindAction != null && bindingIndex != -1)
{
// Mevcut binding yolunu veya geçersiz kılınmış yolu göster.
bindingDisplayText.text = InputBindingResolver.ResolveBindingPath(rebindAction, bindingIndex);
}
}
public void StartRebind()
{
rebindButton.interactable = false;
bindingDisplayText.text = "Bekleniyor...";
rebindAction.PerformInteractiveRebinding(bindingIndex)
.WithCancelingThrough<Keyboard>() // ESC ile iptal etme
.WithCancelingThrough<Gamepad>() // Gamepad ile iptal etme
.OnComplete(operation =>
{
operation.Dispose();
rebindButton.interactable = true;
UpdateBindingDisplay();
SaveRebinds(); // Rebinding'i kaydet
})
.OnCancel(operation =>
{
operation.Dispose();
rebindButton.interactable = true;
UpdateBindingDisplay();
})
.Start();
}
// Rebinding verilerini kaydetme (örnek: PlayerPrefs kullanarak)
private void SaveRebinds()
{
string rebinds = rebindAction.SaveBindingOverridesAsJson();
PlayerPrefs.SetString("rebinds_jump", rebinds);
PlayerPrefs.Save();
Debug.Log("Rebinding kaydedildi: " + rebinds);
}
// Rebinding verilerini yükleme
private void LoadRebinds()
{
if (PlayerPrefs.HasKey("rebinds_jump"))
{
string rebinds = PlayerPrefs.GetString("rebinds_jump");
rebindAction.LoadBindingOverridesFromJson(rebinds);
Debug.Log("Rebinding yüklendi: " + rebinds);
UpdateBindingDisplay();
}
}
// Bu metodu Start() içinde veya uygun bir yerde çağırın
void Awake()
{
// ... (playerInput ve aksiyonları tanımlama)
LoadRebinds();
}
}
// Binding yolunu daha okunabilir hale getirmek için yardımcı sınıf
public static class InputBindingResolver
{
public static string ResolveBindingPath(InputAction action, int bindingIndex)
{
if (action == null || bindingIndex < 0 || bindingIndex >= action.bindings.Count)
{
return "N/A";
}
var binding = action.bindings[bindingIndex];
string path = action.GetBindingDisplayString(bindingIndex);
// Gamepad özel tuşları için daha iyi isimler
if (binding.path.Contains("gamepad"))
{
if (path.Contains("buttonSouth")) return "Gamepad A";
if (path.Contains("buttonEast")) return "Gamepad B";
if (path.Contains("buttonWest")) return "Gamepad X";
if (path.Contains("buttonNorth")) return "Gamepad Y";
if (path.Contains("leftTrigger")) return "Gamepad LT";
if (path.Contains("rightTrigger")) return "Gamepad RT";
if (path.Contains("leftShoulder")) return "Gamepad LB";
if (path.Contains("rightShoulder")) return "Gamepad RB";
if (path.Contains("leftStick")) return "Gamepad Sol Çubuk";
if (path.Contains("rightStick")) return "Gamepad Sağ Çubuk";
if (path.Contains("dpad")) return "Gamepad Yön Tuşları";
}
return path;
}
}
Yukarıdaki örnekte, SaveBindingOverridesAsJson() ve LoadBindingOverridesFromJson() metotları, tüm binding geçersiz kılmalarını bir JSON dizesi olarak kaydetmenizi ve yüklemenizi sağlar. Bu, Unity Input Rebinding verilerini kalıcı hale getirmek için kritik öneme sahiptir.
Kontrolcü Desteği ve Çoklu Oyuncu
Input System, kontrolcüleri otomatik olarak algılar ve yönetir. Klavyeden farklı olarak, gamepad’ler genellikle birden fazla oyuncu tarafından kullanılabilir. Input System, bu senaryoyu InputUser ve PlayerInputManager bileşenleri aracılığıyla kolayca yönetmenizi sağlar.
PlayerInputManager ile Çoklu Oyuncu
PlayerInputManager, otomatik olarak yeni kontrolcüler algıladığında yeni oyuncular oluşturabilir ve bunlara PlayerInput bileşenleri atayabilir. Bu, yerel çok oyunculu oyunlar için idealdir.
- Boş bir GameObject oluşturun ve ona
PlayerInputManagerbileşenini ekleyin. PlayerInputManagerbileşeninde, oyuncu prefab’inizi (üzerindePlayerInputbileşeni olan)Player Prefabalanına atayın.Join Behaviorayarını (örn:JoinPlayersWhenButtonIsPressed) veJoining Device Limitgibi diğer ayarları yapılandırın.
Artık yeni bir gamepad bağlandığında veya belirlenen bir tuşa basıldığında, PlayerInputManager otomatik olarak yeni bir oyuncu örneği oluşturacak ve ona uygun kontrolcüyü atayacaktır.
Cihaza Özel Bağlamalar (Device-Specific Bindings)
Bazen belirli bir cihaz türü için farklı tuş atamaları yapmak isteyebilirsiniz. Input System, Control Schemes ve binding’lerdeki device-specific yollar ile bunu destekler. Örneğin, bir binding’i sadece klavye için veya sadece Xbox kontrolcüsü için tanımlayabilirsiniz.
Pratik İpuçları
- Görsel Geri Bildirim: Rebinding işlemi sırasında oyuncuya hangi tuşa basması gerektiğini veya işlemin iptal edildiğini gösteren net görsel ve metinsel geri bildirimler sağlayın. Örneğin, “Yeni tuşa basın…” veya “İptal edildi” gibi mesajlar kullanın.
- Çakışan Tuş Atamalarını Yönetme: Bir tuşun zaten başka bir aksiyona atanmış olup olmadığını kontrol etmek ve oyuncuyu uyarmak, iyi bir kullanıcı deneyimi için önemlidir. `InputBinding` objelerinin
pathözelliklerini karşılaştırarak bu kontrolü yapabilirsiniz. Ancak, Input System paketi, çakışan bağlamaları doğrudan yöneten bir mekanizma sunmaz; bu genellikle oyun geliştiricisinin sorumluluğundadır. - Varsayılan Ayarlara Dönme: Oyunculara istedikleri zaman varsayılan tuş atamalarına geri dönme seçeneği sunun. Bunu, kaydedilmiş override’ları temizleyerek (
rebindAction.RemoveAllBindingOverrides()) ve ardından oyunun ilk halindeki binding’leri yeniden yükleyerek yapabilirsiniz.
Yaygın Hatalar ve Çözümleri
- Input Actions Varlığını Etkinleştirmeyi Unutmak: Aksiyonlarınızın çalışmadığını fark ederseniz,
playerInput.actions.Enable()veya belirli bir aksiyon haritası içinactionMap.Enable()metodunu çağırdığınızdan emin olun. Genellikle bu,OnEnable()metodunda yapılır. - Yanlış Control Type Seçimi: Bir aksiyon için yanlış
Control Type(örn: bir düğme içinVector2) seçmek, girişlerin doğru okunmamasına neden olabilir. Aksiyonunuzun beklediği veri tipine uygunControl Typeseçtiğinizden emin olun. - UI Navigasyonunda Sorunlar: Kontrolcülerle UI elementlerinde gezinmek için
EventSystem‘in doğru şekilde yapılandırıldığından emin olun. GenellikleStandalone Input ModuleyerineInput System UI Input Modulekullanmanız gerekir. - Rebinding Verilerini Kaydetmemek: Oyuncunun yaptığı tuş atamalarının oyun kapatıldığında kaybolduğunu fark ederseniz,
SaveBindingOverridesAsJson()veLoadBindingOverridesFromJson()metotlarını kullanarak bu verileri kalıcı olarak kaydettiğinizden ve yüklediğinizden emin olun. Bu, Unity Input Rebinding deneyiminin sürekliliği için hayati öneme sahiptir.
Performans ve Optimizasyon Notları
Yeni Input System, eski sisteme göre daha performanslıdır çünkü girişleri daha verimli bir şekilde işler ve gereksiz sorgulamalardan kaçınır. İşte bazı optimizasyon ipuçları:
- Olay Tabanlı Yaklaşım: Mümkün olduğunca
Update()döngüsünde sürekli giriş sorgulamak yerine, aksiyonlarınperformed,startedvecanceledolaylarını kullanın. Bu, sadece giriş olduğunda kodunuzun çalışmasını sağlar. - Gereksiz Aksiyonları Devre Dışı Bırakma: Bir aksiyon haritası (
Action Map) veya belirli bir aksiyon, o anda kullanılmıyorsa (örn: oyun duraklatıldığında veya menüdeyken), bunlarıDisable()metodu ile devre dışı bırakın. Bu, Input System’in işleyeceği giriş miktarını azaltır. - Tek PlayerInput Yöneticisi: Çoklu oyuncu senaryolarında,
PlayerInputManager‘ı tek bir yerde yönetmek, giriş akışını merkezileştirir ve potansiyel performans sorunlarını azaltır.
Sonuç
Unity’nin yeni Input System paketi, modern oyunların giriş yönetimi ihtiyaçlarını karşılamak için güçlü ve esnek bir çözüm sunar. Unity Input Rebinding özelliği sayesinde oyunculara kontrol şemalarını özelleştirme imkanı tanımak, kullanıcı deneyimini önemli ölçüde artırır. Bu makalede ele aldığımız temel kurulum, aksiyon tanımlama, interaktif tuş atama, kontrolcü desteği ve pratik ipuçları ile kendi Unity projelerinizde gelişmiş giriş sistemleri oluşturmaya hazırsınız. Unutmayın, iyi tasarlanmış bir giriş sistemi, oyununuzun erişilebilirliğini ve keyfini artırmanın anahtarıdır.



