Unity3D ile hypercasual kule oyunu geliştirme

Unity3D ile hypercasual kule oyunu geliştirme
Vakit buldukça unity ile rehber niteliğinde basit oyun geliştirme dersleri hazırlamayı düşünüyorum. İlk olarak Tipsy tower benzeri basit fizik tabanlı kule yapma oyunu geliştirdim.  Teker teker her adımı görselleştirip anlatmak büyük bir zaman gerektirdiği için okuyucuların unity temellerini bildiğini varsayıp sadece kilit noktalara değineceğim. 

Oyunda sürekli sağa sola hareket eden bir kancadan alttaki platforma mümkün olduğunca fazla kutu bırakmaya çalışıyoruz. Herhangi bir kutu platformdan düştüğünde oyun bitiyor. 

İlk olarak kamerayı ayarlamamız gerekiyor. Kutuları üst üste koydukça ekran dışına taştığı için kameranın görüş alanını genişletmek gerek. Bunu orthographic size değerini değiştirerek sağlıyorum. Bunun için kamerayı orthographic yapıp y konumu ile size alanlarını 5 yaptım. Böylece y konumu ve size alanını aynı anda arttırarak zeminin ekranın alt kısmında kalmasını sağlıyorum.

Kamera kontrolünü sadece 2 satır olduğu için ayrıca camera scripti oluşturmadan skoruda yöneten Play scripti içinde yaptım.  Her kutu bırakıldığında bir değişkende en yüksekdeki kutuyu bazalarak kamera size alanını güncelliyoruz.

using UnityEngine;
using UnityEngine.UI;

public class Play : MonoBehaviour {

    public static Play instance;
    public static int score;

    public Text scoreText;
    public Camera cam;
    public float height { get; set; }

    private void Awake() {
        instance = this;
        score = 0;
    }

    public void addScore() {
        scoreText.text = (++score).ToString();
    }

    private void Update() {
        cam.orthographicSize = Mathf.Lerp(cam.orthographicSize, Mathf.LerpUnclamped(5f, 10f, height / 12f), Time.deltaTime);
        cam.transform.position = new Vector3(0f, cam.orthographicSize, cam.transform.position.z);
    }

}

İkinci adım kancayı oluşturdum. Kamera size değerinin 2 katı y konumunda yani ekranın üst kısmında kalacak bir "Hook" objesi ve scripti oluşturup Mathf.PingPong metodunu kullanarak sürekli hareket ettiriyorum. Herhangi bir tuşa basıldığında ise "Hook" objesinin alt objesi olan "Box" 1 saniyeliğine gizlenip tekrar görünüyor o sırada "Box" objesindeki "createClone" metodu çağrılıyor.
using System.Collections;
using UnityEngine;

public class Hook : MonoBehaviour {

    public Box boxPrefab;

    private void Update() {

        transform.position = new Vector3(
            Mathf.PingPong(Time.time * 1.5f, 2f) * 2f - 2f,
            Play.instance.cam.orthographicSize * 2f,
            0f
        );

        if (boxPrefab.gameObject.activeSelf && Input.anyKeyDown) {
            StartCoroutine(drop());
        }

    }

    private IEnumerator drop() {
        Play.instance.addScore();
        boxPrefab.gameObject.SetActive(false);
        boxPrefab.createClone();
        yield return new WaitForSeconds(1f);
        boxPrefab.gameObject.SetActive(true);
    }

}

Hook altında bir "Box" objesi ve içinde "Box" scripti oluşturdum. Fizik için Rigidbody2D ve Boxcollider2D komponentleri var. Ancak kancada asılı kalması için Rigidbody2D GravityScale değerini sıfır yaptım. Scriptteki createClone fonksiyonu objenin kendini klonlayıp klonun düşmesini sağlıyor. Eğer -2 den daha aşağıya düşerse oyun bitiriyor.

using UnityEngine;
using UnityEngine.SceneManagement;

public class Box : MonoBehaviour {

    public void createClone() {
        var clone = Instantiate(this, transform.position, Quaternion.identity);
        clone.GetComponent<Rigidbody2D>().gravityScale = 1f;
        clone.gameObject.SetActive(true);
    }

    private void Update() {
        if (transform.position.y < 0) {
            SceneManager.LoadScene("Gameover");
        }
    }

    private void OnCollisionStay2D(Collision2D collision) {
        if (transform.position.y > Play.instance.height) {
            Play.instance.height = transform.position.y;
        }
    }

}

Mekanik hazır şimdide "Menu" ve "Gameover" sahnelerini oluşturup scriptlerini eklemek kaldı.

"Menu" sahnesi oluşturup bir play butonu ve bir çıkış butonu ekleyip triggerdan menü scriptine bağlıyoruz.

using UnityEngine;
using UnityEngine.SceneManagement;

public class Menu : MonoBehaviour {

    public void play() {
        SceneManager.LoadScene("Play");
    }

    public void quit() {
        Application.Quit();
    }

}​

"Gameover" sahnesi oluşturup  bir replay butonu ve bir menu butonu ekleyerek "Gameover" scriptine ekliyoruz. "Gameover" scripti son skoru ve en iyi skoru gösterecek. Yeni rekor kırıldığında bunu kaydedecek.

using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class Gameover : MonoBehaviour {

    public Text scoreText;
    public Text bestText;

    private void Start() {

        var bestscore = PlayerPrefs.GetInt("bestscore", 0);
        if (Play.score > bestscore) {
            bestscore = Play.score;
            PlayerPrefs.SetInt("bestscore", bestscore);
        }

        scoreText.text = Play.score.ToString();
        bestText.text = bestscore.ToString();
    }

    public void menu() {
        SceneManager.LoadScene("Menu");
    }

    public void replay() {
        SceneManager.LoadScene("Play");
    }

}
Yorumlar