Unity MYSQL Bağlantısı (Hesap Oluşturma ve Giriş Kontrolü)

Unity MySQL Bağlantısı Kurma


Unity MYSQL Bağlantısı (Hesap Oluşturma ve Giriş Kontrolü)

 Hepinize merhaba arkadaşlar bu yazımda sizlere Unity de nasıl oyununuza kullanıcı girişi ve oyuncunun hesap oluşturma sistemini yapacağınızdan bahsedeceğim, aslında oldukça kolay bir yöntem ile bunları kontrol edebiliyorsunuz burada tek gereken şey aslında web tasarımı konusunda biraz bilginizin olması gerektiği çünkü Unity de MYSQL bağlantısını direkt olarak C# ile değil bir internet sitesi üzerinden Unity de bulunan WWW yapıları ile yapıyoruz.

WWW ve WWWForm nedir bilmeyenleriniz varsa direkt konu hakkında araştırma yapmadan buraya gelenleriniz onları bir buradaki yazıya alayım, WWW ve WWWForm hakkında bilgi edindikten sonra gelip buraya baktığınız zaman çok daha rahat bir şekilde burada anlatmak istediğimi anlayacağınızı düşünüyorum.

Mantığın Kavranması

Bir programı ezbere kullanabilirsiniz ama yazılımda böyle bir şey aslında pek de mümkün olmuyor bu yüzden bu işin kısaca bir mantığından size bahsetmek istiyorum, yani WWW kullanarak nasıl Unity üzerinden MySQL bağlantısı kurulur bunun mantığını kavrayalım, sistem nasıl çalışır görelim.

İlk olarak kullanıcının verilerini Database e gönderebilmek için PHP ile basit bir script yazıyoruz, ben bu proje için 2 adet Php sayfası kodladım. İlki kullanıcı hesabı oluşturmak için diğeri ise kullanıcı girişini yapabilmesi için.

Daha sonrasında Unity de ara yüzü oluşturduktan sonra MySQLHelper isimli bir C# dosyası oluşturdum ve içerisinden kullanıcıdan gelen verileri gerekli sayfalara yönlendirmesini ve siteden gelen dönütlere göre ekrana Debug çıktısı yazdırmasını sağladım.

Veri Tabanı ve Web Kısmının Yapılması

İlk olarak herhangi bir web hostuna sahip olmadığın için bilgisayarıma MAMP isimli web host yazılımını kuruyorum ve içerisinden Apache ve MySQL e start veriyorum.

MAMP indirmek için buradaki bağlantıyı kullanabilirsiniz.

Veri Tabanı Oluşturulması

Veri tabanı oluşturmak için "http://localhost/MAMP/index.php?page=phpmyadmin&language=English" adresine gitmeniz gerekiyor.(MAMP indirenler için geçerli.)

İlk olarak sol taraftan "New" kısmına basıyor ve yeni bir veri tabanı oluşturuyoruz.

Unity MySQL Bağlantısı

Burada deneme yazan kısma veri tabanınıza vermek istediğiniz ismi yazabilirsiniz, Türkçe karakter kullanmamanızı öneriyorum. Veri tabanı ismini verdiğimiz yerin hemen sağında bulunan "utf8-bin" ise evrensel ascii kodlarını kabul ettiğini gösterir ve ileride kullanıcılar Türkçe karakter ile hesaplar açtığı zaman sıkıntı yaşamaları için seçmeniz gereken veri tipidir. "utf8-turkish-ci" de seçerseniz aynı sonucu verecektir.
Bu işlemleri yaptıktan sonra artık "Create" butonuna bastığınız zaman veri tabanınız oluşmuş olacaktır.

Unity MySQL Veri Tabanı2


