Unity入門 - ツムツム風 ラブライブ 2Dパズルゲーム -
ツムツムが流行って結構経ちますが、今回はツムツム風のラブライブパズルゲームを作ってみました!
まずはunityの2Dの勉強として、unityが提供している「シューティングゲームチュートリアル」を
一通りやってみて、それをベースに作成しました。
ツムツム風のラブライブパズルゲームの概要
・スクリプトはC#で作成
・2Dモードで作成
・パズルを3つ繋げてクリックすると消える
・1パズルごとに100点加算
・3000点に達するとクリア
・リセットボタンを押すとリスタートできる
WebPlayer
Unity画面のスクリーンショット
手順
1. キャラのスプライトシートを作成
block_sprite_[0-8] という名前でスライスする
2. Prefabsにブロックを作成
Sprite Renderer, Crcle Collider 2D, Rigidbody 2D コンポーネントを追加
3. ブロックが外に出ないように、上下左右に枠を作成
Sprite Renderer,Box Collider 2D コンポーネントを追加
4. クリア用のGUITextを作成
5. スコア用のGUITextを作成
6. リセットボタン用のGUITextureを作成
作成したスクリプト
ブロック操作
using UnityEngine; using System.Collections; using System.Collections.Generic; public class BlockManager : MonoBehaviour { // blockプレハブを設定 public GameObject block; // テクスチャを指定 public Sprite[] blockSprites; // 初期の出現ブロック数 public int block_num = 50; // 出現するx軸の範囲 public float drop_pos_range_x = 2.0f; // 出現するy軸の範囲 public float drop_pos_y = 1.5f; // 直前にクリックしたブロック private GameObject firstBlock; // 直前にクリックしたブロック private GameObject lastBlock; // 現在のブロック名 private string currentName; // 削除するブロックリスト List<GameObject> removeBlockList = new List<GameObject>(); // スコア public int point = 100; // クリアスコア public int clear_point = 3000; // Use this for initialization void Start () { //playSound.PlaySe00 (); DropBlock (block_num); } // Update is called once per frame void Update () { //removeBlockList = new List<GameObject>(); if (Input.GetMouseButton (0) && firstBlock == null) { OnClickFirst (); } else if (Input.GetMouseButton (0) && firstBlock) { OnClicking (); } else if (Input.GetMouseButtonUp(0) && firstBlock) { OnClickEnd (); } } // ブロックを出現させる private void DropBlock(int count){ for (int i = 0; i < count; i++) { // ポジションを取得 Vector3 position = block.transform.position; position.x = Random.Range(position.x - drop_pos_range_x, position.x + drop_pos_range_x); position.y = drop_pos_y; // テクスチャの変更 int spriteId = Random.Range(0, 8); block.name = "block_sprite_" + spriteId; SpriteRenderer spriteObj = block.GetComponent<SpriteRenderer>(); spriteObj.sprite = blockSprites[spriteId]; Instantiate (block, position, block.transform.rotation); } } // クリックした時の処理 private void OnClickFirst(){ // クリックしたオブジェクト取得 RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero); if (hit.collider != null) { //Debug.Log (hit.collider.gameObject.name); GameObject hitObj = hit.collider.gameObject; // オブジェクト名を前方一致で判定 string stTarget = hitObj.name; if (stTarget.StartsWith("block_sprite_")) { firstBlock = hitObj; lastBlock = hitObj; currentName = hitObj.name; // 削除対象のオブジェクトを格納 removeBlockList = new List<GameObject>(); removeBlockList.Add (hitObj); } } } // クリックしている途中の処理 private void OnClicking(){ // クリックしたオブジェクト取得 RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero); if (hit.collider != null) { GameObject hitObj = hit.collider.gameObject; // 同じブロックをクリックしている時 if (hitObj.name == currentName && lastBlock != hitObj) { float distance = Vector2.Distance(hitObj.transform.position, lastBlock.transform.position); if (distance < 1.0f) { // 削除対象のオブジェクトを格納 lastBlock = hitObj; removeBlockList.Add (hitObj); } } } } // クリックをはなした時の処理 private void OnClickEnd(){ int remove_cnt = removeBlockList.Count; Debug.Log ("Remove Count => " + remove_cnt); if (remove_cnt >= 3) { for (int i = 0; i < remove_cnt; i++) { Destroy (removeBlockList[i]); } // スコアの加算 FindObjectOfType<Score>().AddPoint(point * remove_cnt); // クリア判定 int currentPoint = FindObjectOfType<Score> ().GetPoint (); if (currentPoint >= clear_point) { FindObjectOfType<Manager>().GameClear(); } // ボール新たに生成 DropBlock (remove_cnt); } firstBlock = null; lastBlock = null; } }
画面操作
using UnityEngine; using System.Collections; public class Manager : MonoBehaviour { private GameObject clear; // Use this for initialization void Start () { clear = GameObject.Find ("Clear GUI"); clear.SetActive (false); } // Update is called once per frame void Update () { } public void GameClear(){ clear.SetActive (true); } }
スコア管理
using UnityEngine; using System.Collections; public class Score : MonoBehaviour { public GUIText scoreGUIText; private int score; // Use this for initialization void Start () { Initialize (); } // Update is called once per frame void Update () { scoreGUIText.text = score.ToString (); } private void Initialize () { score = 0; } public void AddPoint (int point) { score = score + point; } public int GetPoint () { return score; } }
リセットボタン
using UnityEngine; using System.Collections; public class ResetButton : MonoBehaviour { // Use this for initialization void Start () { } // Update is called once per frame void Update () { } void OnMouseDown() { Application.LoadLevel("Stage"); } void OnMouseUp() { } }
ブロック操作の BlockManager.cs が複雑で結構ハマりましたが
なんとか動くところまで実装出来ました。
本家のツムツムのように、時間制限や特別アイテム、フィーバータイムなどがあったら
もっとゲーム性が上がるんですが、次回以降で(笑)