cial Icons

Unity Buton Yapma

Unity Android Dokunma Katmanı ve Android Kendi Butonunu Yapma


Merhaba arkadaşlar, Unity de kendi butonlarımızı tasarlamamızı sağlayacak olan yada herhangi objelere dokunmamızı sağlayacak olan metodu ve çalışma mantığını anlatacağım. Unity'de kendi butonumu nasıl yaparım, dokunduğum objeleri nasıl etkilerim, oyunumdaki objeler dokunduğumu nasıl algılar, her obje için özel metot mu yazmam gerek ? gibi sorularına cevap arıyorsanız yazımda cevapları bulabilirsiniz.






       TouchLayer adını verdiğim bu metot sayesinde ekranda tıkladığınızda tıklama başladı, bitti, çıktı ya da duruyor gibi durumları kullanabilecek ve ekranda ayarlarını yaptığınız objeleri tıklayabilecek sürükleyebilecek ya da amacınız doğrultusunda istediğiniz gibi kullanabileceksiniz.

     


            Açıklama satırlarında kodların ne olduğunu ve ne amaçla yazıldıklarını anlattım.
 #İf UNITY_EDITOR ile başlayıp #endif ile Biten kısmı isteğe bağlı alabilirsiniz. Bu kısım sayesinde androidde dokunarak yaptıklarınız editörde mouse ile yapabilirsiniz, test amaçlı iyi oluyor.


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

public class TouchLayer : MonoBehaviour
{



    private List<GameObject> touchList = new List<GameObject>();  // her bir dokunulan objeyi tutacak olan list
    private GameObject[] touchesOld;  // dokunmayı bıraktığımız yani touchexit olan objeler
    private  Camera camera;  // ekran kamerası
    private RaycastHit hit;    

 
    void Start()
    {
        GetCamera();
    }

    private void GetCamera()
    {
        camera = GetComponent<Camera>();
    }