Eğer ki şimdiye kadar olan işlemleri doğru olarak yaptıysak ve herhangi bir sorun ile karşılaşmadıysak karşımıza yukarıdaki gibi bir ekran gelecektir burada veri tablosu oluşturmamız gerekiyor.
Kullanıcı hesaplarını tutan bir veri tablosu oluşturacağım için "Name" kısmına "hesaplar" yazıyor ve yanındaki 4 olan kısım kaç adet veri olacağını soruyor. Aklımda 5 adet veriyi tutmak olduğu için 4 ü 5 yapıyor ve "Go" butonuna tıklayıp devam ediyorum.

MySQL Veri Tabanı3

Karşımıza aşağıdaki gibi bir ekran gelecektir, burada tutacağımız verilerin isimlerini ve veri tiplerini belirleyeceğiz. Tabi bir de otomatik oluşacak veri tiplerine otomatik olduğunu işaretleyeceğiz.

Unity MySQL Veri Tabanı 4


Burada ben "id", "kadi", "mail", "pass", "time" olarak 5 adet veri tutacağım bunlardan 2 tanesi otomatik olarak tanımlanacak veriler.
"id" ve "time" otomatik olarak tanımlanacaklar.
Bu tuttuğum verilerin ne işe yaradıklarını merak ediyorsanız hemen cevaplayayım.
id : Kullanıcının hesap id si olarak kullanılacak ve kaçıncı sırada hesap açtığını gösterecek diyebilirim, "int" olarak işaretlenmesi gerekiyor ve en sağ tarafta bulunan "AI" kısmına tik atmanız gerekiyor..
kadi : Kullanıcı adı olarak görev alacak veri. "Text" olarak işaretlenmesi gerekiyor.
mail : Kullanıcının mail bilgisini barındıran veri. "Text" olarak işaretlenmesi gerekiyor.
pass : Kullanıcının şifresini barındıran veri. "Text" olarak işaretlenmesi gerekiyor..
time : Otomatik olarak kullanıcının hangi tarih aralığında hesap açtığı bilgisini barındıran veri. "TimeStamp" olarak işaretlenmesi gerekiyor ve "Default" kısmında "Current_TimeStamp" seçilmesi gerekiyor.

Not : Veri tablonuzu benim gibi rastgele isimlendirmelerde bulunmayın siz daha düzenli ve düzgün isimler atayın...


Unity MySQL5

Unity MySQL6

Buradaki verileri doğru bir şekilde girdiyseniz artık "Save" butonuna tıklayın ve veri tablonuzu oluşturun.

Unity MySQL 7

Bu şekilde bir ekran ile karşılaştıysanız ve herhangi bir sorun karşınıza çıkmadıysa veri tabanı kısmı ile ilgili artık bir sorun kalmamış ve yeni bir işlem yapmanız gerekmiyor demektir.

Web Scriptlerinin Yazılması

Yazdığımız scriptleri "C:\MAMP\htdocs\" içerisine atacaksınız tabi htdocs kısmını içinde herhangi bir dosyaya da atabilirsiniz ben "C:\MAMP\htdocs\UnityMySQL" şeklinde bir yere koydum web kodlarını. Tabi burada attığınız dosya konumu aslında sizin erişeceğiniz URL yapısını değiştirmektedir.

config.php MySQL veri tabanına bağlanmak için gerekli kullanıcı bilgilerini sakladığım Php script dosyası ve içerisi MAMP için şu şekilde
<?PHP
    $host = "localhost"; // MySQL Host
    $host_username = "root"; // MySQL kullanıcı adı
    $host_password = "root"; // MySQL şifresi
    $host_database = "deneme"; // MySQL veri tabanı
?>

girisyap.php MySQL veri tabanına bağlanıp gelen kullanıcı bilgilerini sorguluyor ve eşleşiyor ise kullanıcı girdi bilgisi yolluyoruz.

