Oyuncular nerede takılıyor, hangi bölümü bırakıyor — veri size söylüyor
[/CENTER>
Merhaba!
"Oyuncular bu seviyeyi zor buluyor mu?" sorusunun cevabını tahmin etmek yerine, analitik verilerle ölçmek çok daha güvenilir. Bu konuda oyun içi analitik entegrasyonunu ve kullanımını derinlemesine ele aldım.
C#:
// Unity — basit bir oyun analitik sistemi implementasyonu
using UnityEngine;
using System.Collections.Generic;
using System;
[System.Serializable]
public class AnalitikOlayi
{
public string olayAdi;
public Dictionary<string, object> parametreler;
public string zamanDamgasi;
public string oturumId;
}
public class OyunAnalitikYoneticisi : MonoBehaviour
{
public static OyunAnalitikYoneticisi Instance { get; private set; }
private string mevcutOturumId;
private List<AnalitikOlayi> bekleyeneOlaylar = new List<AnalitikOlayi>();
private float oturumBaslangicZamani;
void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
OturumBaslat();
}
else
{
Destroy(gameObject);
}
}
void OturumBaslat()
{
mevcutOturumId = Guid.NewGuid().ToString();
oturumBaslangicZamani = Time.time;
OlayKaydet("oturum_baslangic", new Dictionary<string, object>
{
{ "platform", Application.platform.ToString() },
{ "oyun_versiyonu", Application.version }
});
}
public void OlayKaydet(string olayAdi, Dictionary<string, object> parametreler = null)
{
var olay = new AnalitikOlayi
{
olayAdi = olayAdi,
parametreler = parametreler ?? new Dictionary<string, object>(),
zamanDamgasi = DateTime.UtcNow.ToString("o"),
oturumId = mevcutOturumId
};
bekleyeneOlaylar.Add(olay);
Debug.Log($"📊 Analitik olayı kaydedildi: {olayAdi}");
// Belirli sayıda olay birikince veya periyodik olarak sunucuya gönder
if (bekleyeneOlaylar.Count >= 20)
{
OlaylariGonder();
}
}
// ─── ÖZEL OYUN OLAYLARI İÇİN YARDIMCI METODLAR ──
public void SeviyeBaslangiciKaydet(int seviyeNo)
{
OlayKaydet("seviye_baslangic", new Dictionary<string, object>
{
{ "seviye_no", seviyeNo },
{ "oturum_suresi", Time.time - oturumBaslangicZamani }
});
}
public void SeviyeTamamlamaKaydet(int seviyeNo, float sureSaniye, int denemeye)
{
OlayKaydet("seviye_tamamlandi", new Dictionary<string, object>
{
{ "seviye_no", seviyeNo },
{ "sure_saniye", sureSaniye },
{ "deneme_sayisi", denemeye }
});
}
public void OyuncuOlumKaydet(int seviyeNo, Vector3 konum, string olumNedeni)
{
// Bu tür veriler, "zorluk ısı haritası" oluşturmak için çok değerli —
// hangi bölgelerde oyuncular en çok ölüyor görsel olarak görülebilir
OlayKaydet("oyuncu_oldu", new Dictionary<string, object>
{
{ "seviye_no", seviyeNo },
{ "konum_x", konum.x },
{ "konum_y", konum.y },
{ "konum_z", konum.z },
{ "olum_nedeni", olumNedeni }
});
}
public void SeviyeBirakmaKaydet(int seviyeNo, float oynananSureSaniye)
{
// Oyuncu oyunu kapattığında/menüye döndüğünde tetiklenmeli —
// bu, "nerede sıkıldılar" sorusuna cevap veriyor
OlayKaydet("seviye_birakildi", new Dictionary<string, object>
{
{ "seviye_no", seviyeNo },
{ "oynanan_sure", oynananSureSaniye }
});
}
void OlaylariGonder()
{
// Gerçek projede burada bir HTTP isteği ile
// backend analitik servisine (kendi sunucunuz veya
// Firebase Analytics/GameAnalytics gibi üçüncü parti) gönderim yapılır
Debug.Log($"📤 {bekleyeneOlaylar.Count} olay sunucuya gönderiliyor...");
bekleyeneOlaylar.Clear();
}
void OnApplicationPause(bool duraklatildi)
{
if (duraklatildi)
{
OlaylariGonder(); // Uygulama arka plana atılırken veriyi kaybetmeyin
}
}
}
Hangi verilerle önemli tasarım kararı aldınız? Deneyimlerinizi paylaşın!