質問編集履歴

5

問題が発生している個所を整理して書き直しました。

2022/04/08 08:10

投稿

blanket
blanket

スコア295

test CHANGED
File without changes
test CHANGED
@@ -2,77 +2,18 @@
2
2
  5枚のブロック画像がランダムに(-7~8*50)配置されている
3
3
  ブロックが上からスクロールしてくる
4
4
  プレイヤーが下に表示されていて左右移動できる
5
- [質問](https://teratail.com/questions/et1oqj4p8c392l)
6
- [パッケージ](https://www.dropbox.com/s/pi7patcntk4trdx/et1oqj4p8c392l.unitypackage?dl=1)
7
5
  ### 実現したいこと
8
6
  ブロックと当たり判定をとった時特定の条件が満たされたら範囲内のオブジェクトを消す処理が知りたい
9
7
  もし配列の同じ画像が2枚以上揃っていたらプレイヤーに当たった時揃ったものをすべて消す
10
8
  上の条件をループさせて連鎖消えを実現させる
11
- ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-03-22/58553352-9082-4860-9310-f7491209e994.png)
12
9
  ### 発生している問題・エラーメッセージ
13
10
  ```
14
-
11
+ 当たったら連結ているすべてのブロックが削除されてしまう。
15
12
  ```
16
13
  ### 該当のソースコード
17
- ```C#
18
- // BlockRandom(ランダム部分)→空のゲームオブジェクトにアタッチ
19
- [SerializeField] GameObject _blockPrefab = default;
20
-
21
- IEnumerator GenerateBlockRoutine()
22
- {
23
- yield return new WaitForSeconds(1.0f);
24
-
25
- for (int y = 0; y < 50; y++)
26
- {
27
- for (int x = -7; x < 8; x++)
28
- {
29
- var go = Instantiate(_blockPrefab, new Vector3(x, y, 0), Quaternion.identity);
30
- go.transform.SetParent(this.transform);
31
- int type = Random.Range(0, 5);
32
- // 画像5個のランダム化
33
- _blockPrefab.GetComponent<DropCnt>().Set(type);
34
- _blockPrefab.GetComponent<DropCnt>().ID1 = y;
35
- _blockPrefab.GetComponent<DropCnt>().ID2 = x;
36
- }
37
- yield return null;
38
- }
39
- }
40
- ```
41
-
42
- ```C#
43
- // DropCnt→1枚のプレファブ画像にアタッチ
44
- [SerializeField] Sprite[] sp;
45
-
46
- public int ID1{get;set;}
47
- public int ID2{get;set;}
48
- public void Set(int n)
49
- {
50
- GetComponent<SpriteRenderer>().sprite = sp[n];
51
- }
52
- ```
53
- ```C#
54
- // Horizontal2D→Playerにアタッチ
55
- public int cnt=0;
56
- void OnCollisionEnter2D(Collision2D collision)
57
- {
58
- if (collision.gameObject.CompareTag("Block"))
59
- {
60
- count++;
61
- if(count>=2)
62
- {
63
- //Destroy(collision.gameObject);
64
- }
65
- }
66
- }
67
- ```
68
- ### 試したこと
69
- 現在の状況
70
- ↓一つのコードでブロックの生成から削除までをやっています。プレイヤーが当たったら連結しているブロックをすべて消すことができました。ただ、これにプレイヤーが当たったブロックの連結数を調べ削除する条件を追加したいです。
71
- ### 補足情報(FW/ツールのバージョンなど)
72
- 2021.2.13f1
73
- Unity2D(コア)
74
14
  ### 追記
75
15
  ```C#
16
+ //Playerにアタッチ
76
17
  public float playerSpeed;
77
18
  private Vector2 player_pos;
78
19
  public int width;
@@ -237,3 +178,9 @@
237
178
  }
238
179
  }
239
180
  ```
181
+ ### 試したこと
182
+ 現在の状況
183
+ ↑一つのコードでブロックの生成から削除までをやっています。プレイヤーが当たったら連結しているブロックをすべて消すことができました。ただ、これにプレイヤーが当たったブロックの連結数を調べ削除する条件を追加したいです。
184
+ ### 補足情報(FW/ツールのバージョンなど)
185
+ 2021.2.13f1
186
+ Unity2D(コア)

4

問題が起きているコードを追加して現在の状況を書き足した。

2022/04/07 13:31

投稿

blanket
blanket

スコア295

test CHANGED
File without changes
test CHANGED
@@ -67,31 +67,173 @@
67
67
  ```
68
68
  ### 試したこと
69
69
  現在の状況
70
- 当たり判定の部分をコメントにしてあります。
71
- 5種類のブロックにそれぞれ別タグつけて当たったら消すということをしました一つのプレファ画像に配列DropCntアタッチるためタグは効果なし
70
+ ↓一つコードでブロックの生成から削除までやっいます。プレイヤーが当たったら連結しているブロックをすべて消すことができました。ただこれにプレイヤーが当たったロック連結数調べ削除する条件を追加です。
72
- count変数を使ってプレイヤーが当たったブロックに隣接しているブロックで同じ画像をカウントして消すということを書いてみましたが駄目でした。
73
71
  ### 補足情報(FW/ツールのバージョンなど)
74
72
  2021.2.13f1
75
73
  Unity2D(コア)
76
74
  ### 追記
77
75
  ```C#
76
+ public float playerSpeed;
78
- int FIELD_WIDTH = 15;
77
+ private Vector2 player_pos;
78
+ public int width;
79
+ public int height;
80
+ public GameObject[] blocks;
81
+ public GameObject[,] fieldBlocks;
82
+ [SerializeField] List<GameObject> checkZumiFieldBlocks = new List<GameObject>();
83
+ GameObject piece;
79
- int FIELD_HEIGHT = 1;
84
+ private int randomNum;
80
-
81
- private void OnCollisionEnter2D(Collision2D other)
85
+ void Start()
82
- {
86
+ {
87
+ fieldBlocks = new GameObject[width, height];
88
+ }
89
+
83
- for (int j = 0;j < FIELD_HEIGHT; j++)
90
+ void Hairetu()// ブロックを作っているところ
84
- {
91
+ {
85
- for (int i = 0; i < FIELD_WIDTH; i++)
92
+ for (int x = 0; x < width; x += 2)
86
- {
93
+ {
94
+ for (int y = 0; y < height; y += 2)
95
+ {
96
+ randomNum = Random.Range(0, 5);// 0,1,2,3,4
97
+ piece = Instantiate(blocks[randomNum]) as GameObject;
98
+ piece.transform.position = new Vector3(x, y, 0);
99
+ fieldBlocks[x, y] = piece;
100
+ }
101
+ }
102
+ }
103
+
104
+ void Begin()
105
+ {
106
+ float moveX = Input.GetAxis("Horizontal") * Time.deltaTime * playerSpeed;
107
+ float moveY = Input.GetAxis("Vertical") * Time.deltaTime * playerSpeed;
108
+
109
+ transform.position = new Vector2(
110
+ //エリア指定して移動する
111
+ Mathf.Clamp(transform.position.x + moveX, 0.0f, 20.0f),
112
+ Mathf.Clamp(transform.position.y + moveY, -4.0f, 18.0f)
113
+ );
114
+
115
+ player_pos = transform.position; //プレイヤーの位置を取得
116
+
117
+ player_pos.x = Mathf.Clamp(player_pos.x, 0.0f, 20.0f); //x位置が常に範囲内か監視
118
+ player_pos.y = Mathf.Clamp(player_pos.y, -4.0f, 18.0f); //y位置が常に範囲内か監視
119
+ transform.position = new Vector2(player_pos.x, player_pos.y);
120
+
121
+ public void Drop()// ブロックの落下処理
122
+ {
123
+ int nullCount = 0;
124
+ for (int x = 0; x < width; x += 2)
125
+ {
126
+ for (int y = 0; y < height; y += 2)
127
+ {
128
+ if (fieldBlocks[x, y] == null)
129
+ {
130
+ nullCount += 2;
131
+ }
132
+ else if (nullCount > 0)
133
+ {
134
+ fieldBlocks[x, y].transform.position += new Vector3(0, -nullCount, 0);
135
+ fieldBlocks[x, y - nullCount] = fieldBlocks[x, y];
136
+ fieldBlocks[x, y] = null;
137
+ }
138
+ }
139
+ nullCount = 0;
140
+ }
141
+ if (RenketuAri())
142
+ {
143
+ StartCoroutine(Erase());
144
+ }
145
+ }
146
+
147
+ public bool RenketuAri()// 連結を確認
148
+ {
149
+ for (int x = 0; x < width; x += 2)
150
+ {
151
+ for (int y = 0; y < height; y += 2)
152
+ {
153
+ checkZumiFieldBlocks.Clear();
154
+ if (Renketusuu(x, y, 0) > 1 && fieldBlocks[x, y] != null)
155
+ {
156
+ return true;
157
+ }
158
+ }
159
+ }
160
+ return false;
161
+ }
162
+
163
+ public IEnumerator Erase()// 1つ以上そろったら削除
164
+ {
165
+ yield return new WaitForSeconds(0.5f);
166
+ for (int x = 0; x < width; x += 2)
167
+ {
168
+ for (int y = 0; y < height; y += 2)
169
+ {
170
+ checkZumiFieldBlocks.Clear();// Listをクリア
171
+ // 同じ種類が1以上だったら配列を削除
172
+ if (Renketusuu(x, y, 0) > 1 && fieldBlocks[x, y] != null)
173
+ {
174
+ Destroy(fieldBlocks[x, y]);
175
+ }
176
+ }
177
+ }
178
+ yield return new WaitForSeconds(0.5f);
179
+ Drop();
180
+ }
181
+
182
+ int Renketusuu(int x, int y, int rennketusuu)// 連結しているか調べる
183
+ {
184
+ if (fieldBlocks[x, y] == null || checkZumiFieldBlocks.Contains(fieldBlocks[x, y]))
185
+ {
186
+ return rennketusuu;
187
+ }
188
+ checkZumiFieldBlocks.Add(fieldBlocks[x, y]);
189
+
190
+ rennketusuu++;
191
+
192
+ if (x != width - 2 && fieldBlocks[x + 2, y] != null && fieldBlocks[x, y].name == fieldBlocks[x + 2, y].name)// 右
193
+ {
194
+ Debug.Log(fieldBlocks[x + 2, y].name);
195
+ rennketusuu = Renketusuu(x + 2, y, rennketusuu);
196
+ }
197
+ if (x != 0 && fieldBlocks[x - 2, y] != null && fieldBlocks[x, y].name == fieldBlocks[x - 2, y].name)// 左
198
+ {
199
+ Debug.Log(fieldBlocks[x - 2, y].name);
200
+ rennketusuu = Renketusuu(x - 2, y, rennketusuu);
201
+ }
202
+ if (y != 0 && fieldBlocks[x, y - 2] != null && fieldBlocks[x, y].name == fieldBlocks[x, y - 2].name)// 下
203
+ {
204
+ Debug.Log(fieldBlocks[x, y - 2].name);
205
+ rennketusuu = Renketusuu(x, y - 2, rennketusuu);
206
+ }
207
+ if (y != height - 2 && fieldBlocks[x, y + 2] != null && fieldBlocks[x, y].name == fieldBlocks[x, y + 2].name)// 上
208
+ {
209
+ Debug.Log(fieldBlocks[x, y + 2].name);
210
+ rennketusuu = Renketusuu(x, y + 2, rennketusuu);
211
+ }
212
+
213
+ return rennketusuu;
214
+ }
215
+
216
+ private void OnCollisionEnter2D(Collision2D collision)
217
+ {
87
- if (other.gameObject.CompareTag("Block_B"))
218
+ if (collision.gameObject.tag == "Block_B" ||
219
+ collision.gameObject.tag == "Block_G" ||
220
+ collision.gameObject.tag == "Block_Y" ||
221
+ collision.gameObject.tag == "Block_R")
222
+ {
223
+ for (int x = 0; x < width; x += 2)
224
+ {
225
+ for (int y = 0; y < height; y += 2)
88
226
  {
227
+ // Listをクリア
228
+ checkZumiFieldBlocks.Clear();
229
+ // 同じ種類が1以上だったら配列を削除
89
- foreach (Transform child in gameObject.transform)
230
+ if (Renketusuu(x, y, 0) > 1 && fieldBlocks[x, y] != null)
90
231
  {
232
+ Debug.Log(fieldBlocks[x, y] + "_" + "連結数_①");
91
- Destroy(child.gameObject);
233
+ Destroy(fieldBlocks[x, y]);
92
234
  }
93
235
  }
94
236
  }
95
237
  }
96
- }
238
+ }
97
- ```
239
+ ```

3

コード例の追加

2022/03/26 06:20

投稿

blanket
blanket

スコア295

test CHANGED
File without changes
test CHANGED
@@ -73,33 +73,22 @@
73
73
  ### 補足情報(FW/ツールのバージョンなど)
74
74
  2021.2.13f1
75
75
  Unity2D(コア)
76
- ### 追
76
+ ### 追
77
77
  ```C#
78
+ int FIELD_WIDTH = 15;
78
- using UnityEngine.UI;
79
+ int FIELD_HEIGHT = 1;
79
- using System;
80
- using System.Linq;
81
80
 
82
- UnityEngine.UI.Image[] A = new UnityEngine.UI.Image[800];
83
-
84
- void OnCollisionEnter2D(Collision2D collision)
81
+ private void OnCollisionEnter2D(Collision2D other)
85
82
  {
86
- if (collision.gameObject.CompareTag("Block"))
83
+ for (int j = 0;j < FIELD_HEIGHT; j++)
87
84
  {
88
- for (var tate = 0; tate < 49; tate++)
85
+ for (int i = 0; i < FIELD_WIDTH; i++)
89
86
  {
90
- var y_ = tate;
91
- //string[] spl1 = A[y_].sprite.name.Split('_');
87
+ if (other.gameObject.CompareTag("Block_B"))
92
- if (y_==y_+1)
93
88
  {
94
- Destroy(collision.gameObject);
89
+ foreach (Transform child in gameObject.transform)
95
- }
96
- for (var yoko = -7; yoko < 8; yoko++)
97
- {
98
- var x_ = yoko;
99
- //string[] spl2 = A[x_].sprite.name.Split('_');
100
- if (x_==x_+1)
101
90
  {
102
- Destroy(collision.gameObject);
91
+ Destroy(child.gameObject);
103
92
  }
104
93
  }
105
94
  }

2

エラー箇所をコメントにした

2022/03/22 17:24

投稿

blanket
blanket

スコア295

test CHANGED
File without changes
test CHANGED
@@ -88,7 +88,7 @@
88
88
  for (var tate = 0; tate < 49; tate++)
89
89
  {
90
90
  var y_ = tate;
91
- string[] spl1 = A[y_].sprite.name.Split('_');
91
+ //string[] spl1 = A[y_].sprite.name.Split('_');
92
92
  if (y_==y_+1)
93
93
  {
94
94
  Destroy(collision.gameObject);
@@ -96,7 +96,7 @@
96
96
  for (var yoko = -7; yoko < 8; yoko++)
97
97
  {
98
98
  var x_ = yoko;
99
- string[] spl2 = A[x_].sprite.name.Split('_');
99
+ //string[] spl2 = A[x_].sprite.name.Split('_');
100
100
  if (x_==x_+1)
101
101
  {
102
102
  Destroy(collision.gameObject);

1

コード例を追加

2022/03/22 17:19

投稿

blanket
blanket

スコア295

test CHANGED
File without changes
test CHANGED
@@ -73,3 +73,36 @@
73
73
  ### 補足情報(FW/ツールのバージョンなど)
74
74
  2021.2.13f1
75
75
  Unity2D(コア)
76
+ ### 追加
77
+ ```C#
78
+ using UnityEngine.UI;
79
+ using System;
80
+ using System.Linq;
81
+
82
+ UnityEngine.UI.Image[] A = new UnityEngine.UI.Image[800];
83
+
84
+ void OnCollisionEnter2D(Collision2D collision)
85
+ {
86
+ if (collision.gameObject.CompareTag("Block"))
87
+ {
88
+ for (var tate = 0; tate < 49; tate++)
89
+ {
90
+ var y_ = tate;
91
+ string[] spl1 = A[y_].sprite.name.Split('_');
92
+ if (y_==y_+1)
93
+ {
94
+ Destroy(collision.gameObject);
95
+ }
96
+ for (var yoko = -7; yoko < 8; yoko++)
97
+ {
98
+ var x_ = yoko;
99
+ string[] spl2 = A[x_].sprite.name.Split('_');
100
+ if (x_==x_+1)
101
+ {
102
+ Destroy(collision.gameObject);
103
+ }
104
+ }
105
+ }
106
+ }
107
+ }
108
+ ```