<?PHP
    include "config.php"; // config.php yi çağırıyoruz

    if(isset($_POST["kullaniciAdi"], $_POST["sifre"])){ // Kullanıcı adı ve şifre verileri gelmişmi kontrol ediyoruz.
        try{ // Hata denetleyicisi başlatıyoruz
            $kullaniciAdi = $_POST["kullaniciAdi"]; // Gelen kullanıcı adı verisini kullaniciAdi değişkenine atıyoruz.
            $sifre = $_POST["sifre"]; // Gelen şifre verisini sifre değişkenine atıyoruz

            $baglanti = new PDO("mysql:host=".$host.";dbname=".$host_database."" , $host_username, $host_password); // veri tabanına bağlanıyoruz.
            $baglanti -> exec("SET NAMES utf8"); // Veri tabanında karakter hatası yaşamamak için karakter setini değiştiriyoruz.
            $baglanti -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Hataları denetliyoruz..

            $sorgu = $baglanti -> query("SELECT * FROM hesaplar WHERE kadi = '$kullaniciAdi' && pass = '$sifre'", PDO::FETCH_ASSOC); // Veri tablosuna bağlanıyoruz ve kullanıcıyı arıyoruz.
            if($sorgu->rowCount()){ // Kullanıcı varsa
                echo "1"; // ekrana 1 yazdırıyoruz
            }else{
                echo "0"; // Kullanıcı yoksa ekrana 0 yazdırıyoruz.
            }           
            // Not : buradaki 1 ve 0 ile Unity de kullanıcıya farklı yazılar yazdırmak için kullanabiliriz
        }catch(PDOException $e){ // Herhangi bir sorun ile karşılaşılmışmı denetliyoruz
            die($e->getMessage()); // Hata var ise hatayı ekrana yazdırıyoruz. 
            // Not: Bu hata yazdırması aslında çok riskli olduğunu söyleyebilirim eğerki oyununuzu profesyonel anlamda yayımlayacaksanız bu kısmıda yukarıdaki gibi 0 1 yerine 2 - 3 gibi sayılar ile daha detaylı bir hale getirebilirsiniz, tabi bu sizin php bilginize kalmış.
        }
    }

?>

hesapolustur.php Unity üzerinden gelen kullanıcı bilgilerini veri tabanına ekliyoruz.

<?PHP
    include "config.php"; // config.php çağırıyoruz

    if(isset($_POST["kullaniciAdi"], $_POST["mail"], $_POST["sifre"])){ // Kullanıcıdan veri gelmişmi kontrol ediyoruz.
        try{ // hata kontrolcüsü başlatıyoruz
            $kullaniciAdi = $_POST["kullaniciAdi"]; // Gelen kullanıcı adını kullaniciAdi değişkenine atıyoruz.
            $mail = $_POST["mail"]; // Gelen mail verisini mail değişkenine atıyoruz.
            $sifre = $_POST["sifre"]; // Gelen şifre verisini sifre değişkenine atıyoruz.

            $baglanti = new PDO("mysql:host=".$host.";dbname=".$host_database."" , $host_username, $host_password); // Veri tabanına bağlanıyoruz.
            $baglanti -> exec("SET NAMES utf8"); // Veri tabanı ile karakter sıkıntısı yaşamamak için karakter tipini set ediyoruz.
            $baglanti -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Hata vb... ayıklacıları açıyoruz

            $sorgu = $baglanti -> prepare("INSERT INTO hesaplar(kadi, mail, pass) VALUES(?,?,?)"); // hesaplar veri tablosuna bağlanıyor ve veri göndericem sana diyoruz
            $sorgu -> bindParam(1, $kullaniciAdi, PDO::PARAM_STR); // isim verisini gönderiyoruz
            $sorgu -> bindParam(2, $mail, PDO::PARAM_STR); // mail verisini gönderiyoruz
            $sorgu -> bindParam(3, $sifre, PDO::PARAM_STR); // şifre verisini gönderiyoruz

            $sorgu -> execute(); // göderdiğimiz verileri veri tablosuna yazdırıyoruz
            echo "1"; // herhangi bir sorun çıkmadığı için 1 yazarak dönüt veriyoruz.
        }catch(PDOException $e){ // hataları yakalıyoruz
            die($e->getMessage()); // herhangi bir hata ile karşılaştıysak bu hatayı yazdırıyoruz.
        }
    }