    // Update is called once per frame
    void Update()
    {
        #if UNITY_EDITOR
        if (Input.GetMouseButton(0) || Input.GetMouseButtonDown(0) || Input.GetMouseButtonUp(0))
        {
            touchesOld = new GameObject[touchList.Count];
            touchList.CopyTo(touchesOld);
            touchList.Clear();

            
            //if(camera==null){
            //    GetCamera();
            //}
            Ray ray = camera.ScreenPointToRay(Input.mousePosition);

            if (Physics.Raycast(ray, out hit))
            {
                GameObject receiver = hit.transform.gameObject;

                touchList.Add(receiver);

                if (Input.GetMouseButtonDown(0))
                {
                    receiver.SendMessage("OnTouchDown", hit.point, SendMessageOptions.DontRequireReceiver);
                }
                if (Input.GetMouseButtonUp(0))
                {
                    receiver.SendMessage("OnTouchUp", hit.point, SendMessageOptions.DontRequireReceiver);
                }
                if (Input.GetMouseButton(0))
                {
                    receiver.SendMessage("OnTouchStay", hit.point, SendMessageOptions.DontRequireReceiver);
                }

            }

            foreach (GameObject g in touchesOld)
            {
                if (!touchList.Contains(g))
                {
                    g.SendMessage("OnTouchExit", hit.point, SendMessageOptions.DontRequireReceiver);
                }
            }
        }
        #endif

        if (Input.touchCount > 0)
        {

            touchesOld = new GameObject[touchList.Count];
            touchList.CopyTo(touchesOld);
            touchList.Clear();

            foreach (Touch touch in Input.touches)
            {
                Ray ray = camera.ScreenPointToRay(touch.position);  // ekrana yapılan dokunuş icin bir ray nesnesi üretiyoruz 
                                                                    // bu ray sayesinde dokunulan x ve y z dokunuşla aynı olan unity objeleri yakalnıyor
                
                if (Physics.Raycast(ray, out hit))  // dokunuş için alınan ray nesnesi kullanrak fizik raycast metodu ile o bölgede olup dokunulan unity objeleri out hit olarak bize geri dönüyor
                {
                  


                    //if(hit.transform.gameObject.tag==Tags.Touchable){   // bu koşullada eğer isterseniz sadece tag' ini ayarladığınız objeler tıklamayı alır yani her dokunuşta bu metod çalışmaz sadece tag i aynı olan unity objesine basıldığında metoda girer ve
                                                                            // gereksiz çalışmamış olur

                        GameObject receiver = hit.transform.gameObject;  // hit yani dokunulan unity nesnesini gameobje olarak nesneleştiriyoruz

                        touchList.Add(receiver);                        // dokunulanlar listesine ekliyoruz ki exit durumunda da yakalayabilelim!
                   
                        if (touch.phase == TouchPhase.Began)            // unity nin dokunuz durumları! dokunuş başladıysa Touchdown metodu çağırılacak yani buton aşağı indi basma gerçekleşti!
                        {
                            receiver.SendMessage("OnTouchDown", hit.point, SendMessageOptions.DontRequireReceiver); // bu ise androidde de olan broadcast gibi bir yöntem bir mesaj yollanıyor adı 'OnTouchDown' ve bu metodu içerisinde barındıran nesneler
                                                                                                                        // bu metodu çalıştırmış oluyor. yani bir broadcast atılıyor ve broadcast receiver'ı olan yani metodu içinde barındıranlar bu mesajı almış oluyor.
                        }
                        if (touch.phase == TouchPhase.Ended)            // yine dokunma durumu dokunma bitti ise buton yukarda yani touchup !
                        {
                            receiver.SendMessage("OnTouchUp", hit.point, SendMessageOptions.DontRequireReceiver);
                        }
                        if (touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved) // yine bir durum, eğer tıklanma sürekli ise buton down halinde kalıyor yani hala dokunuyorum.
                        {
                            receiver.SendMessage("OnTouchStay", hit.point, SendMessageOptions.DontRequireReceiver);
                        }
                        if (touch.phase == TouchPhase.Canceled)   // ve exit yani artık dokunmuyorum çıktım ama updan farklı dokundum parmağımı kaldırmadan çıktım da olabilir böyle durumlarda eğer tıklanan objeden yada butondan bir
                        {                                          // eylem gerçekleştirmesi bekleniyorsa bu eylemi touchup olduğunda yaparsanız exit olduğunda eylem gerçekleşmez
                                                                    // yani diyelimki yanlışlıkla başla butonuna bastım fakat başlamıycaktım sürükleyip çıkarak butona basmamış oluyorum.
                        
                            receiver.SendMessage("OnTouchExit", hit.point, SendMessageOptions.DontRequireReceiver);
                        }
                    }
                //}
            }
            foreach (GameObject g in touchesOld)
            {
                if (!touchList.Contains(g))
                {
                    g.SendMessage("OnTouchExit", hit.point, SendMessageOptions.DontRequireReceiver);
                }
            }
        }
    }
}


           Açıklama satırlarında elimden geldiğince anlattım her metodun ve nesnenin ne iş yaptığını, söylediğim gibi eğer unity objelerinize tag belirler ve o taglar doğrultusunda çağırırsanız gereksiz işlemci yorması olmaz ve oyununuz daha hızlı çalışır.


Şimdi gel gelelim abi biz bunu yazdık da sonra ne olacak kısmına :)

Yazdığımız bu class ı ekrandaki bir objeye eklememiz gerekiyor. Bence en mantıklısı Kamera'ya eklemek: 




































Artık yapmamız gereken tek şey içinde onTouchDown, onTouchUp metodlarını barındıran bir buton scripti yazmak:




public class ButtonScript : MonoBehaviour {


    private GameManagerPlane gm;




    public Material UpMat;
    public Material DownMat;

    private Renderer Rend;


 // Use this for initialization
 void Start () {

        GetManagerInstance();
        Rend = GetComponent<Renderer>();

        Rend.material = UpMat;
 
 }

    private void GetManagerInstance()
    {
        gm = GameManagerPlane.getManager;
    }
 
 // Update is called once per frame
 void Update () {
        if(gm==null ){
            GetManagerInstance();
        }
 
 }

    void OnTouchDown(Vector3 point){
        Rend.material = DownMat;
    }

    void OnTouchUp() {
        Rend.material = UpMat;
        gm.ButtonPressed(this.name);

    
    }

    void OnTouchExit(){
        Rend.material = UpMat;

    }

    void OnTouchStay(){

    }
}
         
           Sizde benim gibi iki tane materyal koyarak down olduğunda birini up olduğunda diğerini set ederek değişimi izleyebilirsiniz.

           Her dediğini yaptım objeme tıklıyorum ama hala bişey olmuyor gibi şeyler olabilir :D Objenizde Collider olmasına dikkat edin, yani ilk test için ekrana bir Cube koyup deneyebilirsiniz. 

Tag ayarlayıp sadece tag'i aynı olan objelere dokununca nasıl çalıştırcam diyor iseniz, gelecek yazımda bulabilirsiniz :)


İyi Çalışmalar.

Hiç yorum yok :

Yorum Gönder