###前提・実現したいこと
Unity2Dでドラッグ&ドロップではめていくパズルゲームを作成中です。
現在、パズルが出てくるスポーンが一つだけなのですが、三つに増やしたいと考えております。
クリックした際、それぞれの元の座標を取得して、パズルがハマらなかった際に元の位置に戻したいです。
###該当のソースコード
Group.cs
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Group : MonoBehaviour 6{ 7 private Vector3 screenPoint; 8 private Vector3 offset; 9 10 //座標が範囲内であるか,Gridに値があるかどうかを判定 11 bool isValidGridPos() 12 { 13 foreach (Transform child in transform) 14 { 15 Vector2 v = Grid.roundVec2(child.position); 16 17 if (!Grid.insideBorder(v)) 18 return false; 19 20 if (Grid.grid[(int)v.x, (int)v.y] != null && 21 Grid.grid[(int)v.x, (int)v.y].parent != transform) 22 return false; 23 } 24 return true; 25 } 26 27 void updateGrid() 28 { 29 for (int y = 0; y < Grid.h; ++y) 30 for (int x = 0; x < Grid.w; ++x) 31 if (Grid.grid[x, y] != null) 32 if (Grid.grid[x, y].parent == transform) 33 Grid.grid[x, y] = null; 34 35 foreach (Transform child in transform) 36 { 37 Vector2 v = Grid.roundVec2(child.position); 38 Grid.grid[(int)v.x, (int)v.y] = child; 39 } 40 } 41 42 //オブジェクトをクリックする 43 void OnMouseDown() 44 { 45 // マウスカーソルは、スクリーン座標なので、 46 // 対象のオブジェクトもスクリーン座標に変換してから計算する。 47 48 // このオブジェクトの位置(transform.position)をスクリーン座標に変換。 49 screenPoint = Camera.main.WorldToScreenPoint(transform.position); 50 // ワールド座標上の、マウスカーソルと、対象の位置の差分。 51 offset = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z)); 52 53 54 } 55 56 //オブジェクトをドラッグする 57 void OnMouseDrag() 58 { 59 Vector3 currentScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z); 60 Vector3 currentPosition = Camera.main.ScreenToWorldPoint(currentScreenPoint) + this.offset; 61 transform.position = currentPosition; 62 } 63 64 //オブジェクトをドロップする 65 void OnMouseUp() 66 { 67 Vector3 currentScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z); 68 Vector3 currentPosition = Camera.main.ScreenToWorldPoint(currentScreenPoint) + this.offset; 69 70 //currentPositionが範囲内であるか,Gridに値があるかどうかを判定 71 if (isValidGridPos()) 72 { 73 transform.position = Grid.roundVec2(currentPosition); 74 Grid.deleteFullRows(); 75 Grid.deleteFullLines(); 76 77 //指定範囲内ではブロックの当たり判定を無くす 78 BoxCollider2D collider = GetComponent<BoxCollider2D>(); 79 collider.enabled = false; 80 81 //次のブロックを呼び出す 82 FindObjectOfType<Spawner>().spawnNext(); 83 84 85 } 86 else 87 { 88 //Spawnerオブジェクトの座標を取る 89 transform.position = GameObject.Find("Spawner").transform.position; 90 } 91 92 } 93 94 95 // Use this for initialization 96 void Start() 97 { 98 99 } 100 101 // Update is called once per frame 102 void Update() 103 { 104 if (isValidGridPos()) 105 { 106 // It's valid. Update grid. 107 updateGrid(); 108 } 109 } 110} 111
Grid.cs
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Grid: MonoBehaviour { 6 public static int w = 10; 7 public static int h = 10; 8 public static Transform[,] grid = new Transform[w, h]; 9 10 //座標を整数にする 11 public static Vector2 roundVec2(Vector2 v) 12 { 13 return new Vector2(Mathf.Round(v.x), 14 Mathf.Round(v.y)); 15 } 16 17 //指定範囲内かどうかを判定 18 public static bool insideBorder(Vector2 pos) 19 { 20 return ((int)pos.x >= 0 && 21 (int)pos.x < w && 22 (int)pos.y >= 0 && 23 (int)pos.y < h); 24 } 25 26 //横列を消去 27 public static void deleteRow(int y) 28 { 29 for(int x = 0; x < w; ++x) 30 { 31 Destroy(grid[x, y].gameObject); 32 grid[x, y] = null; 33 } 34 } 35 36 //縦列を消去 37 public static void deleteLine(int x) 38 { 39 for (int y = 0; y < h; ++y) 40 { 41 Destroy(grid[x, y].gameObject); 42 grid[x, y] = null; 43 } 44 } 45 46 //横列が埋まっているかどうかを判定 47 public static bool isRowFull(int y) 48 { 49 for (int x = 0; x < w; ++x) 50 if (grid[x, y] == null) 51 return false; 52 return true; 53 } 54 55 //縦列が埋まっているかどうかを判定 56 public static bool isLineFull(int x) 57 { 58 for (int y = 0; y < h; ++y) 59 if (grid[x, y] == null) 60 return false; 61 return true; 62 } 63 64 65 public static void deleteFullRows() 66 { 67 for(int y = 0; y < h; ++y){ 68 if (isRowFull(y)) 69 { 70 deleteRow(y); 71 } 72 } 73 } 74 75 public static void deleteFullLines() 76 { 77 for (int x = 0; x < w; ++x){ 78 if (isLineFull(x)) 79 { 80 deleteLine(x); 81 } 82 } 83 } 84} 85
Spawner.cs
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Spawner : MonoBehaviour 6{ 7 8 public GameObject[] groups; 9 public void spawnNext() 10 { 11 //配列の中をランダムで取り出す 12 int i = Random.Range(0, groups.Length); 13 14 //オブジェクトのインスタンスを作成 15 Instantiate(groups[i], 16 transform.position, 17 Quaternion.identity); 18 } 19 20 21 void Start() 22 { 23 spawnNext(); 24 } 25 26}
現在ドロップした瞬間にスポーンの位置に戻るようにしているため、複数個の場合、それぞれの位置に戻したいです。
rayを活用してみたのですが、ブロックは Instantiateで生成しているためか、反応しませんでした
回答よろしくお願いいたします。
###補足情報(言語/FW/ツール等のバージョンなど)
環境 Unity 5.6.2f1
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。