Not : Arkadaşlar ben burada daha önceden aynı bilgiler ile hesap oluşturulmuş mu veya kullanıcı şifresini md5, SHA yöntemler ile şifrelemek gibi güvenlik önlemleri almadan dümdüz yazdım eğer ki siz oyun çıkartacak ve kullanıcıların hesap oluşturmasını istiyorsanız bu gibi güvenlik önlemlerine dikkat etmelisiniz!

Unity Kodlarının Yazılması

MySQLHelper

MySQL Helper ile verileri gönderil almayı sağlıyoruz.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement; // Sahne değiştirmek için kullandığımız kütüphane

public class MYSQLHelper:MonoBehaviour
{
    [SerializeField] // Değişkene Inspector penceresinden erişilmesini sağlıyoruz.
    private string hesapOlusturURL = ""; // Hesap oluştur bağlantısı için değişken oluşturuyoruz.
    [SerializeField] // Değişkene Inspector penceresinden erişilmesini sağlıyoruz.
    private string girisYapURL = ""; // Giriş yap bağlantısı için değişken oluşturuyoruz.

    // Her yerden ulaşabilmek için HesapOlustur ve GirisYap adında iki adet değişken oluşturuyor ve içerisine 
    // StartCoroutine içinde kullanacağımız asıl fonksiyonları çağırıyoruz.
    public void HesapOlustur(string kullaniciAdi, string ePosta, string sifre){
        StartCoroutine(_HesapOlustur(kullaniciAdi, ePosta, sifre));
    }
    public void GirisYap(string kullaniciAdi, string sifre, int acilacakSayfa){
        StartCoroutine(_GirisYap(kullaniciAdi, sifre , acilacakSayfa));
    }

    // Giriş yapıldıysa geçerli sahneyi yeniden yüklemesi için bir fonksiyon yazdım, 
    public void GirisYapildi(int sahneID){
        PlayerPrefs.SetInt("giris", 1); // PlayerPrefs ile kullanıcının giriş yapıp yapmadığının verisini tutuyorum ve böylelikle kullanıcıya sürekli olarak giriş ekranı göstermiyorum.
        // yukarıdaki playerprefs 1 ise giriş yapılmış anlamına geliyor.
        SceneManager.LoadScene(sahneID, LoadSceneMode.Single); // Sahneyi yeniden yüklüyorum
    }
    IEnumerator _HesapOlustur(string kullaniciAdi, string ePosta, string sifre)
    {
        yield return new WaitForEndOfFrame(); // Son karenin gelmesi bekleniyor
        WWWForm hesapOlusturmaForm = new WWWForm(); // WWW form oluşturuyorum
        hesapOlusturmaForm.AddField("kullaniciAdi", kullaniciAdi); // Kullanıcı adı verisini forma ekliyorum
        hesapOlusturmaForm.AddField("mail", ePosta); // Mail verisini forma ekliyorum
        hesapOlusturmaForm.AddField("sifre", sifre); // Şifre verisini forma ekliyorum
 
        WWW veriGonder = new WWW(hesapOlusturURL, hesapOlusturmaForm); // WWW ile veri gönderilmesi için siteye bağlanıyorum
        yield return veriGonder; // Veriyi gönderiyorum
        if(veriGonder.text == "1"){ // Siteden 1 yanıtı geldiyse
            Debug.Log("Hesap oluşturma başarılı"); // Giriş başarılı dedirtiyorum
        }else{
            Debug.Log("Hesap oluştururken bir sorun ile karşılaşıldı! \nSorun sende değil bende. :')"); // Siteden 1 dışında bir yanıt gelirse sorun var yazısı yazıdırıyorum
        }
    }

    IEnumerator _GirisYap(string kullaniciAdi, string sifre, int acilacakSayfa){
        yield return new WaitForEndOfFrame(); // Son karenin gelmesi bekleniyor
        WWWForm girisYapForm = new WWWForm(); // WWW Form oluşturuyorum
        girisYapForm.AddField("kullaniciAdi", kullaniciAdi); // Kullanıcı adı bilgisini forma ekliyorum
        girisYapForm.AddField("sifre", sifre); // Şifre bilgisini forma ekliyorum

        WWW veriGonder = new WWW(girisYapURL, girisYapForm); // Forma eklediğim verileri WWW ile siteye gönderiyorum
        yield return veriGonder; // Siteye verileri gönderdim
        if(veriGonder.text == "1"){ // Siteden gelen veri 1 ise
            Debug.Log("Giriş Yapıldı"); // Giriş yapıldı diyorum
            GirisYapildi(acilacakSayfa); // Giriş yapıldı fonksiyonunu çağırıyorum
        }else if(veriGonder.text == "0"){ // Gelen veri 0 ise
            Debug.Log("Kullanıcı adı veya şifre hatalı!"); // Şifre veya kullanıcı adı yanlış diyorum
        }else { // Farklı bir veri geldiyse siteden
            Debug.Log("Giriş yapılırken bir sorun ile karşılaşıldı! \nSorun sende değil bende :')"); // Hata mesajı bastırıyorum
        }
    }
}

UIManager

UIManager ile panelleri açıyor kapatıyor ve girdilerden(Input) gelen verileri MYSQLHelper scriptine yolluyoruz.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


public class UIManager : MonoBehaviour
{
    public GameObject[] paneller; // Ana ekran, giriş ve hesap oluşturma panellerini buraya atıyorum ve arasında geçiş sağlayabiliyorum.
    public MYSQLHelper _mysqlHelper; // Yazdığımız MySQL Helper Scriptini buraya sürükleyeceğiz ve oradaki fonksiyonlara bunun ile erişeceğiz.
    public InputField _hesapOlusturKullaniciAdi; // Hesap oluştur paneli kullanıcı adı girdisi
    public InputField _hesapOlusturSifre; // Hesap oluştur paneli şifre girdisi
    public InputField _hesapOlusturEPosta; // Hesap oluştur paneli e posta girdisi
    public InputField _girisYapKullaniciAdi; // Giriş paneli kullanı adı girdisi
    public InputField _girisYapSifre; // Giriş paneli şifre girdisi
    
    // Panellerin sıralanışı
    // 0 AnaEkran
    // 1 Giriş Paneli
    // 2 Hesap Oluşturma Paneli

    void Awake(){
        if(PlayerPrefs.GetInt("giris") == 1){ // Kullanıcı giriş yapmışmı kontrol ediyorum
            GirisEkraniKapat(); // Giriş yapmışsa giriş ve hesap oluştur panelini kapatıyorum
        }
    }

    // Giriş ve hesap oluştur panelini kapatmak için yazdığım fonksiyon
    public void GirisEkraniKapat(){
        paneller[0].SetActive(false); // ana paneli kapatır
        paneller[1].SetActive(false); // giriş panelini kapatır
        paneller[2].SetActive(false); // hesap oluşturma panelini kapatır

    }

    // Giriş yap butonuna tıklandığı zaman çalışan fonksiyon
    public void GirisYap(){
        _mysqlHelper.GirisYap(_girisYapKullaniciAdi.text, _girisYapSifre.text, 0); // MYSQLHelper scriptindeki girişyap fonksiyonunu çağırıyor ve gerekli bilgileri gönderiyor
    }

    // Hesap oluştur butonuna tıklandığı zaman çalışan fonksiyon
    public void HesapOlustur(){
        _mysqlHelper.HesapOlustur(_hesapOlusturKullaniciAdi.text, _hesapOlusturEPosta.text, _hesapOlusturSifre.text); // MySQL helper scriptinde hesap oluştur fonksiyonunu çağırıyor ve gerekli bilgileri gönderiyor
    }
    
    // Giriş yap panelini açar veya kapatır
    public void GirisPaneliAcKapat()
    {
        if (paneller[0].activeSelf)
        {
            paneller[0].SetActive(false);
            paneller[2].SetActive(false);
            paneller[1].SetActive(true);
        }
        else if (paneller[0].activeSelf == false)
        {
            paneller[0].SetActive(true);
            paneller[1].SetActive(false);
            paneller[2].SetActive(false);

        }
    }
    // Kayır ol panelini açar veya kapatır
    public void KayitPaneliAcKapat()
    {
        if (paneller[0].activeSelf)
        {
            paneller[0].SetActive(false);
            paneller[1].SetActive(false);
            paneller[2].SetActive(true);
        }
        else if (paneller[0].activeSelf == false)
        {
            paneller[0].SetActive(true);
            paneller[1].SetActive(false);
            paneller[2].SetActive(false);

        }
    }
}
 

Unity Sahne Kısmı

Sahnemize 1 adet "Canvas" atıyoruz ve içerisine 3 adet panel atıyoruz.
1. Panelde 2 adet buton atıyor ve "Giriş Yap", "Hesap Oluştur" yazıyoruz bunlar ile giriş paneli ve hesap oluştur panelini açacağız.
2. Panelde 2 adet input ve 1 adet buton atıyoruz. 1. input kullanıcı adı, 2. input şifre için olacak buton ise giriş yapmak için kullanılacak.
3. Panelde 3 adet input ve 1 adet buton ekliyoruz. 1. input kullanıcı adı, 2. input şifre ve 3. input da e posta adresi için kullanılacak. Buton ile de hesap oluşturulacak.
Ayrıca sahneye 2 adet boş obje atıyoruz ve bunların ilkine HesapManager diyip içine MYSQLHepler Scriptini atıyoruz, ikincisine ise UIManager diyip UIManager Scriptini atıyoruz.

Unity Mysql Sahne

Yukarıdaki işlemleri sorunsuz bir şekilde tamamladıktan sonra doğru objeleri doğru bir şekilde UIManager ve HesapManager üzerinde yerleştiriyoruz.

Unity MySQL Hesap Manager

Unity MySQL UIManager

Not : Her zaman dediğim gibi beni örnek almayın sizler daha düzgün isimler ile adlandırın bu oluşturduğunuz objeleri...

Butonlarımıza da fonksiyonları atamayı unutmayın (Toplamda 4 adet butona atamanız gerekiyor ben görsel olarak 2 adetini koydum..)

Unity MySQL Buton1

Unity MySQL Buton2

Buraya kadar her şeyi sorunsuz olarak yaptıysak artık hesap oluşturma denemesi yapabiliriz..

Hesap oluşturalım ve sonra gidip onu veri tabanından kontrol edelim.

Unity Hesap Oluşturma1

Unity Hesap Oluşturma 2

Unity Hesap Oluşturma 3

Gördüğünüz gibi hesabımız veri tabanına eklenmiş. Şimdi bir de hesabımıza giriş yapalım.

Unity Giriş 1

Unity Giriş 2

Evet arkadaşlar gördüğünüz gibi sorunsuz olarak hesap oluşturduk ve oluşturduğumuz hesaba da giriş yapabildik.. 


Videoda "ClearPrefabs" yapıyorum başlangıçta bunu yapmamın sebebi yazıyı hazırlarken görüntü almak için hesap oluşturmuş ve giriş yapmış olmam, hesaptan çıkmak için bunu yapıyorum. 

Eğer oyun içerisinde hesaptan çık butonu koymak istiyorsanız "PlayerPrefs.SetInt("giris", 0);" olan bir fonksiyon yazıp butondan bu fonksiyonu çağırmanız yeterli olacaktır.
Tabi sonrasında sahneyi yeniletmeyi unutmayın.

Bu yazıyı burada sonlandırıyorum ve kendinize iyi bakın diyorum. Sonraki yazılarda görüşmek dileğiyle.

Not : Takıldığınız yerler olursa aşağıdaki yorum kısmına sorabilirsiniz.